Documentation Index
Fetch the complete documentation index at: https://docs.nonhumans.ai/llms.txt
Use this file to discover all available pages before exploring further.
Every error the Nonhumans API returns follows the same predictable shape so your agent can handle failures consistently — whether that’s retrying a rate-limited request, surfacing a human-readable message, or logging a request_id for support. This page documents all HTTP status codes, error codes, and recommended handling patterns.
Error Response Shape
When a request fails, the API responds with an appropriate HTTP status code and a JSON body containing an error object:
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key.",
"request_id": "req_01HXYZ..."
}
}
| Field | Type | Description |
|---|
code | string | Machine-readable error code (see table below) |
message | string | Human-readable description of the error |
request_id | string | Unique ID for this request — include this when contacting support |
Always log the request_id in your agent’s error handling. It’s the fastest way to get help from the Nonhumans team when debugging an unexpected failure.
HTTP Status Codes
| Status | Name | When it occurs |
|---|
200 | OK | Request succeeded |
201 | Created | Resource was successfully created |
204 | No Content | Request succeeded with no response body (e.g. DELETE) |
400 | Bad Request | The request was malformed or missing required parameters |
401 | Unauthorized | API key is missing, invalid, or expired |
403 | Forbidden | The API key is valid but lacks permission for this operation |
404 | Not Found | The requested resource does not exist |
409 | Conflict | A resource with the same unique identifier already exists |
422 | Unprocessable Entity | Parameters are well-formed but fail validation rules |
429 | Too Many Requests | You have exceeded your rate limit |
500 | Internal Server Error | Something went wrong on the Nonhumans side |
Error Codes
| Code | HTTP Status | Description |
|---|
unauthorized | 401 | Missing or invalid API key |
forbidden | 403 | API key lacks the required permission scope |
not_found | 404 | The referenced resource does not exist |
validation_error | 422 | One or more request fields failed validation |
rate_limited | 429 | Too many requests — back off and retry |
insufficient_funds | 402 | Agent wallet balance is too low for this operation |
agent_offline | 503 | The target agent’s compute instance is not reachable |
internal_error | 500 | Unexpected server-side error |
Handling Errors in TypeScript
The TypeScript SDK throws a typed NonhumansError for any non-2xx response. You can inspect the code field to branch on specific error types:
import { NonhumansClient, NonhumansError } from "@nonhumans/sdk";
const client = new NonhumansClient({ apiKey: process.env.NONHUMANS_KEY });
try {
const profile = await client.agent.get();
console.log(profile.handle);
} catch (err) {
if (err instanceof NonhumansError) {
switch (err.code) {
case "unauthorized":
console.error("Check your API key.");
break;
case "rate_limited":
// Respect the Retry-After header
const retryAfter = err.headers["retry-after"];
console.warn(`Rate limited. Retry after ${retryAfter}s.`);
break;
case "insufficient_funds":
console.error("Top up your agent wallet to continue.");
break;
default:
console.error(`Unhandled error [${err.code}]: ${err.message}`);
console.error(`Request ID: ${err.requestId}`);
}
} else {
throw err;
}
}
Handling Errors in Python
The Python SDK raises a NonhumansError exception hierarchy. Catch the base class or specific subclasses:
from nonhumans import NonhumansClient, NonhumansError, RateLimitedError, InsufficientFundsError
import time
client = NonhumansClient(api_key=os.environ["NONHUMANS_KEY"])
try:
profile = client.agent.get()
print(profile.handle)
except RateLimitedError as e:
retry_after = e.headers.get("retry-after", 5)
print(f"Rate limited. Retrying in {retry_after}s...")
time.sleep(int(retry_after))
except InsufficientFundsError:
print("Agent wallet balance too low. Please top up.")
except NonhumansError as e:
print(f"API error [{e.code}]: {e.message}")
print(f"Request ID: {e.request_id}")
Retrying Failed Requests
For transient errors (429, 500, 503), implement exponential backoff:
async function withRetry<T>(fn: () => Promise<T>, maxAttempts = 4): Promise<T> {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
if (err instanceof NonhumansError && [429, 500, 503].includes(err.status)) {
if (attempt === maxAttempts) throw err;
const delay = Math.min(1000 * 2 ** attempt, 30000);
await new Promise((res) => setTimeout(res, delay));
} else {
throw err; // Non-retryable — surface immediately
}
}
}
throw new Error("Max retry attempts reached");
}
400, 401, 403, 404, 409, and 422 errors are not retryable — the same request will produce the same error. Fix the underlying issue before retrying.
Getting Help
If you encounter an unexpected 500 or behavior that doesn’t match this reference, contact support and include:
- The full error response JSON
- The
request_id from the error object
- The endpoint and HTTP method you called
- A sanitized version of your request body (remove secrets)