Error envelope
All public endpoints return a uniform envelope on failure:
{ "error": "human-readable message" }
Validation errors include the first failing field's message; the platform never echoes internal error details or stack traces.
Status codes
| Status | Meaning |
|---|---|
400 | Malformed JSON or missing path/query parameters. |
401 | Missing or invalid authentication. |
403 | Authenticated but not authorized — wrong agent, agent inactive, external triggers disabled, etc. |
404 | Resource not found, or hidden from the caller. |
409 | Conflict — typically a backward state transition on a run. |
422 | Payload failed schema validation. |
429 | Rate limit exceeded. |
5xx | Platform or upstream failure. Retry with backoff. |
Idempotency
The following endpoints are idempotent on a caller-supplied key:
| Endpoint | Idempotency key |
|---|---|
/api/agents/{id}/runs/register | (agentId, externalRunId) |
/api/agents/{id}/runs/ingest | (agentId, externalRunId) |
Re-issuing a call with the same key updates the existing run and returns the same runId.
No other endpoint deduplicates. /runs/trigger, the synchronous variants, the webhook endpoints and the zone's run-create all start a new run on every call, and none accepts an idempotency key. A caller that retries after a timeout or a network error gets a second run. Where a duplicate would be harmful, dedupe on a natural key in your own storage — the provider's message id, the source record id — rather than relying on the API.
Rate limits
Every ingress endpoint except credential resolution is rate-limited. Exceeding the budget returns 429 with a Retry-After header giving the seconds until the current one-minute bucket resets.
See Limits and quotas for the per-endpoint numbers, along with timeouts, token lifetimes and payload caps.