ドキュメントのセクション
エラー
すべての拒否には、detail と並んで errorKind と、対応に必要なフィールドが含まれます。処理はステータスと errorKind で分岐させてください。detail の文言は人が読むためのもので、変わることがあります。
Python ライブラリは、ステータスごとに型付きの例外を送出します。例外はメッセージではなくステータスだけで決まります。5xx はバックオフ付きで再試行してから送出されます。
ステータスコード
| ステータス | Python の例外 | 発生する場合 |
|---|---|---|
| 200 | なし | 成功:結果はボディに入っています。 |
| 202 | なし | 受理:シミュレーションジョブがキューに入りました。結果はポーリングで取得します。 |
| 400 Bad Request | ValidationError | 送られたままではリクエストに答えられません:有限の数でない入力、設定できない逆算、契約外のジョブのボディ、空または上限を超えたバッチ。計上はされません。 |
| 401 Unauthorized | AuthError | キーが送信されていない(ボディに keyUrl が入ります)か、こちらで発行していないキーや失効したキーです。利用枠とは関係ありません。 |
| 402 Payment Required | QuotaError | 計上対象のすべてのルートで、アカウントの月間利用枠を使い切りました。計上はされていません。Retry-After に resetAt までの秒数が入ります。 |
| 403 Forbidden | AuthError | ジョブが他人のものであるか、アカウントのプランに、バッチエンドポイントや要求された解析モードが含まれていません。 |
| 404 Not Found | NotFound | そのような計算ツールのスラッグ、ジョブタイプ、ジョブは存在しません。計上はされません。 |
| 409 Conflict | APIError | キーの上限に達した状態でのデバイスの承認か、すでに判断済みのコードに対する承認です(ログイン中のブラウザーからの呼び出し)。 |
| 422 Unprocessable Content | ValidationError | ボディを解析できません:必須フィールドが欠けているか、値の型が違います(テキストとして送られた入力など)。ルートの実行前に応答します。 |
| 429 Too Many Requests | RateLimitError | その認証情報で 1 分あたりのリクエストが多すぎるか、キュー待ち・実行中のジョブが同時に多すぎます。Retry-After に再試行できる時期が示されます。 |
| 500 Internal Server Error | APIError | 結果は計算されましたが返せなかったか、逆算に失敗しました。課金はされていません。 |
| 503 Service Unavailable | APIError | キーまたは利用枠のカウンターを確認できなかったか、ジョブをキューに入れられませんでした。キューにも入っておらず、課金もされていません。もう一度お試しください。 |
ステータスなしで送出される例外がほかに 2 つあります。ジョブが failed で終わったときの JobFailed(ジョブの errorKind を .kind として持ちます)と、rftools login がキーを受け取れなかったときの LoginError です。
拒否時のボディ
API が送るボディです。今月の数値はプランの表から読み取っています。
{
"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"
}形式が不正、不明、または失効済み。401 が利用枠の使い切りを意味することはありません。
{
"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"
}Retry-After に resetAt までの秒数が入ります。計算ツールを含む、計上対象のすべてのルートで同じボディです。プランで従量課金を有効にできる場合は overageUrl が設定され、その上限も使い切ると reason が overage_cap になります。計上はされていません。
{
"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/"
}Retry-After 付き。制限はリクエストが持つ認証情報で決まります。
{
"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 は 400 を返し、デバイスの承認は reason: key_limit 付きで 409 を返します。
エラーの種類
errorKind は、拒否されたリクエストと、受理後に失敗したシミュレーションジョブに付く、閉じた値の集合です。メッセージの文言ではなく、これで分岐させてください。
| errorKind | 意味 |
|---|---|
| invalid_request | パラメーターが欠けている、型が違う、範囲外である、宣言された選択肢にない、またはこのジョブタイプのパラメーターではありません。400 のボディに、問題のあるすべてのパラメーターが示されます。 |
| too_large | リクエストは契約の範囲内ですが、このプランの実行環境で実行できる規模を超えています。問題の規模を小さくしてください。 |
| not_available | リクエストが、このプランに含まれないモードや機能を求めています。メッセージに、プランに含まれるものが示されます。 |
| rate_limited | 同時実行ジョブの上限に達したか、月間利用枠を使い切りました。Retry-After が付き、月間利用枠の場合は resetAt も付きます。 |
| timeout | ジョブがそのタイプの時間上限を超えました。課金はされません。 |
| interrupted | 実行が完了前に止まりました(ワーカーが置き換えられたか、タスクが停止されました)。課金はされません。 |
| result_expired | ジョブは完了しましたが、結果はもう保存されていません。ステータスは completed のままで、resultUrl はありません。 |
| transient | サービスがその時点でリクエストを受け付けられなかったか、確認できませんでした。キューにも入っておらず、課金もされていません。もう一度お試しください。 |
| fault | 計算中にサービスが失敗しました。メッセージに失敗した段階が示されます。課金はされません。 |