# Offres et limites

Trois offres, **la même qualité partout** : toutes les voix, tous les réglages, le MCP, l'API, les webhooks, les
questions en direct (et leur prolongation), la prise d'appel, le rappel avec contexte et les comptes rendus sont dans
chacune. Le Pro ajoute de la capacité et des outils d'équipe ; l'Entreprise se négocie compte par compte.

Page lisible : [la page Tarifs](https://dialyne.com/tarifs/). Grille lisible par machine : `GET /v1/offres` (public).
Codes stables des offres dans l'API : `particulier` (c'est l'offre **Starter**), `pro`, `entreprise`. Le code
`particulier` reste celui de l'API et des webhooks : seul le nom affiché devient Starter.

## Les trois offres

| | Starter | Pro | Entreprise |
|---|---|---|---|
| Abonnement | 0 € (recharges prépayées) | 99 € / mois | Négocié |
| Minute parlée | 0,20 € (100 crédits) | 0,17 € (85 crédits) | Négociée |
| Minute d'attente | 0,04 € | 0,04 € | 0,04 € par défaut, négociable |
| Appels en même temps | 1 | 5 | Négocié (Pro par défaut) |
| Appels par 24 h glissantes | 20 | 300 | Négocié (Pro par défaut) |
| Membres d'équipe (propriétaire compris) | 1 | 5 | Négocié |
| Clés API permanentes | 1 | 10 | Négocié |
| Appels en lot | — | Oui, 100 numéros par lot | Oui |
| Export comptable CSV | — | Oui | Oui |
| Conservation des transcriptions | 1 à 90 jours (90 par défaut) | 1 à 365 jours (90 par défaut) | Négociée |
| Support | Standard | Prioritaire, sous 24 h ouvrées | Négocié |
| Numéros | 1, offert | 1, offert (plusieurs bientôt) | Négocié |

- Prix sans TVA : franchise en base, art. 293 B du CGI. Le prix affiché est le prix payé.
- Un appel non décroché, occupé ou en erreur de notre côté ne coûte rien, quelle que soit l'offre.
- **Les recharges** : 10, 20, 50 ou 100 €. Un crédit vaut toujours 0,002 € ; une minute parlée débite 100 crédits en
  Starter (0,20 €) et 85 en Pro (0,17 €). `GET /v1/tarifs` → `recharges[].minutes_par_offre`.
- **Starter : crédits valables 30 jours après chaque recharge.** Chaque recharge a sa propre échéance, 30 jours après
  son achat.
- **Les 99 € du Pro ne contiennent pas de minutes** : ils paient la capacité, l'équipe et le prix à la minute du Pro.
- L'abonnement mensuel de minutes (`abo-10` … `abo-100`) reste disponible et ne dépend pas de l'offre.
- **Entreprise** : tout se règle par contrat (prix, abonnement, limites, conservation, membres, clés, numéros, support,
  accord de traitement des données signé). Sans valeur négociée, un réglage prend la valeur du Pro. Aucun prix public :
  dans la grille, `prix_mensuel_cents` et `minute_parlee_cents` valent `null` et `sur_devis` vaut `true`.

## Connaître son offre et sa consommation

```bash
curl -s $TEL_API/v1/offre -H "Authorization: Bearer $TEL_KEY"
```

La réponse donne `offre`, `limites` (appels en même temps, appels par 24 h, membres, clés, conservation…), `usage`
(appels en cours, appels passés sur les dernières 24 h), `fonctions` (appels en lot, export comptable, support
prioritaire) et, pour une Entreprise, `contrat`. `GET /v1/account` contient aussi `offre`, `minute_parlee_cents`,
`credits_par_minute`, `limites`, `usage` et `essai`. En MCP : `get_account_balance` renvoie `plan`,
`price_per_minute_eur` et `limits`.

## Passer au Pro, ou le quitter

- Le Pro est facturé au nom d'une société : il faut un **compte professionnel avec sa raison sociale**
  (`PUT /v1/profil/facturation`), sinon 422 `compte_pro_requis`.
- `POST /v1/offre/pro/checkout` renvoie l'adresse d'une page de paiement (abonnement mensuel de 99 €) :
  `{"url": "…", "offre": "pro", "prix_mensuel_cents": 9900}`. Réservé au propriétaire du compte, téléphone vérifié.
  Déjà en Pro : 409 `deja_pro` ; compte sous contrat Entreprise : 409 `deja_entreprise`.
- `POST /v1/offre/pro/resilier` : l'offre s'arrête à la fin de la période payée (`fin_periode`) ; le compte garde le
  Pro jusque-là, puis repasse en Starter. Rien n'est effacé et ton crédit reste. Un accusé de réception est envoyé
  par e-mail.
- Entreprise : écris-nous ; l'offre est posée sur ton compte par notre équipe, d'après le contrat.

## 5 minutes de test

- À la création du compte, une fois le numéro de mobile **vérifié par SMS**, 500 crédits de test sont ajoutés :
  5 minutes de conversation pour tester le service, **valables 30 jours**. Aucune carte n'est demandée. La réponse de `POST /v1/telephone/verifier`
  contient `essai` : `{"accorde": true, "minutes": 5, "expire_le": "…"}`, ou `{"accorde": false, "raison": "…"}`.
- `GET /v1/essai` donne l'état : `accorde`, `expire_le`, `credits_restants`, `minutes_restantes`, `en_cours` et les
  `regles`.
- Un appel « d'essai » est un appel passé alors que le compte n'a que du crédit d'essai. Ses règles : numéros
  français (+33) seulement, **un appel à la fois**, **5 minutes au plus, attente comprise**, et **annonce IA
  obligatoire** (un retrait demandé renvoie 403 `essai_annonce_ia_obligatoire`, `trial_ai_disclosure_required` en MCP).
- Un essai par numéro de téléphone, une seule fois. Les essais sont aussi limités par adresse IP et par mois : quand
  l'essai n'est pas accordé (`raison` : `telephone_deja_utilise`, `limite_ip`, `budget_epuise`…), le compte fonctionne
  normalement, sans minutes de test.
- Le crédit d'essai ne déclenche pas le numéro offert : le numéro arrive avec ta première recharge. Dès cette
  recharge, les appels redeviennent normaux (le crédit d'essai restant est utilisé en premier, car il expire le plus
  tôt).
- Les minutes de test ne sont pas remboursables.

## Limites d'appels

- **En même temps** : nombre d'appels `en_cours` au moment de créer la mission. Au-delà : 429
  `trop_d_appels_simultanes`.
- **Par 24 h glissantes** : appels lancés sur les 24 dernières heures (pas depuis minuit). Au-delà : 429
  `plafond_journalier_atteint`, avec `erreur.reessayer_apres_s`.
- On compte les missions créées sur les 24 dernières heures. Un lot compte autant de missions que de numéros.
- Les limites anti-abus restent les mêmes pour toutes les offres (même numéro moins de 2 min après, plus de 3 missions
  par 24 h vers un même numéro… voir [reference.md](reference.md#anti-abus)).

Les réponses 429 portent l'en-tête `Retry-After` (secondes). Attends ce délai avant de réessayer.

## Codes d'erreur

Format commun : `detail` commence toujours par le code, puis `erreur` détaille.

```json
{"detail": "plafond_journalier_atteint : Limite atteinte : 20 appels sur 24 heures. Nouvel appel possible dans 90 min environ.",
 "erreur": {"code": "plafond_journalier_atteint", "message": "Limite atteinte : …", "message_en": "Limit reached: …",
            "limite": 20, "utilises": 20, "reessayer_apres_s": 5400, "offre": "particulier"}}
```

| HTTP | Code | Quand | Que faire |
|---|---|---|---|
| 429 | `trop_d_appels_simultanes` | Limite d'appels en même temps atteinte (`erreur.limite`, `erreur.en_cours`, `erreur.offre`) | Attendre la fin d'un appel en cours |
| 429 | `plafond_journalier_atteint` | Limite d'appels sur 24 h glissantes atteinte (`erreur.limite`, `erreur.utilises`, `erreur.reessayer_apres_s`) | Réessayer après `Retry-After` |
| 403 | `fonction_reservee_pro` | Fonction du Pro demandée depuis un compte Starter (`erreur.fonction`) | Passer au Pro |
| 409 | `trop_de_cles` | Nombre de clés API permanentes atteint | Révoquer une clé, ou passer au Pro |
| 409 | `trop_de_membres` | Équipe complète | Retirer un membre |
| 403 | `role_insuffisant` | Action réservée à un admin ou au propriétaire | Demander à un admin |
| 422 | `lot_trop_grand` / `lot_vide` | Plus de 100 numéros, ou aucun numéro valable | Découper le lot |
| 409 | `aucune_question` / `question_expiree` / `prolongation_deja_utilisee` | Prolongation impossible | Voir [questions.md](questions.md) |
| 422 | `compte_pro_requis` | Passage au Pro sans compte professionnel ni raison sociale | Compléter la facturation |
| 409 | `deja_entreprise` | Le compte a un contrat Entreprise | Nous écrire pour le modifier |
| 409 | `deja_pro` | L'offre Pro est déjà active | — |
| 403 | `essai_annonce_ia_obligatoire` | Retrait de l'annonce IA pendant l'essai | Garder l'annonce |
| 409 | `invitation_invalide` | Invitation inconnue, expirée ou déjà utilisée | Demander une nouvelle invitation |
| 409 | `email_deja_compte` | L'e-mail invité a déjà son propre compte | Inviter une autre adresse |

En MCP, les mêmes cas sont des résultats `isError: true` avec un code anglais : `too_many_live_calls`, `daily_limit`,
`plan_feature_required`, `too_many_api_keys`, `insufficient_role`, `batch_too_large`, `no_pending_question`,
`question_expired`, `hold_already_used`, `trial_ai_disclosure_required`.

## Équipe (Pro et Entreprise)

Rôles : `proprietaire` (le titulaire du compte), `admin`, `membre`.

| Action | membre | admin | propriétaire |
|---|---|---|---|
| Appels : créer, suivre, répondre, prolonger, transférer, annuler ; historique ; lots ; réglages de voix | Oui | Oui | Oui |
| Clés API, export comptable, factures, durée de conservation | — | Oui | Oui |
| Inviter, retirer ou changer le rôle des membres | — | Les `membre` seulement | Oui |
| Paiements (recharges, abonnements, offre Pro), facturation, suppression du compte | — | — | Oui |

- Inviter : `POST /v1/equipe/membres` `{"email": "…", "role": "membre"}` → lien d'invitation valable 7 jours.
- La personne invitée choisit son mot de passe : `POST /v1/equipe/rejoindre` `{jeton, mot_de_passe, nom?}`. Elle se
  connecte ensuite avec son e-mail, sur le compte de l'équipe, avec son rôle (`GET /v1/profil` → `role`, `equipe`).
- Retirer un membre ferme ses sessions. Une action hors de son rôle renvoie 403 `role_insuffisant`.
- Un e-mail qui a déjà son propre compte ne peut pas être invité (409 `email_deja_compte`).
- Si le compte repasse en Starter, les membres ne peuvent plus se connecter ; rien n'est effacé.

## Export comptable (Pro et Entreprise)

`GET /v1/factures/export.csv?depuis=2026-11-01&jusqu_au=2026-11-30` : une ligne par facture ou avoir (date d'émission
dans la période), prête pour Excel ou ton logiciel de comptabilité : séparateur `;`, virgule décimale, UTF-8 avec BOM.
Colonnes : `numero`, `type`, `date`, `client`, `siren`, `siret`, `tva_client`, `libelle`, `montant_ht_eur`, `tva_eur`,
`montant_ttc_eur`, `mention_tva`, `payee_le`, `reference_paiement`, `facture_origine` (avoirs en négatif). Réservé au
propriétaire et aux admins.
