Changelog

Journal public des modifications de l’API. Changements additifs et rétrocompatibles (nouveaux champs facultatifs) ; les changements cassants sont signalés explicitement — les intégrations existantes continuent de fonctionner sans modification.

2026-07-28 — Renommage en ChunkChef

Le produit s’appelle désormais ChunkChef. Trois changements sont visibles sur le protocole ; le reste est interne.

  • Rupture — en-têtes de signature de webhook renommés. X-Hotdoc-Timestamp et X-Hotdoc-Signature deviennent X-Chunkchef-Timestamp et X-Chunkchef-Signature. Le schéma de signature est inchangé ; seuls les noms d’en-têtes diffèrent. Mettez à jour votre vérification.
  • Rupture — le préfixe de la clé API a changé. Les nouvelles clés sont émises sous la forme chunkchef_<id>.<secret> au lieu de hotdoc_<id>.<secret>. Les clés existantes cessent d’authentifier ; générez-en une nouvelle dans le tableau de bord.
  • Rupture — le discriminateur d’erreur typée a changé. Dans Status.details, @type vaut désormais type.googleapis.com/chunkchef.v1.billing.QuotaExceededDetail. Si vous testez cette chaîne, mettez-la à jour.

Les endpoints, les formats de requête et de réponse ainsi que les domaines hotdoc.io / api.hotdoc.io restent inchangés.

2026-07-28 — Spécification OpenAPI

  • Spécification lisible par machine publiée à l’adresse /openapi.yaml — OpenAPI 3.0.3, générée à partir des définitions protobuf du service et couvrant les cinq opérations publiques de Jobs (POST /v1/jobs/upload, POST /v1/jobs, GET /v1/jobs/{id}, GET /v1/jobs/{id}/result, GET /v1/jobs). Fournissez le fichier à n’importe quel générateur compatible OpenAPI pour construire un client ; cette référence rédigée à la main reste la documentation en prose.
  • Changement de comportement — la taille de page de GET /v1/jobs est désormais bornée. pageSize vaut 50 par défaut et est plafonné à 200. Auparavant, un appel omettant pageSize renvoyait tout l’historique des travaux en une seule réponse. Si vous vous appuyiez dessus, parcourez les pages avec pageToken.
  • Changement de comportement — un pageToken qui ne se résout plus renvoie 400. Auparavant, un tel jeton reprenait la liste à la première page sans le moindre signal, ce qui pouvait vous renvoyer des enregistrements déjà vus. Traitez le 400 comme « le curseur ne s’applique plus, recommencez sans pageToken ».
  • Corrigé — parcourir GET /v1/jobs page par page ne saute ni ne répète plus de travaux. Le curseur s’ancrait sur une colonne différente de celle qui ordonnait la liste, si bien qu’une liste sur plusieurs pages pouvait perdre certains travaux et en renvoyer d’autres deux fois.

2026-07-24 — Confiance par consensus (k-consensus)

  • Nouveau champ consensus (facultatif) sur POST /v1/jobs — facultatif, nécessite responseSchema (sinon rejeté avec 400). consensus.mode fixe le nombre d’exécutions : CONSENSUS_MODE_TWO_RUNS (2, un sondage d’instabilité), CONSENSUS_MODE_THREE_RUNS (3, recommandé) ou CONSENSUS_MODE_FIVE_RUNS (5, rigueur maximale). hotdoc exécute chaque chunk k fois avec votre clé et vote champ par champ (à la pluralité) sur la réponse.
  • Nouveau champ de résultat llm[].consensusk, runsVotable, minAgreement, incomplete et disagreements[] (variants[] concurrentes avec le nombre d’exécutions et si chacune est included — a gagné le vote). Vous permet de voir sur quels champs le modèle était stable et sur lesquels il a hésité, au prix de k fois le coût en tokens sur votre clé. Voir « Exécutions de consensus » dans la documentation du Job API.

2026-07-15 — Fusion de chunks

  • Nouveau champ merge (facultatif) sur POST /v1/jobs — fusion facultative côté serveur des réponses du modèle par chunk en un seul résultat pour tout le document. merge.scope choisit une fusion par fichier (MERGE_SCOPE_FILE, par défaut) ou par tout le job (MERGE_SCOPE_JOB) ; merge.conflictPolicy détermine comment les valeurs de champ divergentes sont résolues (MERGE_CONFLICT_POLICY_FIRST_NON_NULL par défaut, ou MERGE_CONFLICT_POLICY_MAJORITY) ; merge.dedupeBy active la déduplication de contenu entre fichiers par noms de champs JSON (JSON + responseSchema uniquement ; vide conserve le comportement sûr par défaut, déduplication technique seule).
  • Nouveau champ de résultat merged[] — une entrée par fichier (ou une par job à scope=job) avec le content combiné, schemaValid (lorsque responseSchema est défini), conflicts[], les compteurs dedupeRemovedTechnical/dedupeRemovedContent, et mergeIncomplete/incompleteChunks lorsqu’un chunk n’a pas pu être fusionné en toute sécurité. Les lignes llm[] par chunk existantes restent inchangées et disponibles. Cela clôt la note en suspens « le service ne fusionne toujours pas les chunks » du 2026-06-24 — la fusion est désormais disponible, facultative, et désactivée par défaut. Voir « Fusion des résultats en chunks » dans la documentation du Job API.

