camelAI Documentation

API Reference

REST API

Create agents, send prompts, poll runs and read events over HTTP

The REST API is served under https://run.camelai.com/v1. The full specification is /v1/openapi.json (OpenAPI 3). Every request sends Authorization: Bearer <API key>; see Authentication.

The SDKs wrap all of this, including tool calls over the agent's own connection, which REST alone can't serve. Use REST for languages without an SDK, and for scripts.

Create an agent

bash
curl https://run.camelai.com/v1/agents \
  -H "Authorization: Bearer $CAMELAI_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: support-triage" \
  -d '{"model": "anthropic/claude-sonnet-5-5", "systemPrompt": "Be concise.", "builtins": ["web_search"]}'
json
{"id": "client_...", "token": "...", "expiresAt": null}

The Idempotency-Key is the agent's key: the same key returns the same agent, brought to the configuration you send. The body takes name, model, systemPrompt, systemPromptAppend, thinkingLevel, builtins, definition, subject, context, keyScope, spendLimit, modelHeaders, mounts, fileTools, ttlSeconds and initialMessages.

It also takes prompt, a first message with the same body as POST /v1/agents/{id}/prompt. The answer then carries prompt: the request to poll, or {error} if it was refused. The agent is made either way.

Send a message and get the result

bash
curl https://run.camelai.com/v1/agents/$AGENT/prompt \
  -H "Authorization: Bearer $CAMELAI_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "Which tickets look urgent?", "requestId": "msg-8812", "from": {"id": "u_42", "name": "Ada"}}'

The prompt answers 202 with the request record. requestId is optional; it makes the prompt idempotent, so sending the same one again returns the same run. Other fields are files, metadata, whileRunning (queue or steer), spendLimit and allowDisconnected.

Poll the request until state is completed:

bash
curl https://run.camelai.com/v1/agents/$AGENT/requests/msg-8812 \
  -H "Authorization: Bearer $CAMELAI_API_KEY"
json
{"id": "msg-8812", "method": "prompt", "state": "completed",
 "outcome": {"result": {"reply": "Tickets 4411 and 4417...", "replyIndex": 5, "messages": 6,
                        "error": null, "files": [], "toolErrors": []}}}

An ended request with error set failed; stopped: "input_required" means it waits on a person. See Run outcomes. Instead of polling, you can register a webhook for run.completed and run.failed.

Endpoints

Conventions

  • Errors are {"error": "<message>", "code": "<CODE>"}. Switch on code, not the message. See Errors.
  • Every POST that changes something takes an Idempotency-Key header. A retry with the same key, path and body gets the first answer again, for 24 hours.
  • Every 429 and 503 has Retry-After.