Errors.
Every status code you'll see, what it means, and how to fix the request.
This page covers the webhook service. Alchemist's tool errors are in Build with Alchemist.
Error response shape
Every error from the webhook service — 4xx and 5xx alike — returns a JSON body with the same envelope:
Error envelopeJSON
{
"error": {
"code": "unauthorized",
"message": "Authorization header is missing or malformed.",
"request_id": "req_3f9a1b2c"
}
}
| Field | Description |
|---|---|
code |
Machine-readable error code. Use this in your error-handling logic. |
message |
Human-readable explanation safe to show in logs. |
request_id |
Opaque per-request ID. Include it in support emails so Olbrain can trace the exact request. |
Status reference
| Status & code | Meaning | What to do |
|---|---|---|
400 invalid_json, bad_request |
The body isn't valid JSON, or doesn't match what the agent expects. | Check your JSON against the agent's input schema. |
400 invalid_body |
A signed webhook's body isn't a JSON object. | Send a JSON object. |
400 runtime_not_applicable |
The endpoint doesn't fit the agent type: run routes on a chat agent, session routes on a job, stats on a research agent. | Run management is for jobs; session management is for chat agents. |
400 invalid_status |
An unknown status filter when listing runs. |
Use one of the statuses in Run management. |
400 invalid_days |
days is not 1, 7 or 30 when reading agent stats. |
Use one of those windows. See Monitoring & analytics. |
400 invalid_resolution |
An approval body is missing exception_id, has another resolution than approved, rejected or modified, or sends modified_data without modified. |
See Approvals. |
401 unauthorized |
The Authorization header is missing or malformed, or the key is unknown, revoked, or expired. | Send exactly Bearer ak_... and check the key is active in Noesis. |
401 invalid_signature |
A signed webhook failed verification. | Check the secret, the signed bytes, and your clock. |
402 insufficient_funds, credit_limit_exceeded |
Your organization can't pay for the request. | See Billing & plans. |
403 subscription_inactive, subscription_suspended |
No active subscription, or billing is suspended. | See Billing & plans. |
403 agent_not_published |
The agent isn't published yet. | Publish it, or ask Alchemist to. |
403 agent_archived |
The agent is paused or retired. | If it is paused, ask an org admin to resume it. A retired agent can't come back, so use another agent. |
409 agent_archived |
A research chat on an agent that is paused or retired. | If it is paused, ask an org admin to resume it. A retired agent can't come back, so use another agent. |
403 agent_locked |
The agent is locked by its owner. | Ask its owner. |
403 forbidden_key_kind |
This key, such as one made for a public share link, can't read conversations. | Use an organization Access Key. |
403 widget_origin_not_allowed |
Website chat on a site that isn't listed. | Add the exact site in Noesis. |
404 agent_not_found |
The agent doesn't exist, is in another organization, or the key is limited to another agent. Returned the same way so it doesn't leak which. | Check the agent_id and the key. |
404 session_not_found, message_not_found |
The session or message doesn't exist, or belongs to another agent. | Check both ids and the agent. |
404 run_not_found |
The run doesn't exist or belongs to another agent. | Runs are read through the agent that started them. |
404 file_id_not_found |
An uploaded file_id doesn't exist for this agent. |
Upload the file for this agent first. |
409 invalid_state_transition |
A run control the run's current state doesn't allow. | Re-fetch the run and check its state. |
409 delivery_in_progress |
The same signed delivery is still running. | Retry shortly. |
411 length_required |
The upload has no Content-Length. |
Send the header; most HTTP clients do. |
413 body_too_large, file_too_large |
The JSON body is over 1 MiB, or the file is too large. | Upload large data via File uploads. |
415 expected_multipart |
The upload isn't multipart/form-data. |
Send one part named file. |
422 validation_error |
The inputs don't match the agent's input schema. | Check the fields the agent expects. |
429 daily_run_limit |
The job reached today's run limit. | Wait until tomorrow, or raise the limit. |
500 internal_error, upload_aborted |
Something failed on our side, or an upload didn't finish. | Retry once; if it persists, contact support. |
501 runtime_not_supported |
This agent type isn't supported on this endpoint yet. | Use the endpoint for its type. |
502 upstream_error, upstream_timeout |
The agent failed or took too long. | Retry with backoff. |
503 billing_unavailable |
Billing couldn't be checked. | Retry in a few moments. |
503 widget_disabled, signed_senders_disabled, secret_unavailable, delivery_store_unavailable |
A feature or a dependency is briefly unavailable. | Retry with backoff. |
504 forward_failed |
The request couldn't be delivered to the agent. | Retry with backoff. |
Retrying
Retry on 502, 503, and 504 with exponential backoff — start at 1 s, double up to a 60 s cap, give up after roughly 10 minutes. Do not retry on 4xx — they indicate a problem with your request that retrying will not fix.
Idempotency
If a retry could produce a duplicate side effect, include an Idempotency-Key
field inside your JSON body. Your agent or workflow can dedupe against it.
Debugging a failed request
- Capture the response status and body before doing anything else.
- If 401 — confirm the key is still active in Noesis and copy it again. Keys are case-sensitive.
- If 404 — confirm the
agent_idin your URL matches the agent in Noesis, and that the key belongs to that agent's organization (and isn't limited to another agent). - If 502 — retry once after 1 s, then escalate.
- For sustained issues, email support@olbrain.com with the request id from your client logs and the time of failure.