Errors
Consistent error envelope across every endpoint on https://eu.ingest.agentping.io/v1/.... Knowing which codes are retryable and which are terminal is most of what you need.
Response shape
JSON endpoints (POST /v1/runs, POST /v1/runs/{id}/events, POST /v1/runs/{id}/finish, POST /v1/heartbeats):
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_id",
"message": "Field 'id' must match pattern run_(eu|us)_[0-9a-f]{32}.",
"field": "id"
}
| Field | Type | Description |
|---|---|---|
error |
string | Stable machine-readable code. SDKs branch on this. |
message |
string | Human-readable explanation. |
field |
string | Present when tied to a specific request field. |
GET /v1/ping errors use text/plain with a single line; the first word is the machine code, the rest is the operator-friendly message.
Status codes
| Status | Meaning | Retryable? |
|---|---|---|
200 OK |
Idempotent retry: ID already stored with matching fields. | No retry needed. |
202 Accepted |
Payload accepted. | No retry needed. |
400 Bad Request |
Malformed: bad ID, missing field, unknown region, batch over 50, invalid JSON. | No. Fix the request. |
401 Unauthorized |
Bad credential, region mismatch, or ping-token scope violation. | No. Fix credentials or routing. |
409 Conflict |
Idempotent ID reused with different content. For runs: same id, different agent or started_at. |
No. Investigate. |
429 Too Many Requests |
Rate-limit bucket exhausted or monthly hard cap (150% of plan) hit. Retry-After set. |
Yes, after Retry-After. See Quotas. |
500 Internal Server Error |
Unexpected server failure. | Yes, with backoff. |
502 Bad Gateway |
Edge couldn't reach worker pool. | Yes, with backoff. |
503 Service Unavailable |
Ingest shedding load or deploying. | Yes, with backoff. |
Common error codes
error |
When | Typical fix |
|---|---|---|
invalid_id |
400 on malformed identifier. |
Match ^<prefix>_[a-z]{2}_[0-9a-f]{32}$. Let the SDK construct IDs. |
missing_field |
400 when a required field is absent. |
Add the field named in message. |
unknown_region |
400 when region segment isn't eu or us. |
Use a supported-region credential. |
region_mismatch |
401 when credential region differs from edge region. |
Send to the matching regional endpoint. |
invalid_credential |
401 when credential is wrong, revoked, or malformed. |
Issue a new credential. |
scope_violation |
401 when a ping token is used for an out-of-scope agent. |
Use the right token, or issue one for the new agent. |
id_conflict |
409 when the same run id was previously stored with different fields. |
Use a fresh UUIDv7. Indicates a client bug. |
rate_limit |
429 from the per-team bucket. |
Back off, retry after Retry-After. |
quota_exceeded |
429 once past 150% of plan allowance. |
Upgrade or wait for the UTC month rollover. |
Examples
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": "region_mismatch",
"message": "Credential region 'us' does not match endpoint region 'eu'. Send this request to https://eu.ingest.agentping.io/v1/... from the us region, or use an eu credential."
}
HTTP/1.1 409 Conflict
Content-Type: application/json
{
"error": "id_conflict",
"message": "Run 'run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6' exists with agent 'support-triage', started_at 2026-05-15T14:32:01.123Z. Supplied agent 'invoice-sync' does not match.",
"field": "agent"
}
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 7
{
"error": "rate_limit",
"message": "Team rate limit exceeded: 500 req/sec sustained. Retry in 7 seconds."
}
Retries
The official SDKs retry the retryable codes above automatically and never throw an AgentPing failure into your code. Terminal 4xx (400, 401, 409) are not retried; fix the request. For details, see your SDK reference.