{"openapi":"3.1.0","info":{"title":"tryVidimus API","version":"1","description":"\nL'API tryVidimus transforme les photos et vidéos prises pendant une transaction en **preuves scellées** que n'importe qui peut vérifier de façon indépendante. Chaque fichier est capturé en direct, signé (C2PA) et horodaté (RFC 3161) par un tiers neutre : aucune des deux parties ne peut prétendre plus tard que le fichier a été modifié.\n\n## Comment ça marche\n\n1. **Créez une session de capture** avec `POST /v1/capture-sessions`. Vous recevez une `capture_url`.\n2. **Envoyez ce lien** à la personne qui prend les photos (le fournisseur ou le destinataire). Elle capture depuis son téléphone ; les fichiers vont directement dans le stockage et ne passent jamais par vos serveurs.\n3. **Nous scellons la preuve** : nous vérifions les fichiers, nous les signons et nous obtenons un horodatage pour la preuve, en général en quelques secondes. Vous recevez un webhook `proof.sealed`, ou vous lisez la preuve avec `GET /v1/proofs/{id}`.\n4. **N'importe qui peut la vérifier** avec les routes publiques, sans compte.\n\n## Adresse et format\n\n`https://api.tryvidimus.com`. Tout est en JSON sur HTTPS ; le HTTP simple n'est pas servi. Les identifiants sont des chaînes préfixées (`prf_…` pour les preuves, `cps_…` pour les sessions de capture, `med_…` pour les fichiers).\n\n## Authentification\n\nEnvoyez votre clé d'API comme jeton « bearer » :\n\n```\nAuthorization: Bearer sk_test_…\n```\n\nUne clé appartient à une organisation et porte des **droits** : `create_proof` (créer des sessions de capture), `read_proof` (lire les preuves), `manage_webhooks` (gérer les endpoints de webhook), `manage_templates` (gérer les modèles et les styles de capture) et `manage_settings` (gérer vos réglages). Un appel sans le bon droit échoue avec `403 insufficient_scope`. `GET /v1/me` vous indique quelle clé vous utilisez.\nLes routes de la page de capture utilisent le jeton de session présent dans l'URL à la place d'une clé, et les routes de vérification publique n'ont besoin de rien.\n\n## Horodatage\n\nChaque preuve porte **son propre jeton d'horodatage RFC 3161**, émis par une autorité d'horodatage indépendante et vérifié avant que la preuve soit scellée. Deux dates ne se confondent jamais. `captured_at` (sur chaque fichier) est l'heure à laquelle **notre service a observé** le fichier : elle n'est pas qualifiée. `gen_time` (sur l'horodatage) est l'heure **certifiée par l'autorité** : pour un horodatage qualifié (`qualified: true`), c'est un horodatage qualifié eIDAS, donné à la seconde, qui prouve que la preuve existait au plus tard à cette heure. En mode test, l'horodatage est simulé et ne prouve rien. N'importe qui peut vérifier un horodatage sans nous : avec le `manifest_sha256` et le jeton du paquet public, `openssl ts -verify -digest <manifest_sha256> -in proof.tsr -CAfile chain.pem`.\n\n## Mode test et mode live\n\nLe préfixe de la clé fixe le mode : `sk_test_…` pour le bac à sable, `sk_live_…` pour la production. Les deux modes ne partagent jamais de données : une clé de test ne voit jamais une preuve live (elle reçoit un `404`). En mode test, rien n'est facturé et les horodatages sont **simulés** : ils n'ont aucune valeur juridique et la vérification indique `test_mode`.\n\n## Langues\n\nLa page de capture et les textes d'un modèle de capture peuvent s'afficher en plusieurs langues. Donnez la langue de la personne qui capture avec `locale` quand vous créez une session de capture : une étiquette BCP 47 comme `en`, `fr`, `es`, `de` ou `pt-BR`. Un modèle de capture (`POST /v1/capture-templates`) peut contenir chaque texte en plusieurs langues ; quand une langue manque, la page utilise la langue de base (`pt` pour `pt-BR`), puis la langue par défaut du modèle, puis l'anglais.\n\n## Aspect de la page de capture\n\nCréez un **style** de capture avec `POST /v1/capture-themes` : un nom, une couleur principale, une langue, et un logo avec `PUT /v1/capture-themes/{id}/logo`. Vous pouvez avoir plusieurs styles, par exemple un par marque. Choisissez le style d'un modèle de capture avec `theme_id` dans `POST /v1/capture-templates` ; sans lui, la page de capture utilise votre style par défaut. Les styles sont les mêmes en test et en production.\n\n## Avant et après\n\nPour comparer l'état d'un objet à deux moments (une remise et un retour, par exemple), faites la première capture comme d'habitude, attendez que sa preuve soit scellée, puis créez la seconde session de capture avec `compare_to` égal à l'`id` de la première preuve. La première est l'« avant », la seconde l'« après ». L'« avant » doit être scellé, avec la même `external_reference` et la même `party` ; une preuve est soit un « avant », soit un « après », jamais les deux, et a au plus un partenaire. L'« après » utilise le même modèle que l'« avant » : la personne doit donc fournir au moins autant de photos, prise de vue par prise de vue (ne donnez pas `template_id`). Chaque preuve indique son partenaire : `compare_to` sur l'« après », `compared_by` sur l'« avant ». Pour lister les preuves qui attendent encore leur « après », utilisez `GET /v1/proofs?linked=false`.\n\nSi deux liens visent le même « avant », la première capture terminée l'emporte. L'autre n'est pas sauvegardée : la terminer échoue avec `409 compare_to_already_used`, aucune preuve n'est créée, aucun crédit n'est utilisé, et vous recevez un webhook `capture_session.rejected` (son corps contient `session_id`, `code`, `compare_to`, `external_reference`, `party`, `stage` et `rejected_at`). Le refus apparaît aussi dans vos journaux. Nous ne comparons pas les photos et ne jugeons pas l'état de l'objet : les preuves montrent seulement ce que chaque partie a capturé, et c'est à vous de les apprécier.\n\n## Idempotence\n\n`POST /v1/capture-sessions` exige un en-tête `Idempotency-Key` : une valeur unique (par exemple un UUID) pour chaque création que vous tentez. Si un appel échoue sur le réseau, renvoyez-le avec la **même** clé : vous obtenez la réponse d'origine (avec l'en-tête `Idempotent-Replayed: true`) au lieu d'une seconde session. Les clés sont conservées 1 heure. Réutiliser une clé avec un corps différent échoue avec `422 idempotency_key_reused` ; une requête encore en cours de traitement échoue avec `409 request_in_progress` et un en-tête `Retry-After`.\n\n## Pagination\n\nLes routes de liste utilisent des curseurs, pas des numéros de page. Passez `limit` (de 1 à 100, 50 par défaut) et lisez `has_more` et `next_cursor` dans la réponse ; renvoyez `next_cursor` comme `cursor` pour obtenir la page suivante. Une preuve créée pendant que vous parcourez la liste ne provoque jamais de doublon ni de trou. Considérez le curseur comme opaque.\n\n## Erreurs\n\nLes erreurs suivent la RFC 9457 (`application/problem+json`) :\n\n```json\n{\n  \"type\": \"https://api.tryvidimus.com/errors/proof-not-found\",\n  \"title\": \"Proof not found\",\n  \"status\": 404,\n  \"code\": \"proof_not_found\"\n}\n```\n\nRaisonnez sur `code`, qui est stable. `title` s'adresse aux personnes et peut changer. `field` désigne le champ fautif d'une erreur `422`.\n\n## Limites de débit\n\nChaque clé a un nombre de requêtes par minute (60 par défaut). Les appels qui créent quelque chose coûtent plus cher que les lectures. Chaque réponse authentifiée porte `RateLimit-Limit` et `RateLimit-Remaining`. Au-delà de la limite, vous recevez `429 rate_limited` avec un en-tête `Retry-After`, en secondes.\n\n## Webhooks\n\nAu lieu d'interroger l'API, déclarez un endpoint avec `POST /v1/webhook-endpoints` et choisissez les événements : `proof.sealed`, `proof.failed`, `capture_session.completed`, `capture_session.rejected`, et deux réservés à une version ultérieure, `capture_session.expired` et `dossier.ready` (acceptés, mais jamais envoyés pour l'instant). Nous envoyons un `POST` avec un corps JSON à votre URL HTTPS. `events` (pluriel) est la liste à laquelle vous vous abonnez en créant l'endpoint ; chaque corps envoyé porte `event` (singulier), le nom de l'unique événement qu'il rapporte (par exemple `\"event\": \"proof.sealed\"`), puis les champs de cet événement. Le corps exact de chaque message, avec le sens de chaque champ, est dans le groupe **Événements de webhook** de cette référence. Une capture terminée produit deux messages, `capture_session.completed` puis `proof.sealed`, envoyés chacun séparément. Si votre serveur ne répond pas par un statut `2xx`, nous réessayons après 1 minute, 5 minutes, 30 minutes, 2 heures et 12 heures, puis nous abandonnons.\n\n`capture_session.completed` est envoyé quand la personne a terminé la capture, quelques secondes après l'enregistrement des fichiers et **avant** le scellement de la preuve. Son corps contient `session_id`, `proof_id`, `external_reference`, `party`, `stage` et `completed_at`. C'est le signal fiable que la capture est terminée, car la personne peut fermer la page avant d'être ramenée dans votre application : attendez `proof.sealed` avant de vous appuyer sur la preuve. Les endpoints créés avant cet événement ne le reçoivent pas tant qu'ils ne s'y abonnent pas.\n\nPour voir ce qui a été envoyé et pourquoi un envoi a échoué, lisez-le avec `GET /v1/webhook-deliveries/{id}` (ou ouvrez-le dans votre compte) : vous obtenez le corps JSON de l'événement exactement tel que votre endpoint l'a reçu, que vous pouvez copier pour rejouer l'événement sur votre propre serveur, le statut HTTP et le début de la réponse de votre serveur à la dernière tentative, et la raison d'un échec. Pour essayer votre serveur, envoyez-vous un événement d'exemple avec `POST /v1/webhook-endpoints/{id}/test` : il a les mêmes champs qu'un vrai événement, avec des valeurs d'exemple et `\"test\": true`, et il est signé avec votre secret comme tout envoi, ce qui permet de vérifier votre code de signature de bout en bout. Au plus 20 événements de test par endpoint et par heure.\n\nChaque envoi porte trois en-têtes :\n\n| En-tête | Signification |\n| --- | --- |\n| `X-Signature` | `t=<secondes unix>,v1=<signature>` (un `v1` par secret actif) |\n| `X-Webhook-Id` | Identifiant de cette tentative d'envoi |\n| `X-Event-Id` | Identifiant de l'événement : **identique d'une tentative à l'autre**, servez-vous-en pour ignorer les doublons |\n\n**Vérifiez chaque appel** : la signature est le HMAC-SHA256, en hexadécimal minuscule, de `<t>.<corps brut>`, calculé avec le secret de votre endpoint (la chaîne entière, `whsec_` compris). Comparez-la à chaque valeur `v1`, et rejetez l'appel si `t` date de plus de 5 minutes.\n\n```js\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nfunction isValid(header, rawBody, secret, toleranceSeconds = 300) {\n  const parts = header.split(',');\n  const t = Number(parts.find((p) => p.startsWith('t='))?.slice(2));\n  if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;\n  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();\n  return parts\n    .filter((p) => p.startsWith('v1='))\n    .some((p) => {\n      const given = Buffer.from(p.slice(3), 'hex');\n      return given.length === expected.length && timingSafeEqual(given, expected);\n    });\n}\n```\n\nLe secret n'est affiché qu'**une seule fois**, à la création ou à la rotation de l'endpoint. La rotation garde l'ancien secret valide un certain temps pour que vous puissiez basculer sans perdre un appel.\n\nPour voir ce qui a été envoyé à vos endpoints et ce que votre serveur a répondu, lisez le journal d'envoi avec `GET /v1/webhook-deliveries` (filtrez par `endpoint_id` ou `status`, par exemple `abandoned`). Il ne contient jamais le contenu envoyé.\n"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{}},"paths":{"/health":{"get":{"summary":"État du service","tags":["État du service"],"description":"Public. Indique si l'API fonctionne, avec sa version et le commit qu'elle exécute. Ne vérifie pas les autres services.","responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"Toujours `ok` quand l'API répond.","enum":["ok"]},"version":{"type":"string","description":"Version de l'API.","examples":["0.2.0"]},"commit":{"type":"string","description":"Le commit à partir duquel l'API a été construite.","examples":["4203fc32c36a38f00d71e6b2c959d20c54abf6f5"]}},"required":["status","version","commit"],"additionalProperties":false}}}}}}},"/health/details":{"get":{"summary":"État détaillé (supervision)","tags":["État du service"],"description":"Réservé à la supervision : demande le jeton de supervision, pas une clé d'API. Contrôle les services dont l'API dépend.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"`degraded` quand un contrôle échoue."},"version":{"type":"string","description":"Version de l'API."},"commit":{"type":"string","description":"Le commit à partir duquel l'API a été construite."},"checks":{"type":"object","properties":{"database":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"La base de données."},"storage":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"Le stockage des fichiers."},"timestamp_authority":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"L'autorité d'horodatage."}},"required":["database","storage","timestamp_authority"],"additionalProperties":false,"description":"Un contrôle par dépendance."}},"required":["status","version","commit","checks"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"503":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"],"description":"`degraded` quand un contrôle échoue."},"version":{"type":"string","description":"Version de l'API."},"commit":{"type":"string","description":"Le commit à partir duquel l'API a été construite."},"checks":{"type":"object","properties":{"database":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"La base de données."},"storage":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"Le stockage des fichiers."},"timestamp_authority":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error","not_configured"],"description":"`ok`, `error`, ou `not_configured` quand le service n'est pas configuré (jamais présenté comme `ok`)."},"latency_ms":{"type":"number","description":"Durée du contrôle, en millisecondes."}},"required":["status"],"additionalProperties":false,"description":"L'autorité d'horodatage."}},"required":["database","storage","timestamp_authority"],"additionalProperties":false,"description":"Un contrôle par dépendance."}},"required":["status","version","commit","checks"],"additionalProperties":false}}}}}}},"/v1/capture-sessions":{"post":{"summary":"Créer une session de capture","tags":["Sessions de capture"],"description":"Crée une session de capture à usage unique pour une transaction et renvoie une `capture_url`. Envoyez ce lien à la personne qui doit prendre les photos ou les vidéos (le fournisseur ou le destinataire) : les fichiers vont de son téléphone directement vers le stockage et ne passent jamais par vos serveurs. Demande le droit `create_proof` et un en-tête `Idempotency-Key`. Le lien expire à `expires_at` (30 minutes par défaut). La preuve apparaît quand la personne a terminé. Un modèle de capture (`template`, ou celui qui correspond à `stage` et `category`) fixe les prises de vue demandées à la personne et les textes qu'elle voit. Avec une clé de production, une session est refusée avec `402 insufficient_balance` quand votre solde disponible ne peut pas couvrir une preuve de plus : le solde disponible est votre solde moins les preuves déjà promises (captures ouvertes ou pas encore scellées), donc votre solde ne passe jamais sous zéro. Ajoutez des fonds pour en ouvrir de nouvelles (une capture déjà commencée se termine toujours). Les clés de bac à sable ne sont jamais refusées.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"external_reference":{"type":"string","pattern":"^[A-Za-z0-9_.:/#=+-]{1,200}$","description":"Votre propre identifiant de la transaction (une réservation, une commande…). Il relie entre elles toutes les preuves d'une même transaction. Un identifiant technique uniquement : ni adresse e-mail, ni nom, ni espaces.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui prend les photos : `provider` (celui qui remet l'objet) ou `recipient` (celui qui le reçoit).","examples":["provider"]},"stage":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Le moment de la transaction, sous la forme d'un identifiant de votre choix (`pickup`, `return`, `delivery`…). Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus.","examples":["pickup"]},"category":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Le type d'objet ou de service, sous la forme d'un identifiant de votre choix. Même format que `stage`.","examples":["vehicle"]},"template_id":{"type":"string","maxLength":80,"description":"Le modèle de capture à utiliser, par son `id` (`tpl_…`, donné par `POST /v1/capture-templates`) : il fixe les prises de vue demandées à la personne et les textes d'accueil et de fin. Omettez-le pour utiliser le modèle actif qui correspond à `stage` et `category`, s'il y en a un. `422 template_not_found` s'il n'existe pas, est archivé ou appartient à l'autre mode.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"compare_to":{"type":"string","maxLength":80,"description":"Fait de cette capture l'« après » d'une preuve que vous avez déjà (l'« avant »), par son `id` (`prf_…`). L'« avant » doit être scellé, avec la même `external_reference` et la même `party`, et ne doit pas être lui-même un « après ». La personne doit fournir au moins autant de photos, prise de vue par prise de vue, que l'« avant », avec le même modèle (ne donnez donc pas `template_id`). Une preuve ne peut être comparée qu'à une seule autre : si deux liens visent le même « avant », la première capture terminée l'emporte et l'autre est rejetée avec `409 compare_to_already_used` (et un webhook `capture_session.rejected`). Erreurs : `422 compare_to_not_found`, `compare_to_not_sealed`, `compare_to_mismatch`, `compare_to_is_after`, `compare_template_mismatch` ; `409 compare_to_already_used`.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"locale":{"type":"string","maxLength":35,"pattern":"^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$","description":"La langue de la personne qui capture, sous la forme d'une étiquette BCP 47 : `en`, `fr`, `es`, `de`, `pt-BR`, `es-419`, `zh-Hans`… La page de capture et les textes du modèle s'affichent dans cette langue quand il l'a (voir `GET /v1/capture-templates`). Sans elle, la langue de votre thème de capture est utilisée.","examples":["de"]},"return_url":{"type":"string","maxLength":2048,"format":"uri","description":"Où renvoyer la personne une fois la capture terminée : la page de capture affiche son texte de fin, puis ramène la personne à cette adresse après quelques secondes, avec `proof_id` et `session_id` ajoutés. Son site doit figurer dans vos origines de retour autorisées (`PATCH /v1/settings`), sinon l'appel échoue avec `422 return_url_not_allowed`. `https` seulement ; `http://localhost` est accepté avec une clé de bac à sable. Omettez-la pour laisser la personne sur la page.","examples":["https://app.example.com/bookings/4471/capture-done"]},"location_reference":{"type":"string","maxLength":100,"pattern":"^[A-Za-z0-9_.:/#=+-]{1,200}$","description":"Votre propre identifiant du lieu de la transaction (un site, un casier…). Même format que `external_reference`, 100 caractères au plus.","examples":["site_paris_12"]}},"required":["external_reference","party"],"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,255}$"},"example":"7f3c1e2a-9b4d-4e6f-8a1c-5d2b3e4f6a7b","in":"header","name":"idempotency-key","required":true,"description":"Une valeur unique pour chaque création que vous tentez (par exemple un UUID), de 8 à 255 caractères : lettres, chiffres, `_`, `.`, `:` et `-`. Renvoyez-la inchangée pour réessayer sans risque : vous obtenez la réponse d'origine. Conservée 24 heures."}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la session de capture.","examples":["cps_01m4akapdbe8e8qq3er9r5qwyj"]},"capture_url":{"type":"string","description":"Le lien à envoyer à la personne qui prend les photos. Il ne fonctionne qu'une fois et expire à `expires_at`.","examples":["https://capture.tryvidimus.com/3f9aXq…"]},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le lien cesse de fonctionner (ISO 8601, UTC).","examples":["2026-10-07T12:00:00.000Z"]},"mode":{"type":"string","enum":["live","test"],"description":"Le mode de votre clé d'API, dont la session hérite.","examples":["test"]},"compare_to":{"description":"La preuve à laquelle cette capture sera comparée (le `compare_to` envoyé) ; `null` pour une capture ordinaire.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]}},"required":["id","capture_url","expires_at","mode","compare_to"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"402":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-endpoints":{"post":{"summary":"Créer un endpoint de webhook","tags":["Endpoints de webhook"],"description":"Déclare une URL qui recevra les événements (voir la section *Webhooks* ci-dessus pour la signature). Renvoie l'endpoint avec son **secret, affiché une seule fois**. Jusqu'à 10 endpoints par mode ; `422 invalid_webhook_url` si l'URL n'est pas acceptable. Demande le droit `manage_webhooks`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"description":"Où nous envoyons les événements. HTTPS uniquement, sur un nom de domaine public (pas d'adresse IP, pas de `localhost`, pas de nom interne), sans identifiants ni fragment, sur le port 443 ou au-dessus de 1023.","examples":["https://example.com/webhooks/tryvidimus"]},"events":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements à recevoir, sans doublons : `proof.sealed`, `proof.failed`, `capture_session.completed`, `capture_session.rejected`, et deux réservés à une version ultérieure, `capture_session.expired` et `dossier.ready` (acceptés, mais jamais envoyés pour l'instant). Chaque message envoyé nomme ensuite son événement dans le champ `event` de son corps.","examples":[["proof.sealed","proof.failed"]]},"description":{"type":"string","maxLength":200,"description":"Une note pour vous, 200 caractères au plus.","examples":["Production, billing service"]}},"required":["url","events"],"additionalProperties":false}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'endpoint de webhook.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"L'endpoint appartient au mode de la clé qui l'a créé, et ne reçoit que les événements de ce mode.","examples":["test"]},"url":{"type":"string","description":"Où les événements sont envoyés.","examples":["https://example.com/webhooks/tryvidimus"]},"description":{"description":"Votre note, s'il y en a une.","type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements que cet endpoint reçoit.","examples":[["proof.sealed","proof.failed"]]},"status":{"type":"string","enum":["active","disabled"],"description":"Les endpoints `disabled` ne reçoivent rien."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'endpoint a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du secret.","examples":["whs_01m4akapdbe8e8qq3er9r5qwyj"]},"hint":{"type":"string","description":"Les premiers caractères du secret, pour le reconnaître. Jamais suffisants pour signer.","examples":["whsec_AbCd"]},"status":{"type":"string","enum":["active","expired"],"description":"`active` : sert à signer les envois. `expired` : n'est plus utilisé."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand ce secret cesse d'être utilisé, pendant une rotation ; `null` pour le secret courant."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le secret a été créé (ISO 8601, UTC)."}},"required":["id","hint","status","expires_at","created_at"],"additionalProperties":false},"description":"Les secrets de signature : un, ou deux pendant une rotation. Jamais le secret lui-même."},"secret":{"type":"string","description":"Le secret de signature en clair. **C'est la seule fois où il est affiché** : conservez-le tout de suite. Il n'est plus jamais renvoyé, et nous ne pouvons pas le relire.","examples":["whsec_…"]}},"required":["id","mode","url","description","events","status","created_at","updated_at","secrets","secret"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"503":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"get":{"summary":"Lister les endpoints de webhook","tags":["Endpoints de webhook"],"description":"Liste les endpoints de webhook de votre organisation, dans le mode de votre clé. Les secrets ne sont jamais inclus. Demande le droit `manage_webhooks`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'endpoint de webhook.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"L'endpoint appartient au mode de la clé qui l'a créé, et ne reçoit que les événements de ce mode.","examples":["test"]},"url":{"type":"string","description":"Où les événements sont envoyés.","examples":["https://example.com/webhooks/tryvidimus"]},"description":{"description":"Votre note, s'il y en a une.","type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements que cet endpoint reçoit.","examples":[["proof.sealed","proof.failed"]]},"status":{"type":"string","enum":["active","disabled"],"description":"Les endpoints `disabled` ne reçoivent rien."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'endpoint a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du secret.","examples":["whs_01m4akapdbe8e8qq3er9r5qwyj"]},"hint":{"type":"string","description":"Les premiers caractères du secret, pour le reconnaître. Jamais suffisants pour signer.","examples":["whsec_AbCd"]},"status":{"type":"string","enum":["active","expired"],"description":"`active` : sert à signer les envois. `expired` : n'est plus utilisé."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand ce secret cesse d'être utilisé, pendant une rotation ; `null` pour le secret courant."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le secret a été créé (ISO 8601, UTC)."}},"required":["id","hint","status","expires_at","created_at"],"additionalProperties":false},"description":"Les secrets de signature : un, ou deux pendant une rotation. Jamais le secret lui-même."}},"required":["id","mode","url","description","events","status","created_at","updated_at","secrets"],"additionalProperties":false},"description":"Vos endpoints de webhook, dans le mode de la clé."}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-endpoints/{id}":{"get":{"summary":"Lire un endpoint de webhook","tags":["Endpoints de webhook"],"description":"Renvoie un endpoint de webhook. Le secret n'est jamais inclus. Demande le droit `manage_webhooks`.","parameters":[{"schema":{"type":"string"},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'endpoint de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'endpoint de webhook.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"L'endpoint appartient au mode de la clé qui l'a créé, et ne reçoit que les événements de ce mode.","examples":["test"]},"url":{"type":"string","description":"Où les événements sont envoyés.","examples":["https://example.com/webhooks/tryvidimus"]},"description":{"description":"Votre note, s'il y en a une.","type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements que cet endpoint reçoit.","examples":[["proof.sealed","proof.failed"]]},"status":{"type":"string","enum":["active","disabled"],"description":"Les endpoints `disabled` ne reçoivent rien."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'endpoint a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du secret.","examples":["whs_01m4akapdbe8e8qq3er9r5qwyj"]},"hint":{"type":"string","description":"Les premiers caractères du secret, pour le reconnaître. Jamais suffisants pour signer.","examples":["whsec_AbCd"]},"status":{"type":"string","enum":["active","expired"],"description":"`active` : sert à signer les envois. `expired` : n'est plus utilisé."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand ce secret cesse d'être utilisé, pendant une rotation ; `null` pour le secret courant."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le secret a été créé (ISO 8601, UTC)."}},"required":["id","hint","status","expires_at","created_at"],"additionalProperties":false},"description":"Les secrets de signature : un, ou deux pendant une rotation. Jamais le secret lui-même."}},"required":["id","mode","url","description","events","status","created_at","updated_at","secrets"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"patch":{"summary":"Modifier un endpoint de webhook","tags":["Endpoints de webhook"],"description":"Change l'URL, les événements, la note ou le statut d'un endpoint. N'envoyez que les champs à modifier, au moins un. Utilisez `status: disabled` pour suspendre les envois sans supprimer l'endpoint. Demande le droit `manage_webhooks`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"description":"Où nous envoyons les événements. HTTPS uniquement, sur un nom de domaine public (pas d'adresse IP, pas de `localhost`, pas de nom interne), sans identifiants ni fragment, sur le port 443 ou au-dessus de 1023.","examples":["https://example.com/webhooks/tryvidimus"]},"events":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements à recevoir, sans doublons : `proof.sealed`, `proof.failed`, `capture_session.completed`, `capture_session.rejected`, et deux réservés à une version ultérieure, `capture_session.expired` et `dossier.ready` (acceptés, mais jamais envoyés pour l'instant). Chaque message envoyé nomme ensuite son événement dans le champ `event` de son corps.","examples":[["proof.sealed","proof.failed"]]},"description":{"anyOf":[{"type":"string","maxLength":200,"description":"Une note pour vous, 200 caractères au plus.","examples":["Production, billing service"]},{"type":"null"}],"description":"Une note pour vous, 200 caractères au plus. Envoyez `null` pour la supprimer."},"status":{"type":"string","enum":["active","disabled"],"description":"`disabled` arrête tous les envois vers cet endpoint ; `active` les reprend."}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string"},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'endpoint de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'endpoint de webhook.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"L'endpoint appartient au mode de la clé qui l'a créé, et ne reçoit que les événements de ce mode.","examples":["test"]},"url":{"type":"string","description":"Où les événements sont envoyés.","examples":["https://example.com/webhooks/tryvidimus"]},"description":{"description":"Votre note, s'il y en a une.","type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements que cet endpoint reçoit.","examples":[["proof.sealed","proof.failed"]]},"status":{"type":"string","enum":["active","disabled"],"description":"Les endpoints `disabled` ne reçoivent rien."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'endpoint a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du secret.","examples":["whs_01m4akapdbe8e8qq3er9r5qwyj"]},"hint":{"type":"string","description":"Les premiers caractères du secret, pour le reconnaître. Jamais suffisants pour signer.","examples":["whsec_AbCd"]},"status":{"type":"string","enum":["active","expired"],"description":"`active` : sert à signer les envois. `expired` : n'est plus utilisé."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand ce secret cesse d'être utilisé, pendant une rotation ; `null` pour le secret courant."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le secret a été créé (ISO 8601, UTC)."}},"required":["id","hint","status","expires_at","created_at"],"additionalProperties":false},"description":"Les secrets de signature : un, ou deux pendant une rotation. Jamais le secret lui-même."}},"required":["id","mode","url","description","events","status","created_at","updated_at","secrets"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"delete":{"summary":"Supprimer un endpoint de webhook","tags":["Endpoints de webhook"],"description":"Supprime un endpoint : il ne reçoit plus rien. Demande le droit `manage_webhooks`.","parameters":[{"schema":{"type":"string"},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'endpoint de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Réponse par défaut"},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-endpoints/{id}/rotate-secret":{"post":{"summary":"Faire tourner le secret d'un endpoint","tags":["Endpoints de webhook"],"description":"Crée un nouveau secret et garde l'ancien valide pendant `expires_in_seconds` (24 heures par défaut, 7 jours au plus), pour que vous puissiez basculer sans perdre un appel : pendant ce temps, chaque envoi porte une signature par secret actif. Le nouveau secret n'est **affiché qu'une seule fois**. Tant que deux secrets sont actifs, une nouvelle rotation échoue avec `409 rotation_in_progress`. Demande le droit `manage_webhooks`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in_seconds":{"type":"integer","minimum":60,"maximum":604800,"description":"Combien de temps l'ancien secret reste valide, en secondes : de 60 à 604800 (7 jours). Une valeur par défaut s'applique si vous l'omettez (24 heures).","examples":[86400]}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string"},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'endpoint de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'endpoint de webhook.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"L'endpoint appartient au mode de la clé qui l'a créé, et ne reçoit que les événements de ce mode.","examples":["test"]},"url":{"type":"string","description":"Où les événements sont envoyés.","examples":["https://example.com/webhooks/tryvidimus"]},"description":{"description":"Votre note, s'il y en a une.","type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.expired","capture_session.completed","capture_session.rejected","dossier.ready"]},"description":"Les événements que cet endpoint reçoit.","examples":[["proof.sealed","proof.failed"]]},"status":{"type":"string","enum":["active","disabled"],"description":"Les endpoints `disabled` ne reçoivent rien."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'endpoint a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du secret.","examples":["whs_01m4akapdbe8e8qq3er9r5qwyj"]},"hint":{"type":"string","description":"Les premiers caractères du secret, pour le reconnaître. Jamais suffisants pour signer.","examples":["whsec_AbCd"]},"status":{"type":"string","enum":["active","expired"],"description":"`active` : sert à signer les envois. `expired` : n'est plus utilisé."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand ce secret cesse d'être utilisé, pendant une rotation ; `null` pour le secret courant."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le secret a été créé (ISO 8601, UTC)."}},"required":["id","hint","status","expires_at","created_at"],"additionalProperties":false},"description":"Les secrets de signature : un, ou deux pendant une rotation. Jamais le secret lui-même."},"secret":{"type":"string","description":"Le secret de signature en clair. **C'est la seule fois où il est affiché** : conservez-le tout de suite. Il n'est plus jamais renvoyé, et nous ne pouvons pas le relire.","examples":["whsec_…"]}},"required":["id","mode","url","description","events","status","created_at","updated_at","secrets","secret"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"503":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-deliveries":{"get":{"summary":"Lister les envois de webhook","tags":["Endpoints de webhook"],"description":"Le journal de ce qui a été envoyé à vos endpoints, du plus récent au plus ancien, dans le mode de votre clé, avec une pagination par curseur. Chaque envoi est un événement pour un endpoint, avec son état (`pending`, `delivered`, `failed` ou `abandoned`), le nombre de tentatives et le statut HTTP que votre serveur a répondu en dernier. Filtrez par `endpoint_id` ou `status` (par exemple `abandoned` pour retrouver les événements que votre serveur n'a jamais acceptés). Le contenu envoyé n'est jamais inclus. Un curseur modifié échoue avec `422 invalid_cursor` ; un `endpoint_id` inconnu avec `404 webhook_endpoint_not_found`. Demande le droit `manage_webhooks`.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"example":20,"in":"query","name":"limit","required":false,"description":"Nombre d'envois à renvoyer, de 1 à 100."},{"schema":{"type":"string","maxLength":300},"in":"query","name":"cursor","required":false,"description":"Le `next_cursor` de la page précédente. Opaque : ne le construisez pas et ne le modifiez pas."},{"schema":{"type":"string","maxLength":40},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"query","name":"endpoint_id","required":false,"description":"Seulement les envois vers cet endpoint de webhook."},{"schema":{"type":"string","enum":["pending","delivered","failed","abandoned"]},"example":"failed","in":"query","name":"status","required":false,"description":"Seulement les envois dans cet état, par exemple `failed` ou `abandoned` pour trouver ce qui demande votre attention."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de cette série de tentatives d'envoi.","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]},"endpoint_id":{"type":"string","description":"L'endpoint de webhook auquel l'événement est envoyé.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"event_id":{"type":"string","description":"Identifiant de l'événement : le même à chaque tentative (l'en-tête `X-Event-Id`), servez-vous-en pour ignorer les doublons.","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]},"event_type":{"type":"string","description":"L'événement, par exemple `proof.sealed`.","examples":["proof.sealed"]},"status":{"type":"string","enum":["pending","delivered","failed","abandoned"],"description":"`pending` : en attente de sa première ou de sa prochaine tentative. `delivered` : votre serveur a répondu par un `2xx`. `failed` : la dernière tentative a échoué, une nouvelle est prévue. `abandoned` : toutes les tentatives ont échoué, nous avons arrêté.","examples":["delivered"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de tentatives faites.","examples":[1]},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la prochaine tentative est prévue (ISO 8601, UTC) ; `null` quand aucune ne l'est."},"last_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la dernière tentative a été faite (ISO 8601, UTC) ; `null` avant la première."},"response_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Le statut HTTP que votre serveur a répondu à la dernière tentative ; `null` s'il n'a pas répondu.","examples":[200]},"error":{"anyOf":[{"type":"string","enum":["http_status","network_error","blocked_address","invalid_url","no_active_secret"]},{"type":"null"}],"description":"Pourquoi la dernière tentative a échoué, en un mot : `http_status` (votre serveur a répondu hors `2xx`), `network_error` (injoignable, délai dépassé, certificat refusé), `blocked_address` (l'adresse vise une adresse non publique), `invalid_url`, `no_active_secret`. `null` quand la dernière tentative a réussi ou qu'il n'y en a pas eu.","examples":["http_status"]},"test":{"type":"boolean","description":"`true` pour un événement de test que vous avez envoyé vous-même avec `POST /v1/webhook-endpoints/{id}/test`."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'événement a été mis en file pour cet endpoint (ISO 8601, UTC)."}},"required":["id","endpoint_id","event_id","event_type","status","attempts","next_attempt_at","last_attempt_at","response_code","error","test","created_at"],"additionalProperties":false},"description":"Les envois vers vos endpoints dans le mode de la clé, du plus récent au plus ancien."},"has_more":{"type":"boolean","description":"`true` quand il reste des envois après cette page."},"next_cursor":{"description":"À donner comme `cursor` pour obtenir la page suivante ; `null` sur la dernière page.","type":["string","null"]}},"required":["data","has_more","next_cursor"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-deliveries/{id}":{"get":{"summary":"Lire un envoi de webhook","tags":["Endpoints de webhook"],"description":"Un envoi avec ce qui a été envoyé : le `payload` JSON de l'événement exactement tel que votre endpoint l'a reçu (copiez-le pour rejouer l'événement sur votre propre serveur), l'état, le nombre de tentatives, le statut HTTP et le début de la réponse de votre serveur à la dernière tentative, et la raison d'un échec. Demande le droit `manage_webhooks`.","parameters":[{"schema":{"type":"string"},"example":"whd_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'envoi de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de cette série de tentatives d'envoi.","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]},"endpoint_id":{"type":"string","description":"L'endpoint de webhook auquel l'événement est envoyé.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"event_id":{"type":"string","description":"Identifiant de l'événement : le même à chaque tentative (l'en-tête `X-Event-Id`), servez-vous-en pour ignorer les doublons.","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]},"event_type":{"type":"string","description":"L'événement, par exemple `proof.sealed`.","examples":["proof.sealed"]},"status":{"type":"string","enum":["pending","delivered","failed","abandoned"],"description":"`pending` : en attente de sa première ou de sa prochaine tentative. `delivered` : votre serveur a répondu par un `2xx`. `failed` : la dernière tentative a échoué, une nouvelle est prévue. `abandoned` : toutes les tentatives ont échoué, nous avons arrêté.","examples":["delivered"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de tentatives faites.","examples":[1]},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la prochaine tentative est prévue (ISO 8601, UTC) ; `null` quand aucune ne l'est."},"last_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la dernière tentative a été faite (ISO 8601, UTC) ; `null` avant la première."},"response_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Le statut HTTP que votre serveur a répondu à la dernière tentative ; `null` s'il n'a pas répondu.","examples":[200]},"error":{"anyOf":[{"type":"string","enum":["http_status","network_error","blocked_address","invalid_url","no_active_secret"]},{"type":"null"}],"description":"Pourquoi la dernière tentative a échoué, en un mot : `http_status` (votre serveur a répondu hors `2xx`), `network_error` (injoignable, délai dépassé, certificat refusé), `blocked_address` (l'adresse vise une adresse non publique), `invalid_url`, `no_active_secret`. `null` quand la dernière tentative a réussi ou qu'il n'y en a pas eu.","examples":["http_status"]},"test":{"type":"boolean","description":"`true` pour un événement de test que vous avez envoyé vous-même avec `POST /v1/webhook-endpoints/{id}/test`."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'événement a été mis en file pour cet endpoint (ISO 8601, UTC)."},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Le corps JSON de l'événement, exactement tel qu'il a été envoyé à votre endpoint (le même à chaque tentative). Copiez-le pour rejouer l'événement sur votre propre serveur.","examples":[{"event":"proof.sealed","proof_id":"prf_01m4akapdbe8e8qq3er9r5qwyj","status":"sealed"}]},"response_body":{"description":"Le début de ce que votre serveur a répondu à la dernière tentative (4 096 caractères au plus) ; `null` s'il n'a pas répondu ou n'a rien envoyé.","examples":["{\"received\":true}"],"type":["string","null"]}},"required":["id","endpoint_id","event_id","event_type","status","attempts","next_attempt_at","last_attempt_at","response_code","error","test","created_at","payload","response_body"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/webhook-endpoints/{id}/test":{"post":{"summary":"Envoyer un événement de test à un endpoint de webhook","tags":["Endpoints de webhook"],"description":"Envoie un événement d'exemple à un endpoint, pour essayer votre serveur : le corps a les mêmes champs que le vrai événement, avec des valeurs d'exemple et `\"test\": true`, et il est signé avec le secret de l'endpoint comme tout envoi (voir la section *Webhooks* plus haut). Il apparaît dans le journal des envois avec `test: true`. L'endpoint doit être `active` (`409 webhook_endpoint_disabled` sinon) ; au plus 20 événements de test par endpoint et par heure (`429 too_many_test_events`). Demande le droit `manage_webhooks`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event_type":{"type":"string","enum":["proof.sealed","proof.failed","capture_session.completed","capture_session.rejected"],"description":"L'événement à envoyer en test : son corps a les mêmes champs que le vrai événement, avec des valeurs d'exemple et `\"test\": true`.","examples":["proof.sealed"]}},"required":["event_type"],"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string"},"example":"whe_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de l'endpoint de webhook."}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de cette série de tentatives d'envoi.","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]},"endpoint_id":{"type":"string","description":"L'endpoint de webhook auquel l'événement est envoyé.","examples":["whe_01m4akapdbe8e8qq3er9r5qwyj"]},"event_id":{"type":"string","description":"Identifiant de l'événement : le même à chaque tentative (l'en-tête `X-Event-Id`), servez-vous-en pour ignorer les doublons.","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]},"event_type":{"type":"string","description":"L'événement, par exemple `proof.sealed`.","examples":["proof.sealed"]},"status":{"type":"string","enum":["pending","delivered","failed","abandoned"],"description":"`pending` : en attente de sa première ou de sa prochaine tentative. `delivered` : votre serveur a répondu par un `2xx`. `failed` : la dernière tentative a échoué, une nouvelle est prévue. `abandoned` : toutes les tentatives ont échoué, nous avons arrêté.","examples":["delivered"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de tentatives faites.","examples":[1]},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la prochaine tentative est prévue (ISO 8601, UTC) ; `null` quand aucune ne l'est."},"last_attempt_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la dernière tentative a été faite (ISO 8601, UTC) ; `null` avant la première."},"response_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Le statut HTTP que votre serveur a répondu à la dernière tentative ; `null` s'il n'a pas répondu.","examples":[200]},"error":{"anyOf":[{"type":"string","enum":["http_status","network_error","blocked_address","invalid_url","no_active_secret"]},{"type":"null"}],"description":"Pourquoi la dernière tentative a échoué, en un mot : `http_status` (votre serveur a répondu hors `2xx`), `network_error` (injoignable, délai dépassé, certificat refusé), `blocked_address` (l'adresse vise une adresse non publique), `invalid_url`, `no_active_secret`. `null` quand la dernière tentative a réussi ou qu'il n'y en a pas eu.","examples":["http_status"]},"test":{"type":"boolean","description":"`true` pour un événement de test que vous avez envoyé vous-même avec `POST /v1/webhook-endpoints/{id}/test`."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand l'événement a été mis en file pour cet endpoint (ISO 8601, UTC)."}},"required":["id","endpoint_id","event_id","event_type","status","attempts","next_attempt_at","last_attempt_at","response_code","error","test","created_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/proofs/{id}":{"get":{"summary":"Lire une preuve","tags":["Preuves"],"description":"Renvoie une preuve de votre organisation, dans le mode de votre clé : son statut, la raison de l'échec le cas échéant, et ses fichiers. Demande le droit `read_proof`. Une preuve inconnue, ou qui appartient à une autre organisation ou à un autre mode, donne le même `404 proof_not_found`.","parameters":[{"schema":{"type":"string"},"example":"prf_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de la preuve."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"status":{"type":"string","enum":["pending","processing","sealed","failed"],"description":"`pending` : créée, en attente de traitement. `processing` : en cours de vérification, de signature et d'horodatage (voir `processing_stage`). `sealed` : signée et horodatée, définitive. `failed` : voir `failure`.","examples":["sealed"]},"processing_stage":{"anyOf":[{"type":"string","enum":["verifying","signing","awaiting_timestamp"]},{"type":"null"}],"description":"Pendant `processing` : `verifying` (nous relisons les fichiers), `signing` (nous signons les copies), `awaiting_timestamp` (en attente du jeton d'horodatage). `null` sinon."},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","description":"Pourquoi elle a échoué, par exemple `hash_mismatch` (le fichier reçu n'est pas celui qui a été déclaré) ou `invalid_media` (ce n'est pas une photo ou une vidéo valide). Fiez-vous à `retriable` pour savoir si l'échec peut être relancé.","examples":["hash_mismatch"]},"retriable":{"type":"boolean","description":"`true` quand la cause était passagère de notre côté. Avant de signaler un échec, nous réessayons déjà automatiquement (signature : jusqu'à 8 essais ; horodatage : jusqu'à 24 heures) : une preuve en échec n'est donc plus réessayée d'elle-même, mais nous pouvons la relancer pour vous sur demande. Ne créez pas de nouvelle session de capture, les fichiers sont conservés avec la preuve. `false` : l'échec est définitif et demande une nouvelle capture."}},"required":["code","retriable"],"additionalProperties":false},{"type":"null"}],"description":"Présent seulement quand `status` vaut `failed`."},"mode":{"type":"string","enum":["live","test"],"description":"Mode de la clé qui a créé la preuve.","examples":["test"]},"external_reference":{"type":"string","description":"L'identifiant que vous avez donné en créant la session de capture.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos.","examples":["provider"]},"stage":{"description":"Le moment de la transaction, tel que vous l'avez déclaré.","examples":["pickup"],"type":["string","null"]},"category":{"description":"La catégorie, telle que vous l'avez déclarée.","examples":["vehicle"],"type":["string","null"]},"location_reference":{"description":"Le lieu, tel que vous l'avez déclaré.","type":["string","null"]},"dispute_status":{"type":"string","enum":["none","active"],"description":"`active` tant que la preuve fait l'objet d'un litige : ses fichiers sont alors conservés jusqu'à la clôture du litige."},"compare_to":{"anyOf":[{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},{"type":"null"}],"description":"Quand cette preuve est un « après », l'`id` de l'« avant » auquel elle devait être comparée ; `null` sinon.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"compared_by":{"anyOf":[{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},{"type":"null"}],"description":"Quand cette preuve est un « avant », l'`id` de l'« après » capturé pour lui être comparé ; `null` tant qu'il n'en a pas. Une preuve est soit un « avant », soit un « après », et a au plus un partenaire.","examples":["prf_01m4akapdbe8ev5xgt0hkpcn14"]},"skipped":{"type":"array","items":{"type":"object","properties":{"step_id":{"type":"string","description":"L'`id` de la prise de vue du modèle.","examples":["garden"]},"reason":{"type":"string","enum":["nothing_to_report","not_applicable"],"description":"Ce que la personne a déclaré : rien à signaler, ou la prise de vue ne s'applique pas.","examples":["nothing_to_report"]}},"required":["step_id","reason"],"additionalProperties":false},"description":"Les prises de vue que la personne a déclarées au lieu de les photographier (le modèle devait l'autoriser). Ce sont des déclarations de la personne qui a capturé, pas des mesures de notre part ; vide s'il n'y en a pas."},"credits_consumed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Montant débité pour cette preuve, en euros. Il est débité quand la preuve est scellée, en production seulement : `0` pour une preuve de bac à sable, ou tant que la preuve n'est pas scellée. Le mouvement figure dans `GET /v1/credits/transactions`.","examples":[1]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand la preuve a été créée (ISO 8601, UTC)."},"sealed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la preuve a été scellée (ISO 8601, UTC) ; `null` jusque-là."},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du fichier.","examples":["med_01m4akapdbe8ev5xgt0hkpcn14"]},"media_type":{"type":"string","enum":["photo","video"],"description":"Type de fichier.","examples":["photo"]},"mime_type":{"type":"string","description":"Type du fichier.","examples":["image/jpeg"]},"size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille du fichier original en octets.","examples":[36525]},"label":{"description":"Le libellé donné lors de la demande d'envoi, s'il y en a un.","examples":["front"],"type":["string","null"]},"captured_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand notre service a reçu le fichier (ISO 8601, UTC). C'est l'heure que nous avons observée, pas celle affichée par le téléphone, et ce n'est pas un horodatage qualifié : seul l'horodatage de la preuve (`gen_time`) prouve quand elle existait."},"original_sha256":{"description":"SHA-256 du fichier original, tel que nous l'avons mesuré.","type":["string","null"]},"signed_sha256":{"description":"SHA-256 de la copie signée (C2PA), une fois qu'elle existe.","type":["string","null"]},"signed":{"type":"boolean","description":"`true` quand la copie signée existe. Téléchargez-la avec le lien d'accès une fois la preuve scellée."}},"required":["id","media_type","mime_type","size_bytes","label","captured_at","original_sha256","signed_sha256","signed"],"additionalProperties":false},"description":"Les fichiers de la preuve."}},"required":["id","status","processing_stage","failure","mode","external_reference","party","stage","category","location_reference","dispute_status","compare_to","compared_by","skipped","credits_consumed","created_at","sealed_at","media"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/proofs":{"get":{"summary":"Lister les preuves","tags":["Preuves"],"description":"Liste les preuves de votre organisation, dans le mode de votre clé, avec une pagination par curseur. Filtrez par `status`, `external_reference`, `party`, `stage` ou `category` ; triez avec `sort`. Un curseur modifié, ou issu de l'autre sens de tri, échoue avec `422 invalid_cursor`. Demande le droit `read_proof`.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"example":20,"in":"query","name":"limit","required":false,"description":"Combien de preuves renvoyer, de 1 à 100."},{"schema":{"type":"string","maxLength":300},"in":"query","name":"cursor","required":false,"description":"Le `next_cursor` de la page précédente. Opaque : ne le construisez pas et ne le modifiez pas."},{"schema":{"type":"string","enum":["pending","processing","sealed","failed"]},"example":"sealed","in":"query","name":"status","required":false,"description":"Seulement les preuves ayant ce statut."},{"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:/#=+-]{1,200}$"},"example":"booking_4471","in":"query","name":"external_reference","required":false,"description":"Seulement les preuves de cette transaction."},{"schema":{"type":"string","enum":["provider","recipient"]},"in":"query","name":"party","required":false,"description":"Seulement les preuves prises par cette partie."},{"schema":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},"example":"pickup","in":"query","name":"stage","required":false,"description":"Seulement les preuves de cette étape."},{"schema":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},"in":"query","name":"category","required":false,"description":"Seulement les preuves de cette catégorie."},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"linked","required":false,"description":"`false` : seulement les preuves sans partenaire (pas encore comparées à une autre, et qui ne sont pas l'« après » d'une autre) : celles qui attendent encore leur « après ». `true` : seulement les preuves qui font partie d'une paire « avant » et « après »."},{"schema":{"default":"-created_at","type":"string","enum":["created_at","-created_at"]},"in":"query","name":"sort","required":false,"description":"Tri par date de création : `created_at` du plus ancien au plus récent, `-created_at` du plus récent au plus ancien."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"status":{"type":"string","enum":["pending","processing","sealed","failed"],"description":"`pending` : créée, en attente de traitement. `processing` : en cours de vérification, de signature et d'horodatage (voir `processing_stage`). `sealed` : signée et horodatée, définitive. `failed` : voir `failure`.","examples":["sealed"]},"processing_stage":{"anyOf":[{"type":"string","enum":["verifying","signing","awaiting_timestamp"]},{"type":"null"}],"description":"Pendant `processing` : `verifying` (nous relisons les fichiers), `signing` (nous signons les copies), `awaiting_timestamp` (en attente du jeton d'horodatage). `null` sinon."},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","description":"Pourquoi elle a échoué, par exemple `hash_mismatch` (le fichier reçu n'est pas celui qui a été déclaré) ou `invalid_media` (ce n'est pas une photo ou une vidéo valide). Fiez-vous à `retriable` pour savoir si l'échec peut être relancé.","examples":["hash_mismatch"]},"retriable":{"type":"boolean","description":"`true` quand la cause était passagère de notre côté. Avant de signaler un échec, nous réessayons déjà automatiquement (signature : jusqu'à 8 essais ; horodatage : jusqu'à 24 heures) : une preuve en échec n'est donc plus réessayée d'elle-même, mais nous pouvons la relancer pour vous sur demande. Ne créez pas de nouvelle session de capture, les fichiers sont conservés avec la preuve. `false` : l'échec est définitif et demande une nouvelle capture."}},"required":["code","retriable"],"additionalProperties":false},{"type":"null"}],"description":"Présent seulement quand `status` vaut `failed`."},"mode":{"type":"string","enum":["live","test"],"description":"Mode de la clé qui a créé la preuve.","examples":["test"]},"external_reference":{"type":"string","description":"L'identifiant que vous avez donné en créant la session de capture.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos.","examples":["provider"]},"stage":{"description":"Le moment de la transaction, tel que vous l'avez déclaré.","examples":["pickup"],"type":["string","null"]},"category":{"description":"La catégorie, telle que vous l'avez déclarée.","examples":["vehicle"],"type":["string","null"]},"location_reference":{"description":"Le lieu, tel que vous l'avez déclaré.","type":["string","null"]},"dispute_status":{"type":"string","enum":["none","active"],"description":"`active` tant que la preuve fait l'objet d'un litige : ses fichiers sont alors conservés jusqu'à la clôture du litige."},"compare_to":{"anyOf":[{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},{"type":"null"}],"description":"Quand cette preuve est un « après », l'`id` de l'« avant » auquel elle devait être comparée ; `null` sinon.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"compared_by":{"anyOf":[{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},{"type":"null"}],"description":"Quand cette preuve est un « avant », l'`id` de l'« après » capturé pour lui être comparé ; `null` tant qu'il n'en a pas. Une preuve est soit un « avant », soit un « après », et a au plus un partenaire.","examples":["prf_01m4akapdbe8ev5xgt0hkpcn14"]},"skipped":{"type":"array","items":{"type":"object","properties":{"step_id":{"type":"string","description":"L'`id` de la prise de vue du modèle.","examples":["garden"]},"reason":{"type":"string","enum":["nothing_to_report","not_applicable"],"description":"Ce que la personne a déclaré : rien à signaler, ou la prise de vue ne s'applique pas.","examples":["nothing_to_report"]}},"required":["step_id","reason"],"additionalProperties":false},"description":"Les prises de vue que la personne a déclarées au lieu de les photographier (le modèle devait l'autoriser). Ce sont des déclarations de la personne qui a capturé, pas des mesures de notre part ; vide s'il n'y en a pas."},"credits_consumed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Montant débité pour cette preuve, en euros. Il est débité quand la preuve est scellée, en production seulement : `0` pour une preuve de bac à sable, ou tant que la preuve n'est pas scellée. Le mouvement figure dans `GET /v1/credits/transactions`.","examples":[1]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand la preuve a été créée (ISO 8601, UTC)."},"sealed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la preuve a été scellée (ISO 8601, UTC) ; `null` jusque-là."},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du fichier.","examples":["med_01m4akapdbe8ev5xgt0hkpcn14"]},"media_type":{"type":"string","enum":["photo","video"],"description":"Type de fichier.","examples":["photo"]},"mime_type":{"type":"string","description":"Type du fichier.","examples":["image/jpeg"]},"size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille du fichier original en octets.","examples":[36525]},"label":{"description":"Le libellé donné lors de la demande d'envoi, s'il y en a un.","examples":["front"],"type":["string","null"]},"captured_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand notre service a reçu le fichier (ISO 8601, UTC). C'est l'heure que nous avons observée, pas celle affichée par le téléphone, et ce n'est pas un horodatage qualifié : seul l'horodatage de la preuve (`gen_time`) prouve quand elle existait."},"original_sha256":{"description":"SHA-256 du fichier original, tel que nous l'avons mesuré.","type":["string","null"]},"signed_sha256":{"description":"SHA-256 de la copie signée (C2PA), une fois qu'elle existe.","type":["string","null"]},"signed":{"type":"boolean","description":"`true` quand la copie signée existe. Téléchargez-la avec le lien d'accès une fois la preuve scellée."}},"required":["id","media_type","mime_type","size_bytes","label","captured_at","original_sha256","signed_sha256","signed"],"additionalProperties":false},"description":"Les fichiers de la preuve."}},"required":["id","status","processing_stage","failure","mode","external_reference","party","stage","category","location_reference","dispute_status","compare_to","compared_by","skipped","credits_consumed","created_at","sealed_at","media"],"additionalProperties":false},"description":"Les preuves de cette page."},"has_more":{"type":"boolean","description":"`true` quand une autre page existe."},"next_cursor":{"description":"Renvoyez-le comme `cursor` pour obtenir la page suivante ; `null` sur la dernière page.","type":["string","null"]}},"required":["data","has_more","next_cursor"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/proofs/{id}/media/{media_id}/access-link":{"get":{"summary":"Obtenir un lien de téléchargement d'une copie signée","tags":["Preuves"],"description":"Renvoie un lien temporaire (15 minutes par défaut) pour télécharger la **copie signée** d'un fichier. L'original n'est jamais proposé. Seulement pour une preuve `sealed` : sinon `409 proof_not_sealed`. Le fichier vient directement du stockage. Demande le droit `read_proof`.","parameters":[{"schema":{"type":"string"},"example":"prf_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de la preuve."},{"schema":{"type":"string"},"example":"med_01m4akapdbe8ev5xgt0hkpcn14","in":"path","name":"media_id","required":true,"description":"Identifiant du fichier, tiré de `media` dans la preuve."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Un lien de téléchargement temporaire vers la copie signée. Le fichier vient directement du stockage ; ne conservez pas le lien."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le lien cesse de fonctionner (ISO 8601, UTC). 15 minutes après sa création, par défaut."}},"required":["url","expires_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-templates":{"post":{"summary":"Créer un modèle de capture","tags":["Modèles de capture"],"description":"Définit ce que demande la page de capture : les prises de vue et les textes d'accueil et de fin. Vous désignez le modèle par son `id` (`tpl_…`), renvoyé ici : donnez-le en `template_id` quand vous créez une session de capture. Le `name` n'est qu'un libellé. Un modèle sans `stage` ni `category` n'est jamais choisi automatiquement : désignez-le avec `template_id`. En production, un modèle déjà utilisé par une session de capture ne peut plus être modifié (`409 template_in_use`) : dupliquez-le. Demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"default":"en","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"],"type":"string","maxLength":35,"pattern":"^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$"},"stage":{"default":null,"description":"Utiliser ce modèle automatiquement pour les sessions créées avec ce `stage`. Un couple `stage` et `category` n'appartient qu'à un seul modèle.","examples":["pickup"],"anyOf":[{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},{"type":"null"}]},"category":{"default":null,"description":"Utiliser ce modèle automatiquement pour les sessions créées avec cette `category` (avec `stage` quand les deux sont donnés).","examples":["vehicle"],"anyOf":[{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},{"type":"null"}]},"session_ttl_minutes":{"default":null,"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180],"anyOf":[{"type":"integer","minimum":10,"maximum":720},{"type":"null"}]},"max_extra_photos":{"default":10,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10],"type":"integer","minimum":0,"maximum":20},"theme_id":{"default":null,"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"welcome":{"type":"object","properties":{"title":{"default":null,"description":"Titre de l'écran d'accueil, 120 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}]},"body":{"default":null,"description":"Texte de l'écran d'accueil, 600 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}]}},"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"default":null,"description":"Titre de l'écran de fin, 120 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}]},"body":{"default":null,"description":"Texte de l'écran de fin, 600 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}]}},"additionalProperties":false,"description":"L'écran de fin."},"steps":{"default":[],"maxItems":30,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"default":null,"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."],"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}]},"required":{"default":true,"description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue.","type":"boolean"},"min_photos":{"default":1,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2],"type":"integer","minimum":1,"maximum":20},"max_photos":{"default":1,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6],"type":"integer","minimum":1,"maximum":20},"section":{"default":null,"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}],"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}]},"allowed_skips":{"default":[],"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]],"maxItems":2,"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]}}},"required":["id","label"],"additionalProperties":false},"description":"Les prises de vue à réaliser, dans l'ordre, 30 au plus, chacune avec son propre `id`. Une liste vide signifie : photographier librement."}},"required":["name"],"additionalProperties":false}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du modèle : la façon de le désigner (`template_id` quand vous créez une session de capture, et dans le chemin des routes ci-dessous). Il ne change jamais.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"type":"string","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"]},"locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles ce modèle a des textes, la langue par défaut comprise. La page de capture peut s'afficher dans chacune d'elles.","examples":[["de","en","fr"]]},"stage":{"description":"Le `stage` pour lequel ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"category":{"description":"La `category` pour laquelle ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"session_ttl_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180]},"max_extra_photos":{"type":"integer","minimum":0,"maximum":20,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10]},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"welcome":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":0,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}],"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2]},"max_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]]}},"required":["id","label","instruction","required","min_photos","max_photos","section","allowed_skips"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"in_use":{"type":"boolean","description":"`true` dès qu'au moins une session de capture a été créée à partir de ce modèle. Un modèle de production utilisé ne peut plus être modifié : dupliquez-le et modifiez la copie."},"archived_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand le modèle a été archivé (ISO 8601, UTC), ou `null` tant qu'il est actif. Un modèle archivé ne démarre plus de session ; les sessions et les preuves déjà faites gardent leur copie."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le modèle a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."}},"required":["id","name","default_locale","locales","stage","category","session_ttl_minutes","max_extra_photos","theme_id","welcome","completion","steps","in_use","archived_at","created_at","updated_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"get":{"summary":"Lister les modèles de capture","tags":["Modèles de capture"],"description":"Liste les modèles de capture de votre organisation, par libellé : les actifs, ou les archivés avec `archived=true`. Paginée : `limit` (50 par défaut, 100 au plus) et le `next_cursor` de la page précédente ; `has_more` dit s’il existe une autre page. Demande le droit `manage_templates`.","parameters":[{"schema":{"default":"false","type":"string","enum":["true","false"]},"in":"query","name":"archived","required":false,"description":"`false` (défaut) : vos modèles actifs. `true` : vos modèles archivés seulement."},{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"example":20,"in":"query","name":"limit","required":false,"description":"Combien de modèles renvoyer, de 1 à 100."},{"schema":{"type":"string","maxLength":400},"in":"query","name":"cursor","required":false,"description":"Le `next_cursor` de la page précédente. Opaque : ne le construisez pas et ne le modifiez pas."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du modèle : la façon de le désigner (`template_id` quand vous créez une session de capture, et dans le chemin des routes ci-dessous). Il ne change jamais.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"type":"string","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"]},"locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles ce modèle a des textes, la langue par défaut comprise. La page de capture peut s'afficher dans chacune d'elles.","examples":[["de","en","fr"]]},"stage":{"description":"Le `stage` pour lequel ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"category":{"description":"La `category` pour laquelle ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"session_ttl_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180]},"max_extra_photos":{"type":"integer","minimum":0,"maximum":20,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10]},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"welcome":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":0,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}],"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2]},"max_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]]}},"required":["id","label","instruction","required","min_photos","max_photos","section","allowed_skips"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"in_use":{"type":"boolean","description":"`true` dès qu'au moins une session de capture a été créée à partir de ce modèle. Un modèle de production utilisé ne peut plus être modifié : dupliquez-le et modifiez la copie."},"archived_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand le modèle a été archivé (ISO 8601, UTC), ou `null` tant qu'il est actif. Un modèle archivé ne démarre plus de session ; les sessions et les preuves déjà faites gardent leur copie."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le modèle a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."}},"required":["id","name","default_locale","locales","stage","category","session_ttl_minutes","max_extra_photos","theme_id","welcome","completion","steps","in_use","archived_at","created_at","updated_at"],"additionalProperties":false},"description":"Les modèles de capture de cette page, par libellé."},"has_more":{"type":"boolean","description":"`true` quand une autre page existe."},"next_cursor":{"description":"À donner comme `cursor` pour obtenir la page suivante ; `null` sur la dernière page.","type":["string","null"]}},"required":["data","has_more","next_cursor"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-templates/{id}":{"get":{"summary":"Consulter un modèle de capture","tags":["Modèles de capture"],"description":"Renvoie un modèle de capture par son `id`, archivé ou non. Demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":80},"example":"tpl_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du modèle (`tpl_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du modèle : la façon de le désigner (`template_id` quand vous créez une session de capture, et dans le chemin des routes ci-dessous). Il ne change jamais.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"type":"string","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"]},"locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles ce modèle a des textes, la langue par défaut comprise. La page de capture peut s'afficher dans chacune d'elles.","examples":[["de","en","fr"]]},"stage":{"description":"Le `stage` pour lequel ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"category":{"description":"La `category` pour laquelle ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"session_ttl_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180]},"max_extra_photos":{"type":"integer","minimum":0,"maximum":20,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10]},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"welcome":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":0,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}],"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2]},"max_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]]}},"required":["id","label","instruction","required","min_photos","max_photos","section","allowed_skips"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"in_use":{"type":"boolean","description":"`true` dès qu'au moins une session de capture a été créée à partir de ce modèle. Un modèle de production utilisé ne peut plus être modifié : dupliquez-le et modifiez la copie."},"archived_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand le modèle a été archivé (ISO 8601, UTC), ou `null` tant qu'il est actif. Un modèle archivé ne démarre plus de session ; les sessions et les preuves déjà faites gardent leur copie."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le modèle a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."}},"required":["id","name","default_locale","locales","stage","category","session_ttl_minutes","max_extra_photos","theme_id","welcome","completion","steps","in_use","archived_at","created_at","updated_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"patch":{"summary":"Modifier un modèle de capture","tags":["Modèles de capture"],"description":"Modifie le libellé, les prises de vue, les textes, le `stage` ou la `category` d'un modèle. Envoyez seulement les champs à changer, au moins un ; un champ envoyé remplace entièrement la valeur précédente (envoyez toutes les `steps` pour en changer une). Un modèle de **production** à partir duquel des sessions de capture ont déjà été créées est figé : l'appel échoue avec `409 template_in_use` ; dupliquez-le avec `POST /v1/capture-templates/{id}/duplicate` et modifiez la copie. Les modèles du bac à sable restent modifiables. Un modèle archivé échoue avec `409 template_archived`. Demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"stage":{"description":"Utiliser ce modèle automatiquement pour les sessions créées avec ce `stage`. Un couple `stage` et `category` n'appartient qu'à un seul modèle.","examples":["pickup"],"anyOf":[{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},{"type":"null"}]},"category":{"description":"Utiliser ce modèle automatiquement pour les sessions créées avec cette `category` (avec `stage` quand les deux sont donnés).","examples":["vehicle"],"anyOf":[{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"},{"type":"null"}]},"session_ttl_minutes":{"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180],"anyOf":[{"type":"integer","minimum":10,"maximum":720},{"type":"null"}]},"max_extra_photos":{"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10],"type":"integer","minimum":0,"maximum":20},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"welcome":{"type":"object","properties":{"title":{"default":null,"description":"Titre de l'écran d'accueil, 120 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}]},"body":{"default":null,"description":"Texte de l'écran d'accueil, 600 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}]}},"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"default":null,"description":"Titre de l'écran de fin, 120 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}]},"body":{"default":null,"description":"Texte de l'écran de fin, 600 caractères au plus, sous forme de chaîne ou d'une chaîne par langue (l'objet doit contenir la `default_locale`) ; `null` pour utiliser le texte propre à la page.","anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}]}},"additionalProperties":false,"description":"L'écran de fin."},"steps":{"maxItems":30,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"default":null,"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."],"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}]},"required":{"default":true,"description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue.","type":"boolean"},"min_photos":{"default":1,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2],"type":"integer","minimum":1,"maximum":20},"max_photos":{"default":1,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6],"type":"integer","minimum":1,"maximum":20},"section":{"default":null,"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}],"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}]},"allowed_skips":{"default":[],"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]],"maxItems":2,"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]}}},"required":["id","label"],"additionalProperties":false},"description":"Les prises de vue à réaliser, dans l'ordre, 30 au plus, chacune avec son propre `id`. Une liste vide signifie : photographier librement."}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","maxLength":80},"example":"tpl_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du modèle (`tpl_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du modèle : la façon de le désigner (`template_id` quand vous créez une session de capture, et dans le chemin des routes ci-dessous). Il ne change jamais.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"type":"string","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"]},"locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles ce modèle a des textes, la langue par défaut comprise. La page de capture peut s'afficher dans chacune d'elles.","examples":[["de","en","fr"]]},"stage":{"description":"Le `stage` pour lequel ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"category":{"description":"La `category` pour laquelle ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"session_ttl_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180]},"max_extra_photos":{"type":"integer","minimum":0,"maximum":20,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10]},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"welcome":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":0,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}],"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2]},"max_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]]}},"required":["id","label","instruction","required","min_photos","max_photos","section","allowed_skips"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"in_use":{"type":"boolean","description":"`true` dès qu'au moins une session de capture a été créée à partir de ce modèle. Un modèle de production utilisé ne peut plus être modifié : dupliquez-le et modifiez la copie."},"archived_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand le modèle a été archivé (ISO 8601, UTC), ou `null` tant qu'il est actif. Un modèle archivé ne démarre plus de session ; les sessions et les preuves déjà faites gardent leur copie."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le modèle a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."}},"required":["id","name","default_locale","locales","stage","category","session_ttl_minutes","max_extra_photos","theme_id","welcome","completion","steps","in_use","archived_at","created_at","updated_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"delete":{"summary":"Archiver un modèle de capture","tags":["Modèles de capture"],"description":"Archive un modèle : il n'est jamais supprimé. Il ne démarre plus de session de capture (`422 template_not_found` pour une nouvelle session qui le désigne), il quitte la liste par défaut, et son libellé ainsi que son `stage` / `category` redeviennent libres. Les sessions de capture et les preuves déjà faites gardent leur copie et fonctionnent toujours. Répéter l'appel ne change rien. Demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":80},"example":"tpl_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du modèle (`tpl_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Réponse par défaut"},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-templates/{id}/duplicate":{"post":{"summary":"Dupliquer un modèle de capture","tags":["Modèles de capture"],"description":"Crée une copie d'un modèle (utilisé ou non, archivé ou non) avec le même contenu et un **nouvel `id`**. La copie ne reprend pas le choix automatique par `stage` et `category` : il appartient à l'original tant qu'il est actif ; archivez donc l'original, puis donnez `stage` et `category` à la copie. C'est ainsi qu'on modifie un modèle de production déjà utilisé. `409 template_name_taken` si le libellé est déjà pris par un modèle actif. Demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Libellé de la copie. Omettez-le pour obtenir le libellé de l'original suivi de `_copy`. Il doit être unique parmi vos modèles actifs.","examples":["pickup_car_v2"],"type":"string","pattern":"^[a-z0-9_.-]{1,64}$"}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","maxLength":80},"example":"tpl_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du modèle (`tpl_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du modèle : la façon de le désigner (`template_id` quand vous créez une session de capture, et dans le chemin des routes ci-dessous). Il ne change jamais.","examples":["tpl_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Libellé du modèle, pour le reconnaître dans une liste. Lettres minuscules, chiffres, `_`, `.` et `-`, 64 caractères au plus. Unique parmi vos modèles actifs ; ce n'est PAS ainsi qu'on désigne le modèle (utilisez son `id`). Vous pouvez le changer tant que le modèle n'a pas servi.","examples":["pickup_car"]},"default_locale":{"type":"string","description":"La langue de vos textes quand un texte est une simple chaîne, et le repli quand une langue manque. Une étiquette BCP 47 : `en`, `fr`, `de`, `pt-BR`… Elle ne peut pas être changée ensuite. `en` si vous l'omettez.","examples":["en"]},"locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles ce modèle a des textes, la langue par défaut comprise. La page de capture peut s'afficher dans chacune d'elles.","examples":[["de","en","fr"]]},"stage":{"description":"Le `stage` pour lequel ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"category":{"description":"La `category` pour laquelle ce modèle est utilisé automatiquement, le cas échéant.","type":["string","null"]},"session_ttl_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Durée de validité d'un lien de capture, en minutes, comptée à partir de la création de la session : de 10 minutes à 12 heures (720). La personne peut fermer la page et revenir jusque-là. `null` : la durée par défaut du serveur (3 heures). Un lien déjà envoyé garde sa propre échéance quand vous modifiez le modèle.","examples":[180]},"max_extra_photos":{"type":"integer","minimum":0,"maximum":20,"description":"Nombre de photos supplémentaires que la personne peut ajouter sans qu'elles correspondent à aucune prise de vue (un dégât que personne n'avait prévu), de 0 à 20. `0` : aucune. `10` si vous l'omettez. Elles sont scellées comme les autres et listées à part des prises de vue du modèle.","examples":[10]},"theme_id":{"description":"Le style de la page de capture que ce modèle utilise : son `id` donné par `GET /v1/capture-themes` (`thm_…`). La page de capture prend l'aspect de ce style (logo, nom, couleur, langue). `null` : le style par défaut de votre organisation. Les styles sont les mêmes en test et en production.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"welcome":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran d'accueil : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":120},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":120}}]},{"type":"null"}],"description":"Titre de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."},"body":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":600},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":600}}]},{"type":"null"}],"description":"Texte de l'écran de fin : une chaîne, ou une chaîne par langue ; `null` pour utiliser le texte propre à la page."}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"anyOf":[{"type":"string","minLength":0,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":80}}],"description":"Nom court de la prise de vue, montré à la personne, 80 caractères au plus. Une chaîne, ou une chaîne par langue comme `{\"en\": \"Front\", \"fr\": \"Face avant\"}` : l'objet doit contenir la `default_locale`.","examples":["Front of the vehicle"]},"instruction":{"anyOf":[{"anyOf":[{"type":"string","minLength":0,"maxLength":300},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":0,"maxLength":300}}]},{"type":"null"}],"description":"Ce qu'il faut faire pour cette prise de vue, montré sous le libellé, 300 caractères au plus. Une chaîne, ou une chaîne par langue, comme `label`.","examples":["Stand back so the whole front is visible."]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre minimal de photos que cette prise de vue demande, de 1 à 20, quand `required` vaut `true` (sans effet sinon). `1` si vous l'omettez.","examples":[2]},"max_photos":{"type":"integer","minimum":1,"maximum":20,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue, de 1 à 20, et au moins `min_photos`. `1` si vous l'omettez : une photo par prise de vue.","examples":[6]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Identifiant de l'étape, stable d'une modification à l'autre.","examples":["kitchen"]},"label":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":80}}],"description":"Nom de l'étape, montré à la personne, 80 caractères au plus : une chaîne, ou une chaîne par langue comme le nom d'une prise de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape à laquelle appartient cette prise de vue, par exemple une pièce ou une zone (`{\"id\": \"kitchen\", \"label\": {\"en\": \"Kitchen\", \"fr\": \"Cuisine\"}}`). Les prises de vue qui ont le même `section.id` doivent se suivre et porter le même `label` : la page les montre ensemble sous le nom de l'étape. `null` : une prise de vue seule, comme avant les étapes.","examples":[{"id":"kitchen","label":"Kitchen"}]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue : `nothing_to_report` (rien à signaler à cet endroit) et/ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Vide (par défaut) : la prise de vue ne peut pas être passée. Une prise de vue passée compte comme faite même si `required` vaut `true`, et la déclaration est gardée avec la preuve.","examples":[["nothing_to_report"]]}},"required":["id","label","instruction","required","min_photos","max_photos","section","allowed_skips"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"in_use":{"type":"boolean","description":"`true` dès qu'au moins une session de capture a été créée à partir de ce modèle. Un modèle de production utilisé ne peut plus être modifié : dupliquez-le et modifiez la copie."},"archived_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand le modèle a été archivé (ISO 8601, UTC), ou `null` tant qu'il est actif. Un modèle archivé ne démarre plus de session ; les sessions et les preuves déjà faites gardent leur copie."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le modèle a été créé (ISO 8601, UTC)."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand il a été modifié pour la dernière fois (ISO 8601, UTC)."}},"required":["id","name","default_locale","locales","stage","category","session_ttl_minutes","max_extra_photos","theme_id","welcome","completion","steps","in_use","archived_at","created_at","updated_at"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-themes":{"post":{"summary":"Créer un style de capture","tags":["Styles de capture"],"description":"Crée un aspect pour la page de capture : un nom, une couleur principale et une langue (le logo s'ajoute avec `PUT /v1/capture-themes/{id}/logo`). Donnez son `id` comme `theme_id` à un modèle de capture pour l'utiliser. Votre premier style devient votre style par défaut ; le nombre de styles n'est pas limité. `409 theme_name_taken` si un autre style actif porte ce nom. Les styles sont les mêmes en test et en production. Cette route demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"locale":{"default":"en","type":"string","enum":["en","fr","es","de"],"description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]}},"required":["name"],"additionalProperties":false}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"get":{"summary":"Lister les styles de capture","tags":["Styles de capture"],"description":"Liste les styles de capture actifs de votre organisation : le style par défaut d'abord, puis par nom. Les styles archivés ne sont pas listés. Cette route demande le droit `manage_templates`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false},"description":"Vos styles de capture : le style par défaut d'abord, puis par nom."}},"required":["data"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-themes/{id}":{"get":{"summary":"Lire un style de capture","tags":["Styles de capture"],"description":"Renvoie un style de capture par son `id`. Cette route demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"patch":{"summary":"Modifier un style de capture","tags":["Styles de capture"],"description":"Change le nom, la couleur principale ou la langue d'un style. Envoyez seulement les champs à changer, au moins un. Les sessions de capture déjà créées gardent l'aspect qu'elles ont reçu. Cette route demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"locale":{"type":"string","enum":["en","fr","es","de"],"description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"delete":{"summary":"Archiver un style de capture","tags":["Styles de capture"],"description":"Archive un style : il n'est plus listé ni sélectionnable, et les sessions de capture déjà créées gardent leur aspect. Le style par défaut ne peut pas être archivé (`409 theme_is_default`), ni un style qu'un modèle de capture utilise (`409 theme_in_use` : donnez d'abord un autre style au modèle). Cette route demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Réponse par défaut"},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-themes/{id}/default":{"post":{"summary":"Définir le style de capture par défaut","tags":["Styles de capture"],"description":"Fait de ce style le style par défaut : la page de capture le prend quand le modèle de la session n'en désigne pas un autre. Cette route demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-themes/{id}/logo":{"put":{"summary":"Définir le logo d'un style de capture","tags":["Styles de capture"],"description":"Définit ou remplace le logo d'un style, affiché en haut de la page de capture. Une image PNG seulement (`data:image/png;base64,…`), 64 Ko au plus, 512 × 512 pixels au plus, sans donnée supplémentaire : sinon `422` avec la raison dans `code` (`logo_invalid`, `logo_too_large`, `logo_too_big_dimensions`…). Cette route demande le droit `manage_templates`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"logo":{"type":"string","minLength":30,"maxLength":90000,"description":"Le logo, sous la forme d'une URL `data:image/png;base64,…`. Une image PNG seulement, 64 Ko au plus et 512 × 512 pixels au plus."}},"required":["logo"],"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"delete":{"summary":"Retirer le logo d'un style de capture","tags":["Styles de capture"],"description":"Retire le logo d'un style : la page de capture n'affiche aucun logo pour lui. Cette route demande le droit `manage_templates`.","parameters":[{"schema":{"type":"string","maxLength":40},"example":"thm_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant du style (`thm_…`)."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du style, à donner dans `theme_id` d'un modèle de capture.","examples":["thm_01m4akapdbe8e8qq3er9r5qwyj"]},"name":{"type":"string","description":"Le nom du style, de 1 à 80 caractères, unique parmi les styles actifs de votre organisation (la casse ne compte pas). La page de capture l'affiche comme le nom de votre marque.","examples":["Gîte du Lac"]},"primary_color":{"type":"string","description":"La couleur principale de la page de capture, `#rrggbb`. Elle doit être assez foncée pour se lire sur la page : une couleur trop claire est refusée avec `422 color_not_readable`.","examples":["#1f6b52"]},"locale":{"type":"string","description":"La langue dans laquelle la page de capture démarre quand la session n'en demande pas une autre : `en`, `fr`, `es` ou `de`.","examples":["fr"]},"has_logo":{"type":"boolean","description":"`true` quand le style a un logo, affiché en haut de la page de capture."},"is_default":{"type":"boolean","description":"`true` pour le style par défaut : celui que la page de capture prend quand le modèle de la session n'en désigne pas un autre."}},"required":["id","name","primary_color","locale","has_logo","is_default"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/settings":{"get":{"summary":"Consulter vos réglages","tags":["Réglages"],"description":"Renvoie les réglages de votre organisation pour le mode de votre clé : les sites vers lesquels une session de capture peut renvoyer la personne, et la langue de votre organisation. Les sites de retour sont séparés entre le test et la production : une clé de test lit et modifie seulement ceux de test ; la langue est la même pour les deux. Demande le droit `manage_settings`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"allowed_return_origins":{"type":"array","items":{"type":"string"},"description":"Les sites vers lesquels une session de capture peut renvoyer la personne une fois la capture terminée (`return_url`), sous forme d'origines : `https://app.example.com`, sans chemin. 20 au plus. `http://localhost` est accepté pour le développement, et seulement avec une clé de bac à sable à la création d'une session. Une liste vide signifie qu'aucune adresse de retour n'est acceptée.","examples":[["https://app.example.com"]]},"locale":{"type":"string","enum":["en","fr"],"description":"La langue de votre organisation : celle des e-mails et de l'espace client des personnes de votre équipe qui n'ont pas choisi la leur. `en` ou `fr` ; toute autre langue vaut l'anglais. Elle est la même en test et en production.","examples":[["fr"]]}},"required":["allowed_return_origins","locale"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}},"patch":{"summary":"Modifier vos réglages","tags":["Réglages"],"description":"Modifie les réglages de votre organisation pour le mode de votre clé (une clé de test ne change que les sites de retour de test, jamais ceux de production ; la langue est commune). Envoyez seulement les champs à changer, au moins un ; une liste envoyée remplace entièrement la précédente. `locale` (`en` ou `fr`) est la langue des e-mails et de l'espace client des personnes de votre équipe qui n'ont pas choisi la leur. `allowed_return_origins` doit contenir des sites (`https://app.example.com`, sans chemin) : une session de capture ne peut renvoyer la personne que vers l'un d'eux. Demande le droit `manage_settings`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allowed_return_origins":{"maxItems":20,"type":"array","items":{"type":"string","maxLength":255},"description":"Les sites vers lesquels une session de capture peut renvoyer la personne une fois la capture terminée (`return_url`), sous forme d'origines : `https://app.example.com`, sans chemin. 20 au plus. `http://localhost` est accepté pour le développement, et seulement avec une clé de bac à sable à la création d'une session. Une liste vide signifie qu'aucune adresse de retour n'est acceptée.","examples":[["https://app.example.com"]]},"locale":{"type":"string","enum":["en","fr"],"description":"La langue de votre organisation : celle des e-mails et de l'espace client des personnes de votre équipe qui n'ont pas choisi la leur. `en` ou `fr` ; toute autre langue vaut l'anglais. Elle est la même en test et en production.","examples":[["fr"]]}},"additionalProperties":false}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"allowed_return_origins":{"type":"array","items":{"type":"string"},"description":"Les sites vers lesquels une session de capture peut renvoyer la personne une fois la capture terminée (`return_url`), sous forme d'origines : `https://app.example.com`, sans chemin. 20 au plus. `http://localhost` est accepté pour le développement, et seulement avec une clé de bac à sable à la création d'une session. Une liste vide signifie qu'aucune adresse de retour n'est acceptée.","examples":[["https://app.example.com"]]},"locale":{"type":"string","enum":["en","fr"],"description":"La langue de votre organisation : celle des e-mails et de l'espace client des personnes de votre équipe qui n'ont pas choisi la leur. `en` ou `fr` ; toute autre langue vaut l'anglais. Elle est la même en test et en production.","examples":[["fr"]]}},"required":["allowed_return_origins","locale"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/credits":{"get":{"summary":"Consulter votre solde","tags":["Crédits"],"description":"Renvoie le solde de votre compte en euros, avec le total ajouté et le total débité. Le solde appartient au compte, pas à un mode : une clé de bac à sable (`sk_test_…`) affiche le même solde, mais seules les preuves scellées en production le débitent. Demande le droit `read_proof`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Solde en euros : tout ce qui a été ajouté moins tout ce qui a été débité. Il peut être négatif : nous ne vous bloquons pas quand il atteint zéro.","examples":[940]},"granted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total ajouté à votre compte, en euros.","examples":[1000]},"consumed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total débité, en euros (un nombre positif) : le prix de chaque preuve scellée en production.","examples":[60]}},"required":["balance","granted","consumed"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/credits/transactions":{"get":{"summary":"Lister les mouvements du solde","tags":["Crédits"],"description":"Liste les fonds ajoutés à votre compte et les débits, en euros, avec une pagination par curseur. Filtrez par `type` ; triez avec `sort`. Chaque consommation renvoie à la preuve qui l'a causée. Un curseur modifié, ou issu de l'autre sens de tri, échoue avec `422 invalid_cursor`. Demande le droit `read_proof`.","parameters":[{"schema":{"default":50,"type":"integer","minimum":1,"maximum":100},"example":20,"in":"query","name":"limit","required":false,"description":"Combien de mouvements renvoyer, de 1 à 100."},{"schema":{"type":"string","maxLength":300},"in":"query","name":"cursor","required":false,"description":"Le `next_cursor` de la page précédente. Opaque : ne le construisez pas et ne le modifiez pas."},{"schema":{"type":"string","enum":["grant","consumption"]},"example":"consumption","in":"query","name":"type","required":false,"description":"Seulement les mouvements de ce type."},{"schema":{"default":"-created_at","type":"string","enum":["created_at","-created_at"]},"in":"query","name":"sort","required":false,"description":"Tri par date : `created_at` du plus ancien au plus récent, `-created_at` du plus récent au plus ancien."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant du mouvement.","examples":["cre_01m4akapdbe8e8qq3er9r5qwyj"]},"type":{"type":"string","enum":["grant","consumption"],"description":"`grant` : fonds ajoutés. `consumption` : un débit.","examples":["consumption"]},"amount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Montant de ce mouvement, en euros : positif pour un `grant`, négatif pour un `consumption`.","examples":[-1]},"reason":{"type":"string","description":"Pourquoi. Pour un `grant` : `purchase`, `gift` ou `adjustment`. Pour un `consumption` : ce qui a été utilisé, par exemple `proof_sealed`, ou `refund` / `dispute` quand des crédits ont été repris après un remboursement ou un litige de paiement.","examples":["proof_sealed"]},"proof_id":{"description":"La preuve qui a causé le débit, pour un `consumption` ; `null` sinon.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"],"type":["string","null"]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le mouvement a été enregistré (ISO 8601, UTC)."}},"required":["id","type","amount","reason","proof_id","created_at"],"additionalProperties":false},"description":"Les mouvements de cette page."},"has_more":{"type":"boolean","description":"`true` quand une autre page existe."},"next_cursor":{"description":"Renvoyez-le comme `cursor` pour obtenir la page suivante ; `null` sur la dernière page.","type":["string","null"]}},"required":["data","has_more","next_cursor"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/me":{"get":{"summary":"Vérifier votre clé d'API","tags":["Compte"],"description":"Renvoie l'organisation, le mode et les droits de la clé utilisée pour l'appel. Un moyen rapide de vérifier qu'une clé fonctionne.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"organization_id":{"type":"string","description":"Identifiant de l'organisation à laquelle la clé appartient.","examples":["org_01m4akapdbe8e8qq3er9r5qwyj"]},"mode":{"type":"string","enum":["live","test"],"description":"Mode de la clé.","examples":["test"]},"key":{"type":"object","properties":{"prefix":{"type":"string","description":"Les premiers caractères de la clé, pour la reconnaître. Jamais suffisants pour l'utiliser.","examples":["sk_test_AbCd"]},"label":{"description":"Le nom donné à la clé, s'il y en a un.","type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"},"description":"Ce que la clé peut faire : `create_proof`, `read_proof`, `manage_webhooks`, `manage_templates`.","examples":[["create_proof","read_proof"]]}},"required":["prefix","label","scopes"],"additionalProperties":false,"description":"La clé que vous utilisez."}},"required":["organization_id","mode","key"],"additionalProperties":false}}}},"401":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-sessions/{token}/uploads":{"post":{"summary":"Demander des liens d'envoi","tags":["Page de capture"],"description":"Déclare les fichiers sur le point d'être envoyés et renvoie, pour chacun, un lien temporaire pour l'envoyer **directement** (un seul `PUT` pour une photo, un `PUT` par partie pour une vidéo). Les fichiers ne passent jamais par l'API. Le jeton présent dans l'URL fait office d'identification. Refusé avec `413 file_too_large` si un fichier dépasse la limite, et avec `422` pour un type non accepté ou trop de fichiers.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"media_type":{"type":"string","enum":["photo","video"],"description":"Type de fichier.","examples":["photo"]},"mime_type":{"type":"string","minLength":1,"maxLength":100,"description":"Type du fichier. Il doit figurer parmi les types listés dans `constraints` de la session de capture, et il est contrôlé sur le fichier lui-même.","examples":["image/jpeg"]},"size_bytes":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Taille exacte du fichier en octets. Un fichier dont la taille diffère de cette déclaration est rejeté lors du traitement de la preuve.","examples":[183422]},"label":{"type":"string","pattern":"^[a-z0-9_.-]{1,64}$","description":"Un identifiant court pour la prise de vue (`front`, `rear_left`…). Lettres minuscules, chiffres, `_`, `.` et `-`.","examples":["front"]}},"required":["media_type","mime_type","size_bytes"],"additionalProperties":false},"description":"Les fichiers que vous allez envoyer, de 1 à 100."}},"required":["files"],"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string"},"example":"3f9aXq…","in":"path","name":"token","required":true,"description":"Le jeton de session : la dernière partie de `capture_url`."}],"responses":{"201":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"uploads":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"upload_id":{"type":"string","description":"Identifiant de cet envoi. Renvoyez-le au moment de finaliser.","examples":["upl_01m4akapdbe8e8qq3er9r5qwyj"]},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le lien d'envoi cesse de fonctionner (ISO 8601, UTC)."},"method":{"type":"string","description":"Envoyez le fichier entier dans une seule requête `PUT`. Utilisé pour les photos.","enum":["PUT"]},"url":{"type":"string","description":"Où envoyer le fichier. Le lien porte sa propre autorisation : n'ajoutez pas d'en-tête `Authorization`."},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"En-têtes à envoyer avec le `PUT`, exactement tels que donnés (le `Content-Type` fait partie de la signature).","examples":[{"Content-Type":"image/jpeg"}]}},"required":["upload_id","expires_at","method","url","headers"],"additionalProperties":false},{"type":"object","properties":{"upload_id":{"type":"string","description":"Identifiant de cet envoi. Renvoyez-le au moment de finaliser.","examples":["upl_01m4akapdbe8e8qq3er9r5qwyj"]},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le lien d'envoi cesse de fonctionner (ISO 8601, UTC)."},"method":{"type":"string","description":"Envoyez le fichier en parties, chacune avec un `PUT`. Utilisé pour les vidéos.","enum":["MULTIPART"]},"part_size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille de chaque partie en octets, sauf la dernière qui peut être plus petite."},"parts":{"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Numéro de la partie, à partir de 1."},"url":{"type":"string","description":"Où envoyer cette partie par `PUT`. Gardez l'en-tête `ETag` de la réponse : il vous faut pour finaliser."}},"required":["part_number","url"],"additionalProperties":false},"description":"Un lien par partie."}},"required":["upload_id","expires_at","method","part_size_bytes","parts"],"additionalProperties":false}]},"description":"Une entrée par fichier, dans l'ordre où vous les avez déclarés."}},"required":["uploads"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"410":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"413":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-sessions/{token}/uploads/{upload_id}":{"delete":{"summary":"Retirer un envoi","tags":["Page de capture"],"description":"Retire un envoi encore ouvert de cette session, par exemple quand la personne reprend une photo : le fichier est effacé tout de suite, il ne compte plus dans la limite de fichiers et ne pourra plus être finalisé. L'`upload_id` est celui reçu quand vous avez demandé les liens d'envoi. `404 upload_not_found` pour toute autre valeur (inconnu, déjà finalisé, ou d'une autre session).","parameters":[{"schema":{"type":"string"},"example":"3f9aXq…","in":"path","name":"token","required":true,"description":"Le jeton de session : la dernière partie de `capture_url`."},{"schema":{"type":"string"},"example":"upl_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"upload_id","required":true,"description":"L'identifiant de l'envoi, tel que reçu quand vous avez demandé les liens d'envoi."}],"responses":{"204":{"description":"Réponse par défaut"},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"410":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-sessions/{token}/finalize":{"post":{"summary":"Finaliser une capture","tags":["Page de capture"],"description":"À appeler une fois que chaque fichier a été envoyé. Il vérifie que les fichiers sont dans le stockage et crée la preuve, qui démarre à `pending` ; nous vérifions ensuite les fichiers, les signons et obtenons un horodatage pour la preuve. La réponse est `202` : le scellement a lieu juste après, en général en quelques secondes, et est annoncé par le webhook `proof.sealed`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"upload_id":{"type":"string","maxLength":40,"description":"L'`upload_id` que vous avez reçu pour ce fichier.","examples":["upl_01m4akapdbe8e8qq3er9r5qwyj"]},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"SHA-256 du fichier, en 64 caractères hexadécimaux minuscules. C'est un contrôle de transfert : nous le recalculons à partir du fichier stocké et ne nous fions jamais à cette seule valeur.","examples":["8061db5cea33116b0b1210a18998d1005efc128ac2d93a33000a8b0cdddd7145"]},"size_bytes":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Taille exacte du fichier en octets, telle que déclarée lors de la demande d'envoi.","examples":[183422]},"parts":{"maxItems":10000,"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","minimum":1,"maximum":10000,"description":"Numéro de la partie, à partir de 1."},"etag":{"type":"string","minLength":1,"maxLength":200,"description":"L'en-tête `ETag` renvoyé quand cette partie a été envoyée."}},"required":["part_number","etag"],"additionalProperties":false},"description":"Obligatoire pour une vidéo envoyée en parties : chaque partie avec son `ETag`. À omettre pour une photo."}},"required":["upload_id","sha256","size_bytes"],"additionalProperties":false},"description":"Chaque fichier de la capture, une fois envoyé."},"skipped":{"default":[],"description":"Les prises de vue que la personne déclare au lieu de les photographier. Une prise de vue passée compte comme faite même si elle est obligatoire, n'a aucune photo et est gardée avec la preuve (`skipped` sur la preuve). `422 skip_not_allowed` quand le modèle ne l'autorise pas.","maxItems":30,"type":"array","items":{"type":"object","properties":{"step_id":{"type":"string","maxLength":64,"description":"L'`id` de la prise de vue du modèle qui reste sans photos.","examples":["garden"]},"reason":{"type":"string","enum":["nothing_to_report","not_applicable"],"description":"Pourquoi : `nothing_to_report` (rien à signaler à cet endroit) ou `not_applicable` (la prise de vue ne s'applique pas à cet objet). Le modèle doit l'autoriser pour cette prise de vue (`allowed_skips`).","examples":["nothing_to_report"]}},"required":["step_id","reason"],"additionalProperties":false}}},"required":["files"],"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string"},"example":"3f9aXq…","in":"path","name":"token","required":true,"description":"Le jeton de session : la dernière partie de `capture_url`."}],"responses":{"202":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"proof_id":{"type":"string","description":"Identifiant de la preuve en cours de création. Lisez-la avec `GET /v1/proofs/{id}`.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"status":{"type":"string","enum":["pending","processing","sealed","failed"],"description":"Statut de la preuve : `pending` juste après la finalisation. Le scellement prend un peu de temps et il est annoncé par le webhook `proof.sealed`.","examples":["pending"]}},"required":["proof_id","status"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"410":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"503":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-sessions/{token}/before":{"get":{"summary":"Lire les photos « avant » d'une capture","tags":["Page de capture"],"description":"Utilisé par la page de capture quand la session complète une preuve existante (`compare_to`) : renvoie des liens temporaires vers les photos de cet « avant », pour que la personne puisse refaire les mêmes. Seulement les photos, jamais la référence ni aucune autre donnée de l'« avant ». Le jeton dans l'URL fait office d'identification. `404 no_before_photos` pour une session ordinaire, `410` une fois expirée, `409` une fois utilisée, `403 organization_suspended` quand l'organisation est suspendue ou fermée.","parameters":[{"schema":{"type":"string"},"example":"3f9aXq…","in":"path","name":"token","required":true,"description":"Le jeton de session : la dernière partie de `capture_url`."}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"photos":{"type":"array","items":{"type":"object","properties":{"step_id":{"description":"L'`id` de la prise de vue du modèle à laquelle cette photo répond (`other` : une photo hors modèle) ; `null` si la photo n'avait pas de prise de vue.","examples":["front"],"type":["string","null"]},"url":{"type":"string","description":"Un lien temporaire vers la photo de l'« avant », à montrer à côté de l'appareil photo pour que la personne refasse la même. Il cesse de fonctionner à `expires_at`.","examples":["https://storage.example.com/signed/…?X-Amz-Signature=…"]},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand le lien cesse de fonctionner (ISO 8601, UTC)."}},"required":["step_id","url","expires_at"],"additionalProperties":false},"description":"Les photos de l'« avant », dans l'ordre où elles ont été prises."}},"required":["photos"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"410":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/public/proofs/{id}":{"get":{"summary":"Lire le statut public d'une preuve","tags":["Vérification publique"],"description":"Public, sans clé d'API, limité par adresse IP. Renvoie le statut d'une preuve et son horodatage, pour que quiconque détient l'identifiant puisse la vérifier. Jamais les fichiers, jamais le nom de l'organisation, jamais la référence externe.","parameters":[{"schema":{"type":"string"},"example":"prf_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de la preuve."}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la preuve.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"status":{"type":"string","enum":["pending","processing","sealed","failed"],"description":"Mêmes significations que sur `GET /v1/proofs/{id}`.","examples":["sealed"]},"mode":{"type":"string","enum":["live","test"],"description":"`test` : l'horodatage est simulé et n'a aucune valeur juridique.","examples":["test"]},"sealed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"Quand la preuve a été scellée (ISO 8601, UTC) ; `null` jusque-là."},"timestamp":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["direct","merkle_batch"],"description":"`direct` : la preuve a son propre jeton d'horodatage. `merkle_batch` : le jeton certifie un lot de preuves, avec un chemin de Merkle pour chacune.","examples":["direct"]},"authority":{"type":"string","description":"Qui a émis l'horodatage (`simulated` en mode test)."},"qualified":{"type":"boolean","description":"Indique si l'horodatage est un horodatage qualifié au sens d'eIDAS. Toujours `false` pour un horodatage simulé."},"gen_time":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"L'heure certifiée par l'autorité : la preuve existait au plus tard à cette heure (ISO 8601, UTC). Avec `qualified: true`, c'est un horodatage qualifié eIDAS, à la seconde. Ce n'est pas l'heure de la capture."},"serial":{"description":"Numéro de série du jeton d'horodatage.","type":["string","null"]}},"required":["mode","authority","qualified","gen_time","serial"],"additionalProperties":false},{"type":"null"}],"description":"L'horodatage de la preuve ; `null` tant que la preuve n'est pas scellée."}},"required":["id","status","mode","sealed_at","timestamp"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/public/proofs/{id}/bundle":{"get":{"summary":"Obtenir le paquet de vérification d'une preuve","tags":["Vérification publique"],"description":"Public, sans clé d'API. Renvoie tout ce dont un logiciel indépendant a besoin pour vérifier une preuve **scellée** sans nous faire confiance : les empreintes, la preuve de Merkle et le jeton d'horodatage (RFC 3161, en base64). Pour une preuve qui existe mais n'est pas encore scellée : `409 proof_not_sealed`.","parameters":[{"schema":{"type":"string"},"example":"prf_01m4akapdbe8e8qq3er9r5qwyj","in":"path","name":"id","required":true,"description":"Identifiant de la preuve."}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"number","description":"Version du format du paquet.","enum":[1]},"proof_id":{"type":"string","description":"Identifiant de la preuve."},"organization_id":{"type":"string","description":"Identifiant de l'organisation qui a créé la preuve."},"mode":{"type":"string","enum":["live","test"],"description":"Mode de la preuve."},"external_reference_commitment":{"type":"string","description":"Un engagement cryptographique sur la référence externe. La référence elle-même n'est jamais publique ; avec la référence et le sel qui vous ont été remis, n'importe qui peut vérifier qu'elle correspond."},"declared_by_platform":{"type":"object","properties":{"party":{"type":"string","enum":["provider","recipient"],"description":"Qui la plateforme a déclaré comme capturant."},"stage":{"description":"L'étape déclarée par la plateforme.","type":["string","null"]}},"required":["party","stage"],"additionalProperties":false,"description":"Ce que la plateforme a déclaré. C'est présenté comme déclaré, jamais comme vérifié."},"capture":{"type":"object","properties":{"method":{"type":"string","enum":["hosted_live","direct_upload"],"description":"Comment les fichiers ont été capturés : sur la page de capture hébergée, ou envoyés directement."},"session_id":{"description":"La session de capture, s'il y en a eu une.","type":["string","null"]}},"required":["method","session_id"],"additionalProperties":false,"description":"Comment la capture s'est déroulée."},"generator":{"type":"object","properties":{"name":{"type":"string","description":"Nom du logiciel qui a produit la preuve."},"version":{"type":"string","description":"Sa version."}},"required":["name","version"],"additionalProperties":false,"description":"Le logiciel qui a produit la preuve, et sa version."},"media":{"type":"array","items":{"type":"object","properties":{"media_type":{"type":"string","enum":["photo","video"],"description":"Type de fichier."},"mime_type":{"type":"string","description":"Type du fichier.","examples":["image/jpeg"]},"byte_size":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille du fichier original en octets."},"captured_at":{"type":"string","description":"Quand notre service a observé le fichier (ISO 8601, UTC). Ce n'est pas un horodatage qualifié."},"original_sha256":{"type":"string","description":"SHA-256 du fichier original. Comparez-le avec le fichier que vous détenez."},"signed_sha256":{"type":"string","description":"SHA-256 de la copie signée (C2PA)."},"manifest_id":{"type":"string","description":"Identifiant du manifeste C2PA intégré à la copie signée."},"key_version":{"type":"string","description":"Version de la clé de signature qui a signé la copie."}},"required":["media_type","mime_type","byte_size","captured_at","original_sha256","signed_sha256","manifest_id","key_version"],"additionalProperties":false},"description":"Les fichiers de la preuve, dans l'ordre."},"manifest_sha256":{"type":"string","description":"Empreinte du manifeste qui décrit la preuve. En mode `direct`, le jeton d'horodatage certifie cette valeur ; en mode `merkle_batch`, c'est la feuille de l'arbre de Merkle."},"timestamp":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","description":"Toujours `direct` : la preuve a son propre jeton d'horodatage.","enum":["direct"]},"tsr_base64":{"type":"string","description":"Le jeton d'horodatage RFC 3161, en base64. Il certifie `manifest_sha256` lui-même : vérifiez-le avec `openssl ts -verify -digest <manifest_sha256> -in token.tsr -CAfile chain.pem`."},"authority":{"type":"string","description":"Qui a émis l'horodatage (`simulated` en mode test)."},"qualified":{"type":"boolean","description":"Déclaré par le service. Un vérificateur le recalcule et ne se fie jamais à ce champ."},"gen_time":{"type":"string","description":"L'heure certifiée par l'autorité (ISO 8601, UTC) : la preuve existait au plus tard à cette heure."},"serial":{"type":"string","description":"Numéro de série du jeton d'horodatage."},"policy_oid":{"description":"Identifiant de la politique de l'autorité d'horodatage, s'il est fourni.","type":["string","null"]}},"required":["mode","tsr_base64","authority","qualified","gen_time","serial","policy_oid"],"additionalProperties":false},{"type":"null"}],"description":"L'horodatage de la preuve, en mode `direct` (par défaut). `null` pour une preuve horodatée dans un lot (voir `batch`) et tant que la preuve n'est pas scellée. Une fois la preuve scellée, exactement un des deux, `timestamp` ou `batch`, est renseigné."},"batch":{"anyOf":[{"type":"object","properties":{"merkle_root":{"type":"string","description":"Racine de l'arbre de Merkle du lot. Le jeton d'horodatage certifie cette valeur."},"leaf_index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Position de cette preuve parmi les feuilles de l'arbre."},"merkle_path":{"type":"array","items":{"type":"object","properties":{"hash":{"type":"string","description":"Empreinte du nœud voisin dans l'arbre de Merkle."},"position":{"type":"string","enum":["left","right"],"description":"Côté sur lequel cette empreinte est combinée à la vôtre."}},"required":["hash","position"],"additionalProperties":false},"description":"Les empreintes à combiner, de la feuille jusqu'à la racine, pour prouver que cette preuve appartient au lot."},"tsr_base64":{"type":"string","description":"Le jeton d'horodatage RFC 3161, en base64."},"authority":{"type":"string","description":"Qui a émis l'horodatage (`simulated` en mode test)."},"qualified":{"type":"boolean","description":"Déclaré par le service. Un vérificateur le recalcule et ne se fie jamais à ce champ."},"gen_time":{"type":"string","description":"L'heure certifiée par l'autorité (ISO 8601, UTC)."},"serial":{"type":"string","description":"Numéro de série du jeton d'horodatage."},"policy_oid":{"description":"Identifiant de la politique de l'autorité d'horodatage, s'il est fourni.","type":["string","null"]}},"required":["merkle_root","leaf_index","merkle_path","tsr_base64","authority","qualified","gen_time","serial","policy_oid"],"additionalProperties":false},{"type":"null"}],"description":"L'horodatage d'une preuve horodatée dans un lot (mode `merkle_batch`, désactivé par défaut) : le jeton du lot et le chemin de Merkle de cette preuve jusqu'à sa racine. `null` en mode `direct`."}},"required":["version","proof_id","organization_id","mode","external_reference_commitment","declared_by_platform","capture","generator","media","manifest_sha256","timestamp","batch"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"503":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}},"/v1/capture-sessions/{token}":{"get":{"summary":"Lire une session de capture","tags":["Page de capture"],"description":"Utilisée par la page de capture : renvoie ce dont elle a besoin pour fonctionner (qui capture, l'apparence de la page, les textes du modèle dans la langue de la personne, les types et tailles de fichiers acceptés). Le jeton de l'URL fait office d'identification, aucune clé d'API n'est nécessaire. Échoue avec `404` pour un jeton inconnu, `410` une fois expirée, `409` une fois la session utilisée et `403 organization_suspended` une fois l'organisation suspendue ou fermée.","parameters":[{"schema":{"type":"string","maxLength":35,"pattern":"^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$"},"example":"es","in":"query","name":"locale","required":false,"description":"Affiche les textes du modèle dans cette langue plutôt que celle choisie à la création de la session, par exemple quand la personne change de langue sur la page. Un texte qui n'existe pas dans cette langue se replie sur la langue de base (`pt` pour `pt-BR`), puis sur la langue par défaut du modèle, puis sur l'anglais."},{"schema":{"type":"string"},"example":"3f9aXq…","in":"path","name":"token","required":true,"description":"Le jeton de session : la dernière partie de `capture_url`."}],"responses":{"200":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la session de capture.","examples":["cps_01m4akapdbe8e8qq3er9r5qwyj"]},"status":{"type":"string","description":"Toujours `pending` : une session expirée ou déjà utilisée est refusée avec une erreur.","enum":["pending"]},"mode":{"type":"string","enum":["live","test"],"description":"Mode de la clé qui a créé la session.","examples":["test"]},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Quand la session cesse de fonctionner (ISO 8601, UTC)."},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui capture.","examples":["provider"]},"stage":{"description":"Le moment de la transaction déclaré à la création de la session, s'il y en a un.","examples":["pickup"],"type":["string","null"]},"theme":{"type":"object","properties":{"name":{"type":"string","description":"Nom à afficher sur la page de capture."},"logo_url":{"description":"Logo à afficher, si l'organisation en a un.","type":["string","null"]},"primary_color":{"type":"string","description":"Couleur principale de la page, en code hexadécimal.","examples":["#1F6B52"]},"locale":{"type":"string","description":"Langue de la page.","examples":["en"]}},"required":["name","logo_url","primary_color","locale"],"additionalProperties":false,"description":"L'apparence de la page de capture. Elle n'inclut jamais la référence externe ni l'organisation."},"has_before":{"type":"boolean","description":"`true` quand cette capture complète une preuve existante (`compare_to`) : la page lit alors les photos de cet « avant » avec `GET /v1/capture-sessions/{token}/before` pour les montrer à la personne. `false` pour une capture ordinaire."},"return_url":{"description":"Où ramener la personne une fois la capture terminée, tel que choisi à la création de la session, ou `null`. La page y ajoute `proof_id` et `session_id`.","examples":["https://app.example.com/bookings/4471/capture-done"],"type":["string","null"]},"locale":{"type":"string","description":"La langue dans laquelle la page et les textes du modèle s'affichent : celle demandée dans l'appel, sinon celle choisie à la création de la session, sinon celle du thème.","examples":["de"]},"available_locales":{"type":"array","items":{"type":"string"},"description":"Les langues pour lesquelles le modèle a des textes, pour que la page puisse proposer un changement de langue. Vide quand aucun modèle ne s'applique.","examples":[["de","en","fr"]]},"template":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","description":"Nom du modèle qui s'applique à cette session.","examples":["pickup_car"]},"welcome":{"type":"object","properties":{"title":{"description":"Titre de l'écran d'accueil, ou `null` pour garder le texte de la page.","type":["string","null"]},"body":{"description":"Texte de l'écran d'accueil, ou `null` pour garder le texte de la page.","type":["string","null"]}},"required":["title","body"],"additionalProperties":false,"description":"L'écran d'accueil."},"completion":{"type":"object","properties":{"title":{"description":"Titre de l'écran de fin, ou `null` pour garder le texte de la page.","type":["string","null"]},"body":{"description":"Texte de l'écran de fin, ou `null` pour garder le texte de la page.","type":["string","null"]}},"required":["title","body"],"additionalProperties":false,"description":"L'écran de fin."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de la prise de vue, stable d'une modification à l'autre.","examples":["front"]},"label":{"type":"string","description":"Nom court de la prise de vue, montré à la personne.","examples":["Front of the vehicle"]},"instruction":{"description":"Ce qu'il faut faire pour cette prise de vue, affiché sous le nom, si le modèle en donne une.","examples":["Stand back so the whole front is visible."],"type":["string","null"]},"required":{"type":"boolean","description":"`true` quand la capture ne peut pas se terminer sans cette prise de vue."},"min_photos":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre minimal de photos que cette prise de vue demande quand `required` vaut `true` (sans effet sinon).","examples":[2]},"max_photos":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre maximal de photos que la personne peut prendre pour cette prise de vue.","examples":[6]},"allowed_skips":{"type":"array","items":{"type":"string","enum":["nothing_to_report","not_applicable"]},"description":"Ce que la personne peut déclarer au lieu de photographier cette prise de vue (`nothing_to_report`, `not_applicable`) ; vide : la prise de vue ne peut pas être passée.","examples":[["nothing_to_report"]]},"section":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Identifiant de l'étape.","examples":["kitchen"]},"label":{"type":"string","description":"Nom de l'étape, montré au-dessus de ses prises de vue.","examples":["Kitchen"]}},"required":["id","label"],"additionalProperties":false},{"type":"null"}],"description":"L'étape (une pièce, une zone) à laquelle appartient cette prise de vue ; les prises de vue consécutives qui ont le même `section.id` sont montrées ensemble sous son nom. `null` : une prise de vue seule."}},"required":["id","label","instruction","required","min_photos","max_photos","allowed_skips","section"],"additionalProperties":false},"description":"Les prises de vue à faire, dans l'ordre. Une liste vide signifie : prenez librement des photos."},"max_extra_photos":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Nombre de photos supplémentaires, ne correspondant à aucune prise de vue, que la personne peut ajouter. `0` : aucune.","examples":[10]}},"required":["name","welcome","completion","steps","max_extra_photos"],"additionalProperties":false,"description":"Ce que la page demande à la personne. Une copie est faite à la création de la session : modifier le modèle ensuite ne change pas un lien déjà envoyé."},{"type":"null"}],"description":"Le modèle de capture qui s'applique, ou `null` s'il n'y en a aucun : la page montre alors ses écrans par défaut."},"constraints":{"type":"object","properties":{"photo":{"type":"object","properties":{"mime_types":{"type":"array","items":{"type":"string"},"description":"Types de fichiers acceptés pour une photo."},"max_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille maximale acceptée d'une photo, en octets."}},"required":["mime_types","max_bytes"],"additionalProperties":false,"description":"Ce que la page peut envoyer comme photo."},"video":{"type":"object","properties":{"mime_types":{"type":"array","items":{"type":"string"},"description":"Types de fichiers acceptés pour une vidéo."},"max_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Taille maximale acceptée d'une vidéo, en octets."}},"required":["mime_types","max_bytes"],"additionalProperties":false,"description":"Ce que la page peut envoyer comme vidéo."}},"required":["photo","video"],"additionalProperties":false,"description":"Ce que la page peut envoyer. Tout le reste est refusé."}},"required":["id","status","mode","expires_at","party","stage","theme","has_before","return_url","locale","available_locales","template","constraints"],"additionalProperties":false}}}},"403":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"404":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"409":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"410":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"422":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}},"429":{"description":"Réponse par défaut","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"field":{"type":"string"}},"required":["type","title","status","code"],"additionalProperties":false}}}}}}}},"servers":[{"url":"https://api.tryvidimus.com","description":"L'API. La clé que vous utilisez fixe le mode : sk_test_… pour le bac à sable, sk_live_… pour la production."}],"tags":[{"name":"Sessions de capture","description":"Commencez ici. Une session de capture est un lien à usage unique permettant à une personne de prendre les photos ou les vidéos d'une transaction."},{"name":"Modèles de capture","description":"Définissez ce que demande la page de capture : les prises de vue à réaliser et les textes d'accueil et de fin. Demande le droit `manage_templates`."},{"name":"Styles de capture","description":"Définissez l'aspect de la page de capture : un nom, une couleur principale, une langue et un logo. Vous pouvez avoir plusieurs styles (un par marque, par exemple) et en choisir un par modèle de capture avec `theme_id`. Demande le droit `manage_templates`."},{"name":"Page de capture","description":"Routes utilisées par la page de capture elle-même, sur le téléphone de la personne qui capture. Elles utilisent le jeton de session présent dans l'URL de capture à la place d'une clé d'API. Vous n'en avez besoin que si vous construisez votre propre page de capture."},{"name":"Preuves","description":"Lisez les preuves de votre organisation : statut, fichiers, et un lien temporaire vers la copie signée."},{"name":"Endpoints de webhook","description":"Soyez prévenu dès qu'une preuve est scellée ou échoue. Demande le droit `manage_webhooks`."},{"name":"Événements de webhook","description":"Les messages que nous envoyons à vos endpoints de webhook, une entrée par événement, avec le corps JSON exact et les en-têtes de chaque message. Vous ne les appelez pas : vous les recevez."},{"name":"Crédits","description":"Consultez votre solde en euros et ce qui l'a débité. Demande le droit `read_proof`."},{"name":"Réglages","description":"Réglages de votre organisation : les sites vers lesquels une session de capture peut renvoyer la personne, et la langue de votre organisation. Demande le droit `manage_settings`."},{"name":"Vérification publique","description":"Tout le monde peut vérifier une preuve sans compte ni clé d'API : son statut, et le paquet de vérification qu'un logiciel indépendant peut contrôler hors ligne."},{"name":"Compte","description":"Vérifiez quelle clé vous utilisez : son organisation, son mode et ses droits."},{"name":"État du service","description":"Vérifiez que l'API fonctionne et quelle version tourne."}],"webhooks":{"proof.sealed":{"post":{"summary":"Une preuve est scellée","description":"Envoyé quand une preuve est scellée : ses fichiers sont signés (C2PA) et horodatés (RFC 3161). La preuve peut alors être lue avec `GET /v1/proofs/{id}` et vérifiée par n'importe qui. Il suit `capture_session.completed` de la même capture, en général de quelques secondes.","tags":["Événements de webhook"],"parameters":[{"name":"X-Signature","in":"header","required":true,"description":"La signature du message : `t=<unix seconds>,v1=<signature>` (un `v1` par secret actif). La signature est le HMAC-SHA256, en hexadécimal minuscule, de l'horodatage `t`, d'un point et du corps brut, calculé avec le secret de votre endpoint (la chaîne entière, `whsec_` compris). Comparez-la à chaque valeur `v1`, et rejetez l'appel si `t` date de plus de 5 minutes. Voir la section Webhooks de l'introduction pour un exemple complet.","schema":{"type":"string","examples":["t=1791906492,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"]}},{"name":"X-Webhook-Id","in":"header","required":true,"description":"Identifiant de cette tentative d'envoi (`whd_…`). C'est celui que vous trouvez dans `GET /v1/webhook-deliveries`.","schema":{"type":"string","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]}},{"name":"X-Event-Id","in":"header","required":true,"description":"Identifiant de l'événement (`evt_…`). Il est **identique à chaque nouvelle tentative** du même événement : servez-vous-en pour ignorer les doublons.","schema":{"type":"string","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","const":"proof.sealed","description":"Toujours `proof.sealed` : la preuve est scellée (signée et horodatée).","examples":["proof.sealed"]},"proof_id":{"type":"string","description":"Identifiant de la preuve (`prf_…`). Lisez-la avec `GET /v1/proofs/{id}`.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"external_reference":{"type":"string","description":"La référence que votre plateforme a donnée en créant la session de capture (`external_reference`), renvoyée telle quelle.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos : le `party` donné à la création de la session de capture.","examples":["provider"]},"stage":{"description":"Le `stage` donné à la création de la session de capture (`pickup`, `return`…), ou `null` s'il n'y en avait pas.","examples":["pickup"],"type":["string","null"]},"status":{"type":"string","const":"sealed","description":"Toujours `sealed`.","examples":["sealed"]},"sealed_at":{"type":"string","description":"Quand la preuve a été scellée, en ISO 8601 UTC.","examples":["2026-10-13T15:48:12.000Z"]},"verify_url":{"description":"Page publique où n'importe qui peut vérifier la preuve, sans compte. Toujours présente sur le service hébergé.","examples":["https://verify.tryvidimus.com/prf_01m4akapdbe8e8qq3er9r5qwyj"],"type":"string"},"test":{"description":"Présent, et `true`, seulement sur un événement de test envoyé avec `POST /v1/webhook-endpoints/{id}/test`. Les vrais événements n'ont jamais ce champ.","examples":[true],"type":"boolean"}},"required":["event","proof_id","external_reference","party","stage","status","sealed_at"],"additionalProperties":false}}}},"responses":{"2XX":{"description":"Un statut `2xx` accuse réception du message. Le corps de votre réponse est ignoré, mais son début (4096 caractères au plus) est conservé pour que vous puissiez le lire dans votre compte et avec `GET /v1/webhook-deliveries/{id}`."},"default":{"description":"Tout le reste (un autre statut, une redirection (nous n'en suivons jamais), aucune réponse sous 10 secondes, une erreur de connexion ou de certificat) est un échec : nous réessayons après 1 minute, 5 minutes, 30 minutes, 2 heures et 12 heures, puis nous abandonnons (`abandoned`)."}}}},"proof.failed":{"post":{"summary":"Une preuve n'a pas pu être scellée","description":"Envoyé quand une preuve n'a pas pu être scellée. Regardez `retriable` pour savoir si l'échec peut être relancé ou s'il est définitif.","tags":["Événements de webhook"],"parameters":[{"name":"X-Signature","in":"header","required":true,"description":"La signature du message : `t=<unix seconds>,v1=<signature>` (un `v1` par secret actif). La signature est le HMAC-SHA256, en hexadécimal minuscule, de l'horodatage `t`, d'un point et du corps brut, calculé avec le secret de votre endpoint (la chaîne entière, `whsec_` compris). Comparez-la à chaque valeur `v1`, et rejetez l'appel si `t` date de plus de 5 minutes. Voir la section Webhooks de l'introduction pour un exemple complet.","schema":{"type":"string","examples":["t=1791906492,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"]}},{"name":"X-Webhook-Id","in":"header","required":true,"description":"Identifiant de cette tentative d'envoi (`whd_…`). C'est celui que vous trouvez dans `GET /v1/webhook-deliveries`.","schema":{"type":"string","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]}},{"name":"X-Event-Id","in":"header","required":true,"description":"Identifiant de l'événement (`evt_…`). Il est **identique à chaque nouvelle tentative** du même événement : servez-vous-en pour ignorer les doublons.","schema":{"type":"string","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","const":"proof.failed","description":"Toujours `proof.failed` : la preuve n'a pas pu être scellée.","examples":["proof.failed"]},"proof_id":{"type":"string","description":"Identifiant de la preuve (`prf_…`). Lisez-la avec `GET /v1/proofs/{id}`.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"external_reference":{"type":"string","description":"La référence que votre plateforme a donnée en créant la session de capture (`external_reference`), renvoyée telle quelle.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos : le `party` donné à la création de la session de capture.","examples":["provider"]},"stage":{"description":"Le `stage` donné à la création de la session de capture (`pickup`, `return`…), ou `null` s'il n'y en avait pas.","examples":["pickup"],"type":["string","null"]},"status":{"type":"string","const":"failed","description":"Toujours `failed`.","examples":["failed"]},"failure_code":{"type":"string","enum":["hash_mismatch","invalid_media","signing_failed","timestamp_failed"],"description":"Pourquoi elle a échoué. `hash_mismatch` : le fichier reçu n'est pas celui qui était déclaré. `invalid_media` : ce n'est pas une photo ou une vidéo valable. `signing_failed` : le sceau n'a pas pu être appliqué. `timestamp_failed` : l'horodatage indépendant n'a pas pu être obtenu.","examples":["timestamp_failed"]},"retriable":{"type":"boolean","description":"`true` quand l'échec peut être relancé ; `false` quand il est définitif.","examples":[true]},"test":{"description":"Présent, et `true`, seulement sur un événement de test envoyé avec `POST /v1/webhook-endpoints/{id}/test`. Les vrais événements n'ont jamais ce champ.","examples":[true],"type":"boolean"}},"required":["event","proof_id","external_reference","party","stage","status","failure_code","retriable"],"additionalProperties":false}}}},"responses":{"2XX":{"description":"Un statut `2xx` accuse réception du message. Le corps de votre réponse est ignoré, mais son début (4096 caractères au plus) est conservé pour que vous puissiez le lire dans votre compte et avec `GET /v1/webhook-deliveries/{id}`."},"default":{"description":"Tout le reste (un autre statut, une redirection (nous n'en suivons jamais), aucune réponse sous 10 secondes, une erreur de connexion ou de certificat) est un échec : nous réessayons après 1 minute, 5 minutes, 30 minutes, 2 heures et 12 heures, puis nous abandonnons (`abandoned`)."}}}},"capture_session.completed":{"post":{"summary":"Une capture est terminée","description":"Envoyé quand la personne a terminé la capture, quelques secondes après l'enregistrement des fichiers et **avant** le scellement de la preuve. C'est le signal fiable que la capture est terminée, car la personne peut fermer la page avant d'être ramenée dans votre application. Attendez `proof.sealed` avant de vous appuyer sur la preuve.","tags":["Événements de webhook"],"parameters":[{"name":"X-Signature","in":"header","required":true,"description":"La signature du message : `t=<unix seconds>,v1=<signature>` (un `v1` par secret actif). La signature est le HMAC-SHA256, en hexadécimal minuscule, de l'horodatage `t`, d'un point et du corps brut, calculé avec le secret de votre endpoint (la chaîne entière, `whsec_` compris). Comparez-la à chaque valeur `v1`, et rejetez l'appel si `t` date de plus de 5 minutes. Voir la section Webhooks de l'introduction pour un exemple complet.","schema":{"type":"string","examples":["t=1791906492,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"]}},{"name":"X-Webhook-Id","in":"header","required":true,"description":"Identifiant de cette tentative d'envoi (`whd_…`). C'est celui que vous trouvez dans `GET /v1/webhook-deliveries`.","schema":{"type":"string","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]}},{"name":"X-Event-Id","in":"header","required":true,"description":"Identifiant de l'événement (`evt_…`). Il est **identique à chaque nouvelle tentative** du même événement : servez-vous-en pour ignorer les doublons.","schema":{"type":"string","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","const":"capture_session.completed","description":"Toujours `capture_session.completed` : la personne a terminé la capture et les fichiers sont enregistrés. La preuve n'est pas encore scellée : attendez `proof.sealed`.","examples":["capture_session.completed"]},"session_id":{"type":"string","description":"Identifiant de la session de capture (`cps_…`).","examples":["cps_01m4akapdbe8e8qq3er9r5qwyj"]},"proof_id":{"type":"string","description":"Identifiant de la preuve (`prf_…`). Lisez-la avec `GET /v1/proofs/{id}`.","examples":["prf_01m4akapdbe8e8qq3er9r5qwyj"]},"external_reference":{"type":"string","description":"La référence que votre plateforme a donnée en créant la session de capture (`external_reference`), renvoyée telle quelle.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos : le `party` donné à la création de la session de capture.","examples":["provider"]},"stage":{"description":"Le `stage` donné à la création de la session de capture (`pickup`, `return`…), ou `null` s'il n'y en avait pas.","examples":["pickup"],"type":["string","null"]},"completed_at":{"type":"string","description":"Quand la capture a été terminée, en ISO 8601 UTC.","examples":["2026-10-13T15:47:58.000Z"]},"test":{"description":"Présent, et `true`, seulement sur un événement de test envoyé avec `POST /v1/webhook-endpoints/{id}/test`. Les vrais événements n'ont jamais ce champ.","examples":[true],"type":"boolean"}},"required":["event","session_id","proof_id","external_reference","party","stage","completed_at"],"additionalProperties":false}}}},"responses":{"2XX":{"description":"Un statut `2xx` accuse réception du message. Le corps de votre réponse est ignoré, mais son début (4096 caractères au plus) est conservé pour que vous puissiez le lire dans votre compte et avec `GET /v1/webhook-deliveries/{id}`."},"default":{"description":"Tout le reste (un autre statut, une redirection (nous n'en suivons jamais), aucune réponse sous 10 secondes, une erreur de connexion ou de certificat) est un échec : nous réessayons après 1 minute, 5 minutes, 30 minutes, 2 heures et 12 heures, puis nous abandonnons (`abandoned`)."}}}},"capture_session.rejected":{"post":{"summary":"Une capture est refusée","description":"Envoyé quand une capture qui complète un « avant » est refusée parce qu'une autre capture l'a déjà complété (la première terminée l'emporte). Rien n'a été enregistré, aucune preuve n'existe et aucun crédit n'a été utilisé ; la personne qui a terminé en second a reçu `409 compare_to_already_used`.","tags":["Événements de webhook"],"parameters":[{"name":"X-Signature","in":"header","required":true,"description":"La signature du message : `t=<unix seconds>,v1=<signature>` (un `v1` par secret actif). La signature est le HMAC-SHA256, en hexadécimal minuscule, de l'horodatage `t`, d'un point et du corps brut, calculé avec le secret de votre endpoint (la chaîne entière, `whsec_` compris). Comparez-la à chaque valeur `v1`, et rejetez l'appel si `t` date de plus de 5 minutes. Voir la section Webhooks de l'introduction pour un exemple complet.","schema":{"type":"string","examples":["t=1791906492,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"]}},{"name":"X-Webhook-Id","in":"header","required":true,"description":"Identifiant de cette tentative d'envoi (`whd_…`). C'est celui que vous trouvez dans `GET /v1/webhook-deliveries`.","schema":{"type":"string","examples":["whd_01m4akapdbe8e8qq3er9r5qwyj"]}},{"name":"X-Event-Id","in":"header","required":true,"description":"Identifiant de l'événement (`evt_…`). Il est **identique à chaque nouvelle tentative** du même événement : servez-vous-en pour ignorer les doublons.","schema":{"type":"string","examples":["evt_01m4akapdbe8e8qq3er9r5qwyj"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","const":"capture_session.rejected","description":"Toujours `capture_session.rejected` : une capture a été refusée parce qu'une autre capture avait déjà complété le même « avant ».","examples":["capture_session.rejected"]},"session_id":{"type":"string","description":"Identifiant de la session de capture (`cps_…`).","examples":["cps_01m4akapdbe8e8qq3er9r5qwyj"]},"code":{"type":"string","const":"compare_to_already_used","description":"Pourquoi elle a été refusée. `compare_to_already_used` : une autre capture a déjà complété l'« avant » auquel celle-ci se comparait. Rien n'a été enregistré et aucun crédit n'a été utilisé.","examples":["compare_to_already_used"]},"compare_to":{"type":"string","description":"La preuve « avant » (`prf_…`) que cette capture voulait compléter.","examples":["prf_01m4akapdbe8ev5xgt0hkpcn14"]},"external_reference":{"type":"string","description":"La référence que votre plateforme a donnée en créant la session de capture (`external_reference`), renvoyée telle quelle.","examples":["booking_4471"]},"party":{"type":"string","enum":["provider","recipient"],"description":"Qui a pris les photos : le `party` donné à la création de la session de capture.","examples":["provider"]},"stage":{"description":"Le `stage` donné à la création de la session de capture (`pickup`, `return`…), ou `null` s'il n'y en avait pas.","examples":["pickup"],"type":["string","null"]},"rejected_at":{"type":"string","description":"Quand la capture a été refusée, en ISO 8601 UTC.","examples":["2026-10-13T15:49:03.000Z"]},"test":{"description":"Présent, et `true`, seulement sur un événement de test envoyé avec `POST /v1/webhook-endpoints/{id}/test`. Les vrais événements n'ont jamais ce champ.","examples":[true],"type":"boolean"}},"required":["event","session_id","code","compare_to","external_reference","party","stage","rejected_at"],"additionalProperties":false}}}},"responses":{"2XX":{"description":"Un statut `2xx` accuse réception du message. Le corps de votre réponse est ignoré, mais son début (4096 caractères au plus) est conservé pour que vous puissiez le lire dans votre compte et avec `GET /v1/webhook-deliveries/{id}`."},"default":{"description":"Tout le reste (un autre statut, une redirection (nous n'en suivons jamais), aucune réponse sous 10 secondes, une erreur de connexion ou de certificat) est un échec : nous réessayons après 1 minute, 5 minutes, 30 minutes, 2 heures et 12 heures, puis nous abandonnons (`abandoned`)."}}}}}}