Skip to main content

Overview

Use this path if you’re not on Node.js, or if you need to send data the SDK doesn’t capture. The ingest endpoint accepts conversations and agent definitions in one of five formats.

Endpoint

POST https://app.calado.ai/api/ingest

Authentication

Pass your agent’s API key as a Bearer token.
Authorization: Bearer cl_your_api_key_here
Keys are prefixed with cl_ and managed from your agent’s Settings page in the dashboard.

Request format

The top-level request body:

Required

At least one of conversations or agentDefinitions must be present. Empty payloads are rejected.

Optional

agentId
string (UUID)
Pin the request to a specific agent. Validated against the API key. If omitted, the key’s default agent is used.
format
enum
Only set this when forwarding provider request/response bodies untouched. One of anthropic, openai_chat, openai_responses. Omit to use the default shape shown in the examples. See Format selector below.
conversations
array
Array of conversation objects. Max 1,000 per request.
agentDefinitions
array
Array of agent definition objects. Max 100 per request.

Conversation object

Required

messages
array
required
Array of message objects. Min 1, max 10,000.

Optional

externalId
string
Your stable id for this conversation. 1-255 characters. Used to link conversations across ingest calls (for multi-turn sessions) and to deduplicate.
sessionId
string
Grouping id for related conversations. Max 255 characters.
agentDefinitionId
string (UUID)
Link this conversation to a specific agent definition version. Used when analyzing against a known spec.
metadata
object
Arbitrary key-value data. Surfaces in the dashboard under the conversation.
traceData
object
Structured trace information. See Trace data below.
step
object
Position of this conversation in a multi-agent orchestration. See Steps below.

Message object

Required

role
string
required
Typically user, assistant, system, or tool. Any non-empty string is accepted.
content
string | ContentBlock[]
required
Either a plain string (max 100 KB) or an array of content blocks (1-1,000 blocks).

Optional

timestamp
string (ISO 8601)
When the message was produced. Used for ordering when multiple messages share the same logical turn.

Agent definition object

Required

name
string
required
Human-readable name. 1-500 characters. Combined with type to dedupe versions.
type
enum
required
One of system_prompt or tool_schema.
content
string
required
The definition text. 1 byte to 100 KB.

Content blocks

Messages support either a plain string or typed content blocks. Block types mirror Anthropic’s:
TypeShape
text{ type: "text", text: string }
thinking{ type: "thinking", thinking: string }
tool_use{ type: "tool_use", id?: string, name: string, input: unknown }
tool_result{ type: "tool_result", tool_use_id?: string, content?: string | Array<{type:"text", text:string}>, is_error?: boolean }
other{ type: string, ...anything } — unknown block types pass through

Trace data

When you have structured trace info (tool calls with outputs, retrieval results), attach it so analysis has more to work with.
traceData.events
array
{ type, timestamp, duration?, metadata? }[]. Generic trace events.
traceData.toolCalls
array
{ name, input, output?, error?, timestamp?, duration? }[]. One entry per tool invocation.
traceData.retrievals
array
{ query, chunks[], sourceDocIds?, timestamp? }[]. RAG retrieval results.

Steps

When a conversation is one call inside a multi-agent orchestration, attach a step so calado can render the run as a tree and attribute behavior to the right sub-agent. Omit it for single-agent conversations.
step.id
string
Stable id for this step within the run.
step.parentId
string
Id of the parent step. Omit for the root step. Cannot equal step.id.
step.roleName
string
Human-readable role for this sub-agent, e.g. orchestrator or flight_search.
step.inlineDefinition
string | object
The sub-agent’s dynamic prompt or tool schema for this call — the “how it should work” side calado analyzes this step against. String or object, up to 100 KB. Omit it and the step is analyzed against the agent’s static definition.

Format selector

The format field tells calado how to parse the conversations array when you’re forwarding provider bodies untouched. Omit it to use the default shape shown in the examples.
ValueWhen to use
anthropicYou’re forwarding Anthropic messages.create request/response bodies untouched.
openai_chatYou’re forwarding OpenAI chat.completions request/response bodies.
openai_responsesYou’re using OpenAI’s newer responses.create API.
If you’re forwarding provider-shaped data, set format explicitly. Otherwise, leave it off and use the shape shown in the examples.

Example

curl -X POST https://app.calado.ai/api/ingest \
  -H "Authorization: Bearer $CALADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversations": [
      {
        "externalId": "session_abc123",
        "messages": [
          { "role": "user", "content": "What is the refund window?" },
          { "role": "assistant", "content": "You can request a full refund within 30 days." }
        ]
      }
    ],
    "agentDefinitions": [
      {
        "name": "system",
        "type": "system_prompt",
        "content": "You are a customer support agent for Acme Corp."
      }
    ]
  }'

Response

Success (202 Accepted)

{
  "conversations": {
    "accepted": 12,
    "skipped": 0,
    "failed": 0
  },
  "agentDefinitions": {
    "created": 1,
    "unchanged": 2
  },
  "warnings": []
}
FieldMeaning
conversations.acceptedStored with pending classification. Analysis runs when you click Run Analysis in the dashboard.
conversations.skippedRejected for structural reasons (see warnings).
conversations.failedStored, but analysis will not run.
agentDefinitions.createdNew definitions stored (content hash changed or new).
agentDefinitions.unchangedContent hash matched an existing version.
warningsNon-fatal per-item messages.

Error

CodeMeaning
400 Bad RequestPayload failed schema validation. Body contains Zod error details.
401 UnauthorizedMissing, malformed, or invalid API key.
403 ForbiddenKey exists but doesn’t have access to the specified agentId.
413 Payload Too LargeRequest body exceeds 5 MB.
429 Too Many RequestsRate limited. Back off and retry.
5xxServer error. Safe to retry with exponential backoff.

Batch limits

LimitValue
Request body size5 MB
Conversations per request1,000
Agent definitions per request100
Combined conversations + agent definitions1,000
Messages per conversation10,000
Content blocks per message1,000
Message content1 MB
Agent definition content100 KB
Tool schemas per conversation (adapter-extracted)256

Error handling

Retry on 5xx and network errors only, with jittered exponential backoff. 4xx responses are permanent and should not be retried. On repeated 401 responses, stop retrying and surface the error to your operator. The key is wrong, and retrying won’t fix it.

Next: serverless patterns

Flush the queue before your function freezes.