Skip to main content

Response format

All error responses follow the same shape:
{
  "message": "Human-readable error message",
  "errors": []
}
errors is an array of field-level validation errors when applicable (e.g. request body validation failures). It is empty for most errors.

HTTP status codes

CodeNameWhen it occurs
400Bad RequestMissing required field, invalid ObjectId, batch too large, invalid parameter value
401UnauthorizedMissing or invalid API key / session cookie
403ForbiddenAPI key doesn’t have access to the workspace; agent not in workspace
404Not FoundDataset, run, trace, or agent not found
409ConflictRun is already in a terminal state (completed or failed); analysis already running
429Too Many RequestsRate limit exceeded (see Rate Limits)
500Internal Server ErrorUnexpected server error

Common errors

401 Unauthorized

{ "message": "Unauthorized", "errors": [] }
Check that:
  • Your x-api-key header is present and matches a valid workspace API key
  • The key hasn’t been revoked in Settings → API Keys

403 Forbidden

{ "message": "Could not resolve a valid workspace", "errors": [] }
{ "message": "Unauthorized workspace access", "errors": [] }
{ "message": "Agent not found in workspace or insufficient permissions", "errors": [] }
The API key is valid, but it doesn’t have the required access. Verify the workspaceId belongs to the same workspace as your API key.

404 Not Found

{ "message": "Dataset not found", "errors": [] }
{ "message": "Run not found", "errors": [] }
The requested resource doesn’t exist or belongs to a different workspace.

409 Conflict — terminal state

{ "message": "Run is already in a terminal state", "errors": [] }
Returned by POST /results when the run has already been finalized or failed. Check the run status with GET /runs/:id before submitting more results.

400 Bad Request

{ "message": "batchId is required", "errors": [] }
{ "message": "results must be a non-empty array", "errors": [] }
{ "message": "Batch size must not exceed 10", "errors": [] }
{ "message": "Each question must have main_question.query", "errors": [] }
{ "message": "CI/CD is not enabled for this dataset", "errors": [] }

Rate limits

Route groupLimit
POST /ingest/traces300 requests / minute per API key
POST /ingest/ci-runs/*60 requests / minute per API key
POST /custom-agent-evaluations/*60 requests / minute per API key
When a rate limit is hit, the response is 429 Too Many Requests. Wait for the next minute window and retry.

Retrying

Safe to retry on 500 and 429. Not safe to retry POST /results without idempotency keys — always set idempotencyKey on every result to avoid duplicate scoring on retry.