# Limites du sandbox

> Ce que le sandbox Transaction Intelligence offre et ce qu'il ne promet pas : un seul environnement, aucune facturation, des scores non calibrés, des rétentions bornées, des limites de débit et douze devises.

L'API Transaction Intelligence est ouverte dans un seul environnement, le sandbox. Cette page rassemble ce qu'un développeur doit savoir avant d'intégrer : ce que le sandbox retient et combien de temps, ce qu'il borne, et ce qu'il ne promet pas. Les limites de l'API se lisent aussi dans le contrat `https://api.noryo.app/openapi.json` ; celles de Platform (registre d'usage, plafond de clés actives) se lisent sur Platform.

## Un seul environnement

Toute clé émise sur [Platform](https://platform.noryo.app/keys) est une clé sandbox, de la forme `nry_txn_sbx_<key_id>.<secret>`. Le contrat décrit aussi la forme d'une credential de production (`nry_txn_live_<key_id>.<secret>`), mais aucune clé de cette forme ne peut être créée aujourd'hui : la production n'est pas ouverte. Une credential présentée sous un préfixe qui ne correspond pas à la clé enregistrée est refusée avec un 401.

| Aspect | Sandbox | Production |
| --- | --- | --- |
| Clés | `nry_txn_sbx_…`, créées sur Platform une fois le sandbox activé par un owner ou un admin du workspace | Sur demande, revue par Noryo : aucune clé `live` n'est émise |
| Facturation | Aucune | Non ouverte |
| Limites de débit | Réglages publiés dans `x-noryo-rate-limit` (`debit_ti_v1`) | Non ouverte : les réglages provisoires ne sont pas un engagement |

Les seaux du limiteur appartiennent à un environnement (`environment_scoped: true`). Une clé `nry_mer_*` (Merchant API) est refusée sur cette API, et réciproquement.

## Aucune facturation

Le sandbox ne facture rien. Les seuls nombres qui bornent vos requêtes sont les limites de débit opérationnelles, et le contrat dit lui-même ce qu'elles ne sont pas : le tableau `not` de `x-noryo-rate-limit` le liste, dans la [Référence](https://developer.noryo.app/fr-FR/transaction-intelligence/reference).

La page [Usage](https://platform.noryo.app/usage) de Platform compte vos requêtes authentifiées ; ce n'est pas un grand livre de facturation. Un 422 y compte comme une requête, un 401 jamais, et rien n'y est facturé. Voir [Usage et clés d'API](https://developer.noryo.app/fr-FR/transaction-intelligence/usage-and-api-keys).

## Des scores non calibrés

Aucun nombre rendu par l'API n'est une probabilité. Les champs `confidence`, `strength` et `value` portent chacun une extension `x-noryo-score` qui dit leur classe, à quoi ils se comparent et à quoi ils ne se comparent pas ; `calibration` vaut `non_calibree` partout et `is_probability` vaut `false`. Un `0.85` n'est pas « 85 % de chances » : c'est une force d'évidence déterministe. Pour la classe `declared_constant` (le bloc `confidence` de `resolution`), toute transaction qui touche le même motif reçoit le même nombre. Pour décider, utilisez `policy.outcome`, jamais un seuil sur ces valeurs.

| Classe | Sens | Monotone | Usage |
| --- | --- | --- | --- |
| `declared_constant` (constante declaree) | Une valeur POSEE par la personne qui a ecrit le motif ou la regle, lue telle quelle. Elle ne resulte d'aucun calcul sur la transaction : toute transaction qui touche le meme motif recoit le meme nombre. Mesure sur 644 libelles : la precision n'est PAS monotone en ce nombre (0,85 -> 0,86 ; 0,88 -> 0,33 ; 0,92 -> 0,25 ; 0,97 -> 0,79). | false | Ne l'utilisez ni comme seuil ni comme rang. Utilisez `policy.outcome`. |
| `evidence_ratio` (part des signaux corroborants) | `present / possible` : combien de signaux corroborants ce TYPE sait produire, et combien sont effectivement la. Le denominateur DEPEND du type — 5 pour `refund_of`, 4 pour `reversal_of`, 2 pour `transfer_pair`, 5 criteres heterogenes pour une serie — et `corroborations` le rend a cote, parce que sans lui le nombre ne se lit pas. | within_type | Comparable entre deux objets du MEME type et de la meme `detector_version`. Jamais entre un `refund_of` et un `transfer_pair`, jamais entre une relation et une serie. |
| `calendar_fill` (taux de remplissage calendaire) | La part des periodes calendaires de l'etendue observee qui portent au moins une occurrence, pour l'hypothese de cadence retenue. ★ `0` signifie « aucune hypothese calendaire n'a ete retenue » (cadence `irregular_recurring`), pas « faible ». | within_cadence | Comparable entre deux series de MEME cadence. Une hebdomadaire sur 8 semaines et une annuelle sur 2 ans ne se comparent pas. |
| `anchor_stability` (stabilite de l'ancrage) | Un jeu de constantes par TYPE d'ancrage (1,0 pour un jour fixe de semaine, 0,9 pour un jour ajuste au jour ouvre) et deux formules lineaires sur l'etendue des jours pour `fixed_day_of_month` et `flexible_calendar_window`. `0` pour `unknown`. ★ `flexible_calendar_window` a DEUX regles selon la cadence : une constante 0,3 sans `day_range` en cadence `weekly`/`biweekly`, et `1 - etendue/10` (plancher 0,1) avec `day_range` en cadence mensuelle ou plus longue. | within_anchor_type_and_cadence | Comparable entre deux series de MEME type d'ancrage ET de MEME cadence. Un 0,33 `fixed_day_of_month` et un 0,3 `flexible_calendar_window` ne disent pas la meme chose ; un 0,3 `flexible_calendar_window` hebdomadaire et un 0,3 mensuel non plus. |
| `authority_tiebreak` (departage a autorite egale) | La confiance declaree de la source d'une activite. Elle n'entre en jeu qu'APRES la nature d'autorite (`curated` > `deterministic` > `provider` > `inferred` > `participant`), pour departager deux sources de meme nature. | within_nature | Ne compare jamais deux natures : un 0,95 `inferred` ne l'emporte pas sur un 0,90 `curated`. |
| `text_coverage` (couverture textuelle) | Un rapport de longueurs : la part du libelle utile que le motif apparie couvre, ou la part d'un motif compact qu'un fragment tronque recouvre. C'est une propriete du TEXTE, pas une preuve d'identite : un seuil dessus couterait 61 justes pour ecarter 17 faux. | true | Comparable entre libelles. N'en faites pas un seuil d'identite. |

Une calibration statistique n'est pas disponible dans le sandbox et n'est pas annoncée : le jour où elle existera, elle entrera dans le contrat par une version déclarée. Voir [Sémantique des scores](https://developer.noryo.app/fr-FR/transaction-intelligence/score-semantics).

## Rétentions

| Objet | Durée | Ce qui se passe ensuite |
| --- | --- | --- |
| Enrichissement (transaction brute) | 30 jours : `raw_days` et `retention_limit_days` dans `series[].history_coverage`, échéance exacte dans `expires_at` à la relecture | `GET /transactions/v1/enrichments/{enrichment_id}` rend 404 ; la transaction est supprimée et l'API ne la ressuscite jamais |
| Mémoire dérivée d'une série | 400 jours (`derived_days`), comptés depuis la dernière occurrence | Sans nouvelle occurrence, l'état dérivé est supprimé à l'échéance ; une occurrence ultérieure ouvre une série neuve |
| `Idempotency-Key` | Au moins 24 heures | Le rejeu (200 avec la réponse d'origine) n'est garanti que dans cette fenêtre |
| Registre d'usage sur Platform | 35 jours, par jour UTC | Les journées plus anciennes sortent du registre ; un zéro n'est ni « non observé », ni « indisponible » |

Ces deux mémoires ne se confondent pas : une transaction purgée reste purgée, mais la série se souvient qu'elle a eu lieu. Une réponse d'enrichissement est opérationnelle et bornée : ce n'est pas un corpus. Voir [Relire un enrichissement](https://developer.noryo.app/fr-FR/transaction-intelligence/read-an-enrichment).

## Récurrence : ce que la fenêtre permet d'établir

Le contrat le dit en une phrase : deux occurrences font émerger une série, trois peuvent l'établir, une seule jamais. Une série mensuelle peut donc s'établir en quelques occurrences ; une série annuelle n'en gagne qu'une par an, dans une mémoire dérivée (`derived_days`) comptée depuis la dernière occurrence. Avant de lire `status` comme un verdict, lisez `history_coverage` plutôt qu'`occurrence_count` seul :

- `sufficiency` répond à une seule question, « peut-on croire la cadence ? », avec `sufficient`, `limited` ou `insufficient`. `insufficient` signifie « notre mémoire est trop courte pour en juger », jamais « il n'y a pas d'occurrence plus ancienne » ;
- `observed_days` est l'étendue réellement observée, de la première à la dernière occurrence connue ;
- `first_occurrence_bounded` vaut `true` quand l'observation commence avec la première occurrence connue : la série a pu commencer avant.

Il n'existe volontairement aucun champ `started_at` : `first_observed_on` est le premier jour où Noryo a observé la série, pas le jour où elle a commencé. Voir [Séries récurrentes](https://developer.noryo.app/fr-FR/transaction-intelligence/recurring-series).

## Limites de débit et plafond de clés

Les limites de débit s'appliquent par clé et par workspace ; les nombres viennent du contrat :

`debit_ti_v1` — operational_burst_protection · token_bucket

- par clé : 120 requêtes / minute (capacité 120, recharge 2/s)
- par workspace : 600 requêtes / minute (capacité 600, recharge 10/s)

« 120 requetes / minute » est traduit en seau a jetons : capacite 120 (la rafale toleree) rechargee a 2 jetons / seconde (le regime durable). Une clef au repos peut envoyer 120 requetes d'un coup, puis 2 par seconde ; sur la premiere minute apres un repos, jusqu'a 240 passent. Le workspace, lui, borne la somme de toutes ses clefs a 600 / minute (capacite 600, 10 / s) : cent clefs ne font pas cent fois la limite.

Ce n'est pas : `sandbox_lifetime_quota`, `production_usage_quota`, `billing_entitlement`, `commercial_promise`.

Au-delà, l'API répond 429 avec `Retry-After` : rien n'a été calculé ni enregistré, et la requête se rejoue après le délai. Créer plusieurs clés ne multiplie pas la limite : le seau du workspace borne la somme de toutes ses clés. Voir [Limites de débit](https://developer.noryo.app/fr-FR/transaction-intelligence/rate-limits).

Le nombre de clés actives par workspace est plafonné ; Platform lit ce plafond du serveur, et les clés révoquées n'y comptent pas. Une révocation est immédiate : dès la requête suivante, la clé reçoit un 401 et aucun usage n'est compté. Le secret n'est montré qu'une fois, à la création, et Noryo ne le conserve pas : un secret perdu ne se récupère pas, révoquez la clé et créez-en une nouvelle. Voir [Authentification](https://developer.noryo.app/fr-FR/transaction-intelligence/authentication).

## Devises acceptées

`amount.currency` accepte les douze devises de l'enum `Money.currency` ; toute autre est refusée avec un 422 `unknown_currency`. Le nombre de décimales admis dépend de la devise (`amount_precision_exceeds_currency`) : `5.905 EUR` est refusé, `100.50 ISK` aussi, parce que ISK et JPY n'en ont aucune et que KWD en a trois. `amount.value` est une chaîne, jamais un nombre JSON.

**Schéma `Money`**

| Champ | Type | Requis | Description |
| --- | --- | --- | --- |
| `value` | string | oui | Décimal en chaîne. Un flottant perdrait des centimes en silence. Le nombre de décimales admis dépend de la devise : `5.905 EUR` est refusé, `100.50 ISK` aussi (ISK et JPY n'en ont aucune, KWD en a trois). Motif : `^-?(0\|[1-9][0-9]{0,15})(\.[0-9]{1,4})?$`. |
| `currency` | string | oui | Une devise hors de cette liste est refusée 422 `unknown_currency`. Valeurs : `CAD`, `CHF`, `DKK`, `EUR`, `GBP`, `ISK`, `JPY`, `KWD`, `NOK`, `PLN`, `SEK`, `USD`. |

Voir [Enrichir une transaction](https://developer.noryo.app/fr-FR/transaction-intelligence/enrich-a-transaction).

## Ce que le sandbox ne promet pas

- **Un accès production.** Il ne s'obtient par aucun geste : il se demande, Noryo le revoit, et une approbation n'émet aucune clé `live` : d'autres conditions la suivent. La facturation n'est pas ouverte. Voir [Accès production](https://developer.noryo.app/fr-FR/transaction-intelligence/production-access).
- **Une précision chiffrée.** Aucun score n'est calibré, aucun taux de précision n'est annoncé. Un score ne se compare qu'à l'intérieur de sa classe et des conditions que son `x-noryo-score` déclare (`comparable_within` : même type, même cadence ou même nature selon la classe), à `detector_version` égale.
- **Une prévision.** `expected_next_at` est absente tant qu'une série n'est pas établie ou que sa cadence est irrégulière ; `expected_next_window` est une fenêtre, jamais une date.
- **Une vérification de vos déclarations de couverture.** `provenance` vaut toujours `caller_asserted` : Noryo enregistre ce que vous affirmez et ne vérifie pas l'exhaustivité d'une banque. Voir [Couverture d'observation](https://developer.noryo.app/fr-FR/transaction-intelligence/observation-coverage).
- **Un calendrier de jours fériés.** Aucun férié n'est modélisé ; un report est absorbé par la tolérance de la fenêtre, pas reconnu.
- **Une fin déduite du silence.** `lifecycle.state = ended` est réservé à une preuve terminale explicite ; sans couverture complète, une absence donne `unknown`, pas `late`. Voir [Cycle de vie d'une série](https://developer.noryo.app/fr-FR/transaction-intelligence/series-lifecycle).
- **Une localisation.** `confidence.location` vaut toujours `0` : rien n'est résolu sur cet axe dans cette version.
- **Une vérité partagée à partir d'un seul workspace.** Séries et relations restent privées ; une connaissance de nature `participant` ne devient jamais une vérité du graphe d'entités.
- **Un SDK.** Les exemples reposent sur `curl` et `fetch`, exécutables tels quels contre le sandbox.
- **Un rôle de prestataire de paiement.** Noryo Transaction Intelligence n'est ni un prestataire de paiement, ni une banque, ni une BaaS, ni un grand livre comptable.

## Pour aller plus loin

- [Quickstart](https://developer.noryo.app/fr-FR/transaction-intelligence/quickstart) : de l'identité Noryo au premier enrichissement.
- [Erreurs](https://developer.noryo.app/fr-FR/transaction-intelligence/errors) : le catalogue des problèmes, dont `unknown_currency`, `not_found` et `rate_limited`.
- [Référence](https://developer.noryo.app/fr-FR/transaction-intelligence/reference) : le contrat généré, avec `x-noryo-rate-limit` et `x-noryo-score-classes`.

---

Page canonique : https://developer.noryo.app/fr-FR/transaction-intelligence/sandbox-limitations
