Sections de la documentation
Erreurs
Chaque refus porte errorKind à côté de detail, ainsi que les champs sur lesquels agir. Basez votre logique sur le statut et errorKind ; la formulation de detail est écrite pour des personnes et peut changer.
La bibliothèque Python lève une exception typée pour chaque statut, choisie d'après le seul statut, jamais d'après le message. Un 5xx est retenté avec un délai croissant avant que l'exception ne soit levée.
Codes de statut
| Statut | Exception Python | Quand |
|---|---|---|
| 200 | aucune | Succès : le résultat est dans le corps. |
| 202 | aucune | Accepté : une tâche de simulation a été mise en file d'attente ; interrogez-la pour obtenir le résultat. |
| 400 Bad Request | ValidationError | La requête ne peut pas être traitée telle qu'envoyée : une entrée qui n'est pas un nombre fini, une résolution impossible à poser, un corps de tâche hors de son contrat, ou un lot vide ou au-delà de sa limite. Rien n'est décompté. |
| 401 Unauthorized | AuthError | Aucune clé n'a été envoyée (le corps porte keyUrl), ou la clé n'a pas été émise par nous, ou a été révoquée. Ne concerne jamais le quota. |
| 402 Payment Required | QuotaError | Le quota mensuel du compte est épuisé, sur toutes les routes décomptées. Rien n'a été décompté. Retry-After donne les secondes jusqu'à resetAt. |
| 403 Forbidden | AuthError | La tâche appartient à quelqu'un d'autre, ou l'offre du compte ne comprend pas le point de terminaison par lots ou le mode de résolution demandé. |
| 404 Not Found | NotFound | Aucun slug de calculateur, type de tâche ou tâche de ce nom. Rien n'est décompté. |
| 409 Conflict | APIError | Une approbation d'appareil alors que la limite de clés est atteinte, ou pour un code déjà tranché (un appel depuis un navigateur connecté). |
| 422 Unprocessable Content | ValidationError | Le corps est illisible : un champ obligatoire manque, ou une valeur est du mauvais type (une entrée envoyée sous forme de texte). Traité avant que la route ne s'exécute. |
| 429 Too Many Requests | RateLimitError | Trop de requêtes en une minute pour l'identifiant, ou trop de tâches en file d'attente ou en cours à la fois. Retry-After indique quand réessayer. |
| 500 Internal Server Error | APIError | Le résultat a été calculé mais n'a pas pu être renvoyé, ou une résolution a échoué. Rien n'a été facturé. |
| 503 Service Unavailable | APIError | La clé ou le compteur de quota n'a pas pu être vérifié, ou une tâche n'a pas pu être mise en file d'attente. Rien n'a été mis en file d'attente ni facturé ; réessayez. |
Deux autres exceptions sont levées sans statut : JobFailed, quand une tâche se termine en failed (elle porte le errorKind de la tâche comme .kind), et LoginError, quand rftools login ne délivre aucune clé.
Corps des refus
Voici les corps que l'API envoie, avec les chiffres de ce mois-ci tirés de la table des offres.
{
"detail": "An API key is required. Get a free key at https://rftools.io/dashboard/?newKey=1.",
"errorKind": "invalid_request",
"keyUrl": "https://rftools.io/dashboard/?newKey=1"
}{
"detail": "This API key is not valid. It may have been revoked.",
"errorKind": "invalid_request"
}Mal formée, inconnue ou révoquée. Un 401 ne signifie jamais que le quota est épuisé.
{
"detail": "This account's 100 API calls for September are used. They reset on 2026-10-01. The API plan includes 10,000 a month.",
"errorKind": "rate_limited",
"reason": "allowance",
"limit": 100,
"used": 100,
"upgradeUrl": "https://rftools.io/pricing/",
"overageUrl": null,
"resetAt": "2026-10-01T00:00:00+00:00"
}Avec Retry-After en secondes jusqu'à resetAt. Le même corps sur toutes les routes décomptées, calculateurs compris. overageUrl est renseigné lorsque l'offre peut activer le paiement à l'usage ; reason vaut overage_cap une fois ce plafond aussi atteint. Rien n'a été décompté.
{
"detail": "More than 30 requests in 60 seconds from this address. An API key allows 120.",
"errorKind": "rate_limited",
"limit": 30,
"windowSeconds": 60,
"upgradeUrl": "https://rftools.io/pricing/"
}Avec Retry-After. La limite dépend de l'identifiant que porte la requête.
{
"detail": "This account already holds 1 API key, the most the Free plan allows. Revoke a key to free its place, or upgrade to Pro for 3 API keys.",
"errorKind": "not_available",
"keyLimit": 1,
"manageUrl": "https://rftools.io/dashboard/#api-usage",
"upgradeUrl": "https://rftools.io/pricing/"
}POST /apikeys répond 400 ; l'approbation d'appareil répond 409 avec reason: key_limit.
Types d'erreur
errorKind est un ensemble fermé, sur une requête refusée et sur une tâche de simulation qui a échoué après avoir été acceptée. Basez votre logique sur lui plutôt que sur la formulation du message.
| errorKind | Signification |
|---|---|
| invalid_request | Un paramètre manque, est du mauvais type, sort de sa plage, ne figure pas parmi les options déclarées ou n'est pas un paramètre de ce type de tâche. Le corps du 400 liste chaque paramètre en cause. |
| too_large | La requête respecte le contrat mais dépasse ce que l'environnement de calcul de cette offre peut traiter. Réduisez la taille du problème. |
| not_available | La requête demande un mode ou une fonction que cette offre ne comprend pas. Le message nomme ce que l'offre comprend. |
| rate_limited | Une limite de tâches simultanées ou un quota mensuel est épuisé. Porte Retry-After et, pour un quota mensuel, resetAt. |
| timeout | La tâche a dépassé la durée maximale de son type. Elle n'est pas facturée. |
| interrupted | L'exécution s'est arrêtée avant la fin : un worker a été remplacé ou une tâche a été arrêtée. Elle n'est pas facturée. |
| result_expired | La tâche s'est terminée, mais son résultat n'est plus stocké. Le statut reste completed et ne porte pas de resultUrl. |
| transient | Le service n'a pas pu accepter ou vérifier la requête à ce moment-là. Rien n'a été mis en file d'attente ni facturé ; réessayez. |
| fault | Le service a échoué pendant le calcul. Le message indique l'étape ; rien n'est facturé. |