Resources
Errors
The API uses conventional HTTP status codes and returns a JSON error object with a stable type you can branch on. Messages are for humans and may change; types will not.
#The error object
402 Payment Required
{
"error": {
"type": "insufficient_funds",
"message": "Wallet balance 3.5 is below 5.",
"hint": "Top up the wallet or lower the amount.",
"doc_url": "https://docs.synergetics.ai/errors#insufficient_funds"
}
}| Field | Description |
|---|---|
type | Machine-readable error type. Safe to branch on. |
message | Human-readable explanation. Do not parse it. |
hint | Optional. What to try next. |
doc_url | Link to this page, anchored at the error type. |
#HTTP status codes
| Code | Meaning |
|---|---|
200 | Success. |
400 | The request was malformed or missing a required field. |
401 | Missing or invalid API key, or an expired credential or session. |
402 | The wallet cannot cover the payment. |
403 | Understood but refused: revoked credential, untrusted issuer, or a mandate limit. |
404 | The object or endpoint does not exist. |
409 | The request conflicts with the object’s state, such as pending KYA. |
429 | Too many requests. Back off and retry. |
5xx | Something went wrong on our side. Safe to retry with backoff. |
#Error types
| Type | Status | What it means |
|---|---|---|
missing_parameter | 400 | A required field was absent. |
invalid_parameter | 400 | A field was present but malformed, such as a non-positive amount or an agent name with uppercase letters. |
invalid_api_key | 401 | The Authorization header is missing, malformed, or holds a revoked key. |
credential_expired | 401 | The presented credential is past its expires_at. Issue a new one. |
session_expired | 401 | The AgentTalk session token has expired. Open a new session. |
insufficient_funds | 402 | The wallet balance is below the requested amount. |
agent_revoked | 403 | The credential was revoked by its issuer. This is the kill switch firing. |
untrusted_issuer | 403 | The credential is valid but its issuer is not in your trust policy. |
mandate_exceeded | 403 | The payment breached a limit the owner signed. Lower the amount or update the mandate. |
agent_not_found | 404 | No agent with that AgentID. |
credential_not_found | 404 | No credential with that id. |
wallet_not_found | 404 | No wallet with that id. |
session_not_found | 404 | No session with that id. |
name_not_found | 404 | No agent is registered under that .twin name. |
unknown_endpoint | 404 | No route for that method and path. Check the API reference. |
kya_pending | 409 | Know Your Agent verification has not completed for this agent. |
rate_limit_exceeded | 429 | Too many requests for this key. |
#Retrying requests
Retry only when the error is transient. Retrying a 4xx other than 429 returns the same error.
- Retry
429and5xxwith exponential backoff and jitter. - Do not retry
400,401,403or404. Fix the request instead. - Re-establish on
credential_expiredandsession_expired: issue a new credential or open a new session, then retry once.
import random
import time
import requests
RETRYABLE = {429, 500, 502, 503, 504}
def call(method, url, **kwargs):
for attempt in range(5):
res = requests.request(method, url, **kwargs)
if res.status_code not in RETRYABLE:
break
time.sleep(min(2 ** attempt, 30) + random.random())
if not res.ok:
err = res.json()["error"]
raise RuntimeError(f"{err['type']}: {err['message']}")
return res.json()const RETRYABLE = new Set([429, 500, 502, 503, 504]);
async function call(url, init) {
let res;
for (let attempt = 0; attempt < 5; attempt++) {
res = await fetch(url, init);
if (!RETRYABLE.has(res.status)) break;
await new Promise((r) => setTimeout(r, Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000));
}
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.type}: ${body.error.message}`);
return body;
}Payments that fail with mandate_exceeded or insufficient_funds never touch the ledger, so there is nothing to roll back.
Last updated 5 October 2026llms.txt · synergetics.ai · © Synergetics.ai