Agent-readable docs index: /docs/llms.txt. Full docs in one file: /docs/llms-full.txt. Download /docs/docs.zip to grep all markdown files locally.

Messages

Use GET /api/v2/conversations/{conversation_id}/messages with messages:read to read public messages. Each resource has a msg_ ID, direction, actor, typed content parts, timestamps, and delivery status. Internal notes use a separate endpoint and separate permissions.

Send a message

With messages:write, call POST /api/v2/conversations/{conversation_id}/messages. Include the conversation's current ownership version:
{ "content": [{ "type": "text", "text": "Hello from Ruut." }], "expected_owner_version": 0, "external_id": "message-123" }
Replace 0 with the version returned by GET /api/v2/conversations/{conversation_id}. For a text-and-media message, include a typed media part with an uploaded media_id. See media uploads.
The service key acts as its application or configured agent. It cannot impersonate another human or agent. A human takeover or routing change can invalidate an already queued reply.

Replies and templates

Set reply_to_message_id to quote an existing public message in the same conversation. Providers render quoted replies according to their capabilities.
For eligible WhatsApp connections, use an approved template:
{ "content": [{ "type": "template", "name": "status_update", "language": "en", "variables": { "1": "Ready" } }], "expected_owner_version": 0 }
Templates must be approved for that connection and language. A template is sent on its own. A provider reply window cannot be bypassed with an ordinary text message.

Track delivery

A successful send returns 202 with an acceptance snapshot and a polling location. Use GET /api/v2/messages/{message_id} or signed message events to observe progress. Reuse the same idempotency key and body after a timeout. See delivery and retries for handling unknown outcomes.