Seções da documentação
Erros
Toda recusa traz errorKind ao lado de detail, além dos campos para agir. Decida o tratamento pelo status e por errorKind; o texto de detail é escrito para pessoas e pode mudar.
A biblioteca Python lança uma exceção tipada para cada status, escolhida apenas pelo status, nunca pela mensagem. Um 5xx é repetido com espera progressiva antes de ser lançado.
Códigos de status
| Status | Exceção Python | Quando |
|---|---|---|
| 200 | nenhuma | Sucesso: o resultado está no corpo. |
| 202 | nenhuma | Aceito: um trabalho de simulação entrou na fila; consulte-o para obter o resultado. |
| 400 Bad Request | ValidationError | A requisição não pode ser respondida como foi enviada: uma entrada que não é um número finito, uma resolução que não pode ser montada, um corpo de trabalho fora do contrato, ou um lote vazio ou acima do limite. Nada é contabilizado. |
| 401 Unauthorized | AuthError | Nenhuma chave foi enviada (o corpo traz keyUrl), ou a chave não foi emitida por nós, ou foi revogada. Nunca diz respeito à cota. |
| 402 Payment Required | QuotaError | A cota mensal da conta se esgotou, em toda rota contabilizada. Nada foi contabilizado. Retry-After dá os segundos até resetAt. |
| 403 Forbidden | AuthError | O trabalho pertence a outra pessoa, ou o plano da conta não inclui o endpoint em lote ou o modo de resolução pedido. |
| 404 Not Found | NotFound | Não existe esse slug de calculadora, tipo de trabalho ou trabalho. Nada é contabilizado. |
| 409 Conflict | APIError | Uma aprovação de dispositivo com o limite de chaves atingido, ou para um código já decidido (uma chamada de um navegador conectado). |
| 422 Unprocessable Content | ValidationError | O corpo não pode ser lido: falta um campo obrigatório, ou um valor tem o tipo errado (uma entrada enviada como texto). Respondido antes de a rota ser executada. |
| 429 Too Many Requests | RateLimitError | Requisições demais em um minuto para a credencial, ou trabalhos demais na fila ou em execução ao mesmo tempo. Retry-After diz quando tentar de novo. |
| 500 Internal Server Error | APIError | O resultado foi calculado mas não pôde ser devolvido, ou uma resolução falhou. Nada foi cobrado. |
| 503 Service Unavailable | APIError | Não foi possível verificar a chave ou o contador da cota, ou não foi possível colocar um trabalho na fila. Nada entrou na fila nem foi cobrado; tente de novo. |
Mais duas exceções são lançadas sem status: JobFailed, quando um trabalho termina em failed (ela leva o errorKind do trabalho como .kind), e LoginError, quando rftools login não entrega nenhuma chave.
Corpos de recusa
Estes são os corpos que a API envia, com os números deste mês lidos da tabela de planos.
{
"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"
}Malformada, desconhecida ou revogada. Um 401 nunca significa que a cota se esgotou.
{
"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"
}Com Retry-After em segundos até resetAt. O mesmo corpo em toda rota contabilizada, calculadoras incluídas. overageUrl é preenchido quando o plano pode ativar o pagamento por uso; reason é overage_cap quando esse teto também se esgota. Nada foi contabilizado.
{
"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/"
}Com Retry-After. O limite depende da credencial que a requisição leva.
{
"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 responde 400; a aprovação do dispositivo responde 409 com reason: key_limit.
Tipos de erro
errorKind é um conjunto fechado, em uma requisição recusada e em um trabalho de simulação que falhou depois de aceito. Decida o tratamento por ele, e não pelo texto da mensagem.
| errorKind | Significado |
|---|---|
| invalid_request | Um parâmetro está faltando, tem o tipo errado, está fora da faixa, não é uma das opções declaradas ou não é um parâmetro deste tipo de trabalho. O corpo do 400 lista cada parâmetro com problema. |
| too_large | A requisição está dentro do contrato, mas além do que o ambiente de execução deste plano consegue rodar. Reduza o tamanho do problema. |
| not_available | A requisição pede um modo ou um recurso que este plano não inclui. A mensagem nomeia o que o plano inclui. |
| rate_limited | Um limite de trabalhos simultâneos ou uma cota mensal se esgotou. Traz Retry-After e, quando a cota é mensal, resetAt. |
| timeout | O trabalho excedeu o tempo máximo do seu tipo. Nada é cobrado por ele. |
| interrupted | A execução parou antes de terminar — um worker foi substituído ou uma tarefa foi interrompida. Nada é cobrado por ela. |
| result_expired | O trabalho foi concluído, mas o resultado não está mais guardado. O status continua completed e não traz resultUrl. |
| transient | O serviço não conseguiu aceitar nem verificar a requisição naquele momento. Nada entrou na fila nem foi cobrado; tente de novo. |
| fault | O serviço falhou durante o cálculo. A mensagem diz em qual etapa; nada é cobrado por ele. |