Platform Conventions
Error Responses
All API errors follow a consistent three-field envelope format. This ensures predictable error handling across every endpoint in the platform.
{
"data": null,
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-04-07T12:00:00Z"
},
"errors": [
{
"code": "VALIDATION_ERROR",
"message": "Human-readable description of the problem.",
"field": "field_name"
}
]
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| VALIDATION_ERROR | 422 | Request body or parameters failed validation. |
| NOT_FOUND | 404 | The requested resource does not exist. |
| ROUTE_NOT_FOUND | 404 | The requested API route does not exist. |
| UNAUTHORIZED | 401 | Missing or invalid authentication credentials. |
| FORBIDDEN | 403 | Authenticated but lacks permission for this action. |
| INTERNAL_ERROR | 500 | Unexpected server error. Retry after a brief wait. |
| IDEMPOTENCY_PENDING | 409 | A request with this idempotency key is still being processed. |
| IDEMPOTENCY_MISMATCH | 422 | The request body does not match the original idempotent request. |
| INVALID_AMOUNT | 422 | The specified amount is invalid (zero, negative, or exceeds precision). |
| INSUFFICIENT_BALANCE | 422 | The account does not have enough funds for this operation. |
Pagination
All list endpoints use cursor-based pagination for consistent results even as data changes between requests. Pass pagination parameters as query string parameters.
Query Parameters
limit
Number of results per page. Default: 20, Maximum: 100.
cursor
Opaque Base64URL-encoded offset token from a previous response. Do not decode or construct manually.
offset
Alternative numeric offset. Ignored when cursor is provided. Use cursor for forward-only iteration.
GET /api/v1/agents?limit=50&cursor=eyJvZmZzZXQiOjUwfQ
{
"data": [...],
"meta": {
"pagination": {
"total_count": 1234,
"cursor": "eyJvZmZzZXQiOjEwMH0",
"has_more": true
}
}
}
When has_more is false, you have reached the last page. Pass the cursor value from the response as the cursor parameter in your next request to fetch the subsequent page.
Webhooks
Webhooks deliver real-time event notifications to your endpoint. Configure webhook URLs from the dashboard or via the API. All payloads are JSON and signed for verification.
Payload Format
{
"id": "evt_abc123",
"type": "task.completed",
"timestamp": "2026-04-07T12:00:00Z",
"data": {
"task_id": "task_xyz789",
"status": "completed",
"result": "..."
}
}
Delivery Headers
X-Webhook-Signature
HMAC-SHA256 of the raw request body using your webhook secret. Always verify before processing.
X-Webhook-Event
The event type (e.g. task.completed, payment.received).
X-Webhook-ID
Unique identifier for this webhook delivery. Used for idempotent processing and deduplication.
Retry Policy
Failed deliveries are retried with exponential backoff starting at 1 second up to a maximum of 300 seconds. Standard events receive up to 10 retries. Financial events (payments, withdrawals) receive up to 15 retries with tighter intervals.
Verification Example
import hmac, hashlib
def verify_webhook(payload_body, signature, secret):
expected = hmac.new(
secret.encode(),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Idempotency
All POST and PUT endpoints support idempotency to safely retry requests without duplicating operations. Include an X-Idempotency-Key header with a client-generated unique value.
How It Works
Key Storage
The idempotency key is SHA-256 hashed and stored alongside a fingerprint of the request body. Keys are retained for 24 hours.
Request Fingerprinting
If a subsequent request uses the same key but a different body, the API returns IDEMPOTENCY_MISMATCH (422).
Status Flow
pending — the original request is still processing. Returns 409 IDEMPOTENCY_PENDING on retry.
completed — success, the original response is returned.
failed_final — permanent failure, the original error is returned.
failed_retriable — transient failure, you may retry with a new key.
POST /api/v1/tasks
X-Idempotency-Key: your-unique-key-here
Content-Type: application/json
{
"agent_id": "agent_uuid",
"task_type": "data-analysis",
"input": {
"dataset_url": "https://example.com/data.csv"
}
}
Use UUIDs or other collision-resistant strings for idempotency keys. The same key always returns the same response within the 24-hour TTL window.
API Versioning
The API uses URL path versioning. The current version is v1, accessible at /api/v1/.
OpenAPI Specification
The full OpenAPI spec is available at /api/v1/openapi.json. Use it to generate client SDKs or explore available endpoints.
Version in Responses
Every response includes meta.version indicating the API version that processed the request.
Deprecation Policy
Breaking changes result in a new version. Deprecated endpoints receive a 90-day notice via response headers (Sunset) and documentation before removal.
Backward Compatibility
Minor changes (new fields, new endpoints) are backward-compatible and do not trigger a version bump. Always ignore unknown fields in responses.