⌚

watch-api

Documentation de l'API

← Démo interactive
API publique · lecture seule

Intégrer le catalogue de montres dans votre application.

watch-api est la référence canonique des montres, exposée en HTTP. Cette page documente la surface publique (lecture) : recherche, détail, tirage du jour et provenance. Toutes les réponses sont en JSON.

URL de base

https://watch-api-ochre.vercel.app

Tous les endpoints ci-dessous sont préfixés par cette URL. Le seul endpoint sans clé est /api/health.

Authentification

Chaque requête (sauf /api/health) doit porter l'en-tête x-api-key avec une clé consommateur valide. Une clé ressemble à wapi_live_<48 hex>. Les clés sont créées et révoquées côté admin ; elles ne sont affichées qu'une seule fois à la création — conservez-la immédiatement.

x-api-key: wapi_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Ne jamais exposer la clé dans un client (navigateur, app mobile). Appelez l'API depuis votre backend, ou via un proxy serveur — comme le fait la démo /, qui interroge l'API sans jamais révéler la clé au navigateur.
GET/api/healthsans auth

Liveness check. Le seul endpoint sans authentification.

Exemple
curl https://watch-api-ochre.vercel.app/api/health
Réponse
{ "ok": true }
GET/api/watches/:id

Fiche complète d'une montre — le payload qui alimente chaque écran de jeu.

Exemple
curl -H "x-api-key: <clé>" \
  https://watch-api-ochre.vercel.app/api/watches/clx0abc123
Réponse
{
  "id": "clx0abc123",
  "name": "Submariner Date",
  "brand": "Rolex",
  "brandLogoUrl": "https://.../rolex-logo.svg",
  "year": 2020,
  "imageUrl": "https://.../cover.jpg",
  "images": ["https://.../cover.jpg", "https://.../side.jpg"],
  "collection": "Submariner",
  "reference": "126610LN",
  "nickname": null,
  "country": "Suisse",
  "movement": "Automatique",
  "caliber": "Rolex 3235",
  "caseMaterial": "Acier",
  "braceletMaterial": "Acier",
  "caseDiameterMm": 41,
  "caseDimensions": null,
  "variants": [],
  "caliberExecutions": [],
  "technicalDataTruncated": false,
  "complications": ["Date"],
  "priceTier": "5-20k€",
  "gender": "Homme",
  "famous": true,
  "imageCredit": null,
  "model": "Submariner Date",
  "diameter": 41
}
  • Tout champ sauf id, name et brand peut être null (ou []).
  • model et diameter sont des alias hérités de name et caseDiameterMm.
  • caseDimensions contient, lorsqu'elles sont sourcées, diameterMm, widthMm, lengthMm et thicknessMm sous forme de chaînes décimales exactes ; elles ne remplacent pas le diamètre entier historique. Chaque variant peut porter ses propres caseDimensions. caliberExecutions relie une Watch ou Variant à une exécution conditionnelle et à son calibre partagé. La réponse détail borne ces listes à 200 et indique technicalDataTruncated.
  • brandLogoUrl est le logo de la marque (Wikimedia, licence libre) ; null pour les marques sans logo libre ou les fiches non encore reliées à leur marque.
  • complications relève de la curation éditoriale (aucune source importée ne la fournit) : la couverture est encore partielle et se remplit au fil de l'enrichissement. Attendez-vous à [] sur une part des fiches.
  • imageUrl / images sont des liens externes (jamais ré-hébergés) accompagnés de leur crédit et licence ; la couverture photo est encore partielle et progresse au fil de l'enrichissement. Prévoyez un rendu sans image.
  • 404 { "error": "not_found" } si l'id n'existe pas.
  • Non encore sourcés (absents du payload, ajoutés plus tard) : priceEur, waterResistanceM, productionYears. Utilisez priceTier comme signal de prix.
GET/api/watches/random

Tire une ou plusieurs montres du catalogue. Sert la « montre du jour » de façon déterministe, sans état côté serveur.

ParamètreTypeRequisDescription
famousboolnontrue privilégie les montres curées « famous » avec image ; dégrade proprement (famous+image → famous → illustrée → n'importe laquelle) plutôt que 404.
countnumbernon1–50 : renvoie un tableau de N montres distinctes. Omis → un seul objet.
dateYYYY-MM-DDnonRend le tirage déterministe : même date (+ même famous) → même montre pour tous les appelants. Omis → tirage aléatoire à chaque appel.
Exemple
# Montre du jour déterministe depuis le pool famous
curl -H "x-api-key: <clé>" \
  "https://watch-api-ochre.vercel.app/api/watches/random?famous=true&date=2026-07-24"

# Cinq montres famous distinctes
curl -H "x-api-key: <clé>" \
  "https://watch-api-ochre.vercel.app/api/watches/random?famous=true&count=5"
Réponse
// Même forme que GET /api/watches/:id
// (objet unique, ou tableau si count est fourni)
  • 404 { "error": "empty_pool" } uniquement si le catalogue est réellement vide.
  • Le « ne pas répéter pendant N jours » est à la charge du consommateur — l'API ne fait que le tirage.
GET/api/watches/:id/provenance

Origine des faits d'une fiche : quelle observation gagnante (source + tier de confiance) sous-tend chaque champ.

Exemple
curl -H "x-api-key: <clé>" \
  https://watch-api-ochre.vercel.app/api/watches/clx0abc123/provenance
Réponse
// Par champ : la valeur retenue et la source qui l'a emporté
// à l'arbitrage (voir « verified » / tier de confiance).
GET/api/brands

Liste des marques du catalogue (haut de la hiérarchie Brand → Collection → Model → Watch), avec logo, histoire et compteurs.

Exemple
curl -H "x-api-key: <clé>" https://watch-api-ochre.vercel.app/api/brands
Réponse
[
  {
    "id": "clbrand01",
    "key": "rolex",
    "name": "Rolex",
    "country": "Suisse",
    "logoUrl": "https://.../rolex-logo.svg",
    "description": "Manufacture genevoise fondée en 1905…",
    "foundedYear": 1905,
    "models": 57,
    "collections": 18,
    "references": 1240
  }
]
  • logoUrl, description et foundedYear proviennent de la curation éditoriale ; ils peuvent être null (ex. marque sans logo sous licence libre).
  • models / collections / references sont les compteurs de la marque dans le catalogue.
GET/api/models/:id

Détail d'un modèle et ses références (le niveau que la plupart du contenu externe adresse).

Exemple
curl -H "x-api-key: <clé>" https://watch-api-ochre.vercel.app/api/models/<model-id>
Réponse
// Fiche modèle + ses watches/références
GET/api/calibers/:key/watches

Les montres équipées d'un calibre donné (ex. Rolex 3235).

Exemple
curl -H "x-api-key: <clé>" https://watch-api-ochre.vercel.app/api/calibers/<key>/watches
Réponse
// Tableau de montres partageant ce calibre

Erreurs & limites

CodeCorpsQuand
401{ "error": "unauthorized" }Clé x-api-key absente ou invalide.
404{ "error": "not_found" }Détail d'une montre dont l'id n'existe pas.
404{ "error": "empty_pool" }Tirage random sur un catalogue vide.
Il n'y a pour l'instant aucune limite de débit applicative (pas de 429) — seules les limites plateforme (Vercel / Neon) s'appliquent. Mettez en cache les réponses de détail et du tirage du jour côté consommateur.

Surface en lecture seule, sur le même catalogue public que l'API sert. Certains champs numériques (prix exact, étanchéité, années de production) ne sont pas encore sourcés et apparaîtront quand une source les fournira.