2026-07-14 — Sortie structurée (JSON Schema)

  • Nouveau champ responseSchema (facultatif) sur POST /v1/jobs — un JSON Schema autonome (chaîne brute ; uniquement des #/$defs internes, ≤128 KiB, profondeur ≤64, ≤10000 nœuds) par rapport auquel hotdoc valide la réponse JSON du modèle. Pour OpenAI/Grok, il doit être compatible avec le sous-ensemble strict (chaque propriété dans required, optionnalité via type: [..., "null"], additionalProperties: false) ; un schéma écrit dans ce sous-ensemble fonctionne sans modification chez tous les fournisseurs. Un schéma invalide est rejeté avec 400 à la création du job.
  • Nouveaux champs de résultat llm[].schemaValid / llm[].schemaErrors — rapportés uniquement pour les fichiers à un seul chunk. Une réponse non conforme est tout de même renvoyée dans content, mais le job se termine avec le statut JOB_STATUS_PARTIAL au lieu de JOB_STATUS_COMPLETE. Les fournisseurs pour lesquels hotdoc émule les sorties structurées (DeepSeek, Xiaomi) bénéficient d’une tentative de réparation automatique avant l’évaluation.

2026-07-09 — Mode d’extraction

  • Nouveau champ extractionMode (facultatif) sur POST /v1/jobsEXTRACTION_MODE_HYBRID (Extraction hybride optimisée, la valeur par défaut) laisse le convertisseur choisir par fichier entre extraire le texte directement ou utiliser l’OCR ; EXTRACTION_MODE_OCR_ALWAYS force l’OCR neuronal sur tous les fichiers. Ajout d’une valeur par défaut au niveau du compte, configurable dans le tableau de bord sous Paramètres, utilisée lorsqu’un job omet extractionMode.

2026-07-08 — Playground public

  • /playground sur le site — essayez hotdoc sans inscription : envoyez un fichier, lancez un prompt prédéfini et consultez le résultat directement dans le navigateur.
  • Nouveaux endpoints de démo anonymes, /v1/demo/* : envoyer un fichier, créer un job de démo, consulter son résultat et le récupérer sur un compte réel après inscription. Les sessions sont suivies par un cookie (sans connexion) et limitées à 3 exécutions par session plus un budget quotidien partagé entre tous les visiteurs anonymes ; les résultats sont tronqués. C’est un changement additif — l’API authentifiée /v1/jobs reste inchangée.

2026-06-30 — OCR multi-fournisseurs (BYOK)

Cassant. L’étape OCR prend désormais ocr.{provider, model, providerKey} (auparavant ocr.mistralApiKey). Choisissez n’importe quel fournisseur pris en charge — Mistral est le fournisseur par défaut (mistral-ocr-latest). model est requis. De nouveaux marqueurs d’erreur OCR (provider_auth_failed, provider_key_required, rate_limited, ocr_timeout, ocr_backend_*, too_many_pages) remplacent mistral_key_required.

2026-06-26 — Clés d’idempotence

POST /v1/jobs accepte idempotencyKey. Réessayer avec la même clé et des paramètres identiques renvoie le job d’origine ; la même clé avec des paramètres différents renvoie 400.

2026-06-24 — webhooks de fin de job

  • Nouveaux champs webhookUrl et webhookSecret (tous deux facultatifs) à la création d’un job. webhookUrl est un endpoint absolu http/https ; le service y envoie un POST une fois, avec un corps JSON (job_id, account_id, status, finished_at), lorsque le job atteint un statut terminal. webhookSecret est un secret HMAC : lorsqu’il est défini, chaque requête inclut les en-têtes X-Hotdoc-Timestamp et X-Hotdoc-Signature (sha256=hex(hmac_sha256(secret, "<ts>.<body>"))). Les deux champs sont acceptés uniquement en entrée et n’apparaissent jamais dans les réponses. Politique de réessai : jusqu’à 6 tentatives avec des délais de 1 m / 5 m / 15 m / 30 m / 30 m. Voir « Webhooks » pour les détails.

2026-06-24 — découpage conscient de la structure et taille de chunk configurable

  • Découpage du texte conscient de la structure. Le texte reconnu long est désormais coupé le long des frontières de la structure de son format (Markdown / HTML / XML / plain) : les tableaux ne sont pas déchirés au milieu d’une ligne (l’en-tête d’un tableau est répété dans chaque chunk), et le contexte des titres de section est préservé. Le comportement précédent (les chunks comme lignes llm[] distinctes indexées par chunkIndex / chunkTotal) reste inchangé — le service ne fusionne toujours pas les chunks.
  • Nouveau champ neural.chunkBudgetTokens (facultatif) à la création d’un job — budget de tokens par chunk pour la fenêtre de contexte de votre modèle ; plage 160002000000, par défaut la valeur conservatrice du service. La réponse renvoie le budget effectif réel.
  • Nouveau champ ocr[].outputFormat dans le résultat du job — le format du texte reconnu (markdown / html / xml / plain).