Documentation

API Reference

Base URL: https://app.getverbal.ai

Authentication

All API requests require an API key passed in the x-api-key header. Generate keys from Settings > API Keys.

curl https://app.getverbal.ai/api/v1/ingest \
  -H "x-api-key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Requests with a missing or invalid key return 401 Unauthorized.

POST/api/v1/ingest

Ingest Usage Events

Send one or more usage events from your API calls or SDK integrations. This is the primary endpoint for the Verbal SDK and MCP service.

Request Body

{
  "events": [
    {
      "provider": "anthropic",       // required: "anthropic" | "openai" | "google" | ...
      "model": "claude-opus-4",      // required: model identifier
      "input_tokens": 1024,          // required: prompt token count
      "output_tokens": 512,          // required: completion token count
      "cost_usd": 0.0183,            // optional: override calculated cost
      "duration_ms": 2340,           // optional: request duration
      "session_id": "sess_abc123",   // optional: group events into sessions
      "prompt": "Write a function.." // optional: requires prompt storage enabled
    }
  ]
}

Response

{
  "ok": true,
  "inserted": 1,
  "deduplicated": 0
}
POST/api/v1/trace

Ingest Agent Trace

Send agent trace data — runs, steps, tool calls, and sub-agent invocations. Use this for tracking multi-step AI workflows and agent pipelines.

Request Body

{
  "run_id": "run_abc123",            // required: unique run identifier
  "name": "Research task",           // optional: human-readable run name
  "model": "claude-opus-4",         // required: model used
  "provider": "anthropic",           // required: provider
  "steps": [
    {
      "step_id": "step_1",
      "type": "llm_call",            // "llm_call" | "tool_call" | "sub_agent"
      "input_tokens": 800,
      "output_tokens": 200,
      "duration_ms": 1200,
      "tool_name": null              // for type="tool_call": tool identifier
    }
  ],
  "total_cost_usd": 0.024,           // optional: total run cost
  "status": "completed"             // "completed" | "failed" | "running"
}

Response

{
  "ok": true,
  "run_id": "run_abc123"
}
POST/api/v1/import/claude

Import Claude Export

Upload a Claude conversation export JSON file. Events are deduplicated — re-importing the same file is safe.

Request

curl -X POST https://app.getverbal.ai/api/v1/import/claude \
  -H "x-api-key: your-api-key-here" \
  -F "file=@conversations.json"

Response

{
  "ok": true,
  "processed": 142,
  "inserted": 138,
  "deduplicated": 4
}
POST/api/v1/import/chatgpt

Import ChatGPT Export

Upload the conversations.json file from an OpenAI data export. Same deduplication guarantee.

Request

curl -X POST https://app.getverbal.ai/api/v1/import/chatgpt \
  -H "x-api-key: your-api-key-here" \
  -F "file=@conversations.json"

Response

{
  "ok": true,
  "processed": 87,
  "inserted": 85,
  "deduplicated": 2
}

Error Codes

400Bad Request — missing required fields or invalid JSON
401Unauthorized — missing or invalid API key
402Payment Required — feature requires a paid plan
413Payload Too Large — file exceeds 50MB limit
429Too Many Requests — rate limit exceeded
500Internal Server Error — something went wrong on our end