Comptes, paliers et facturation

Statut au 27/07/2026 : self-service livré (Epic 4) — inscription, vérification e-mail, espace client, souscription/résiliation Stripe. Tableau de bord par clé, en-têtes de quota et alerte à 80% livrés (Epic 12, Stories 12.1 à 12.3). Non livré : réconciliation comptable automatisée avec Stripe (voir Dev Notes de la Story 4.4).

Parcours complet : créer un compte → clé Découverte → premier appel

  1. Inscrire un comptePOST /signup avec email + mot de passe (8 caractères minimum). Une clé Découverte est créée, mais inactive. Les domaines d'e-mails jetables courants sont refusés ; les créations de compte sont plafonnées par IP et par période (anti-abus, FR-9).
  2. Vérifier l'e-mail — cliquez le lien reçu (GET /verify?token=...). La clé devient active immédiatement.
  3. Premier appel — utilisez la clé reçue à l'étape 1 comme Authorization: Bearer fxk_... sur n'importe quel endpoint /v1/*.

Aucune action manuelle côté exploitant à aucune étape. Voir le guide de démarrage pour les commandes complètes.

Paliers

Palier Quota inclus Prix [ASSUMPTION] Dépassement
Découverte 20 documents/mois [ASSUMPTION] Gratuit Bloqué (HTTP 429) — jamais d'overage sur le gratuit
Starter 200 documents/mois [ASSUMPTION] 29 €/mois [ASSUMPTION] Overage +20 % du prix unitaire [ASSUMPTION]
Pro 1 000 documents/mois [ASSUMPTION] 79 €/mois [ASSUMPTION] Overage +20 % [ASSUMPTION]
Éditeur 5 000 documents/mois [ASSUMPTION] 199 €/mois [ASSUMPTION] Overage +20 % [ASSUMPTION]

Les montants et quotas marqués [ASSUMPTION] sont repris du PRD comme hypothèses de lancement, pas des décisions commerciales figées — à confronter au marché avant le jalon J3 (voir PRD, §4.6/FR-10). Sur un palier payant, un dépassement de quota n'est jamais bloquant : les documents au-delà du quota inclus sont facturés en overage, jamais interrompus.

Le quota est appliqué par CLÉ API, pas par compte (Story 12.1) : un compte qui possède plusieurs clés voit chacune consommer son propre volume inclus indépendamment des autres. Le tableau de bord (/account/) affiche donc une ligne de consommation par clé active, jamais un total présenté comme un plafond unique de compte.

Souscrire, changer de palier, résilier

Depuis l'espace client (/account/, connexion par e-mail/mot de passe) :

  • Souscrire ou changer de palier : redirection vers Stripe Checkout, hébergé par Stripe — votre carte ne transite jamais par l'infrastructure Heartwood.
  • Gérer carte, factures, résiliation : redirection vers le Stripe Customer Portal, exclusivement.
  • Un changement de palier (upgrade, downgrade, résiliation) est répercuté sur le quota en moins d'une minute (traité par webhook Stripe vérifié par signature).
  • Une résiliation ramène le compte au palier Découverte (pas de coupure brutale) : le quota de 20 documents/mois s'applique de nouveau.

Idempotence

Les endpoints facturés (POST /v1/generate/facturx, POST /v1/validate) acceptent un en-tête Idempotency-Key optionnel, lié au hash du corps de la requête, sur une fenêtre de 24h :

  • Même clé API + même Idempotency-Key + même corps rejoué : le document d'origine est renvoyé tel quel (en-tête Idempotency-Replayed: true), compté une seule fois.
  • Même clé API + même Idempotency-Key + corps différent : HTTP 409, rien n'est produit ni compté.
{
  "type": "idempotency-key-conflict",
  "title": "Idempotency-Key déjà utilisée avec un corps différent",
  "status": 409,
  "detail": "réutilisez une nouvelle Idempotency-Key pour un corps différent (Annexe B PRD)",
  "instance": "01H..."
}

Quota Découverte dépassé

{
  "type": "quota-exceeded",
  "title": "Quota mensuel Découverte dépassé",
  "status": 429,
  "detail": "réinitialisation le 2026-08-01 — upgradez sur /account/ pour un palier sans quota fixe",
  "instance": "01H..."
}

Toutes les erreurs de cette page suivent le format RFC 7807 (application/problem+json).

En-têtes de quota (Story 12.2)

Tout appel authentifié à un endpoint facturé (/v1/generate/facturx, /v1/validate, /v1/generate/ubl, /v1/convert, /v1/extract) porte trois en-têtes de réponse, sur toute réponse — succès comme échec (400, 409, 413, 422, 429...), pas seulement sur un refus de quota :

En-tête Signification
X-Quota-Limit Volume mensuel inclus dans le palier de la clé qui a authentifié l'appel.
X-Quota-Remaining Reste avant d'atteindre ce volume, jamais négatif.
X-Quota-Reset Date de réinitialisation du quota, au format RFC 3339 (premier jour du mois civil suivant, minuit UTC).

/v1/rulepacks (authentifié mais non facturé) ne porte pas ces en-têtes — il ne consomme aucun document du quota.

Représentation retenue pour X-Quota-Remaining sur un palier payant (Starter, Pro, Éditeur — jamais bloquant, AD-5) : le reste RÉEL du volume inclus, borné à 0. Ce n'est jamais un plafond fictif ni une valeur « illimitée » qui mentirait sur le volume réellement inclus — c'est le même chiffre que celui affiché au tableau de bord. Un palier payant à X-Quota-Remaining: 0 continue d'être servi normalement (jamais de 429) : le dépassement est simplement facturé à l'usage (overage). Sur le palier Découverte, X-Quota-Remaining: 0 signifie en revanche que l'appel suivant sera refusé (429) jusqu'à X-Quota-Reset.

Les en-têtes sont calculés sur l'usage journalisé avant l'appel en cours : la requête en cours n'est comptée qu'après son issue (succès ou échec), connue seulement après traitement — trop tard pour poser des en-têtes avant le premier octet de la réponse.

Alerte de quota à 80% (Story 12.3)

Un compte au palier Découverte qui franchit 80% de son quota mensuel (16 documents sur 20) reçoit un e-mail l'informant :

  • combien il a déjà consommé ce mois-ci ;
  • ce qui se passera au-delà du quota inclus (blocage HTTP 429, avec la date de réinitialisation) ;
  • comment changer de palier depuis l'espace client, pour ne jamais être bloqué (les paliers payants ne le sont jamais).

Au plus un envoi par clé et par mois. L'envoi de cet e-mail ne fait jamais échouer l'appel API en cours : une erreur d'envoi est journalisée côté serveur, jamais renvoyée à l'appelant.