API Reference
Full REST API documentation for CustomAgents. Create agents, send messages, manage contacts, and configure webhooks.
Base URL
https://api.customagents.io/v1Authentication
All endpoints require Bearer token authentication:
Authorization: Bearer ca_acct_YOUR_KEYPass your API key in the Authorization header on every request. Account keys are prefixed ca_acct_; per-agent keys are prefixed ca_agt_. Generate and manage keys in Settings → API Keys — see API Keys & Scopes for the full scope model, rotation, IP allowlists, and expiry.
Every key is capped at member-level access and is gated by its scopes: a request to a route whose required scope your key lacks returns 403. A request from an IP outside the key's allowlist, or after the key's expiresAt, is rejected.
Per-agent keys reach only /v1/agents/<their-agentId>/** — see Per-Agent API & MCP.
Rate limits
Limits are enforced per API key, not per plan. Routes fall into three buckets with different budgets:
| Bucket | Routes | Budget (per minute) |
|---|---|---|
| Read | GET routes | ~600 |
| Write | POST / PATCH / DELETE that don't spend | ~60 |
| Spend | money-spending routes (chat/trigger, message send) | ~20 |
Responses carry the IETF draft-7 rate-limit headers — a combined RateLimit header (with limit, remaining, and reset fields) plus RateLimit-Policy. When you exceed the budget the API responds 429 Too Many Requests.
Agents
List Agents
GET /v1/agentsReturns a list of all agents on your account.
Response:
{
"data": [
{
"id": "agent_abc123",
"name": "Customer Support",
"email": "support@yourdomain.com",
"status": "active",
"autonomyMode": "human_in_the_loop",
"createdAt": "2025-01-15T10:30:00Z"
}
]
}autonomyMode is one of full_auto, semi_auto, or human_in_the_loop.
Create Agent
POST /v1/agentsBody:
{
"name": "Sales Agent",
"role": "Qualifies inbound sales leads",
"instructions": "You are a sales qualification agent...",
"tone": "professional",
"autonomyMode": "human_in_the_loop"
}name, role, and instructions are required.
Get Agent
GET /v1/agents/:idUpdate Agent
PATCH /v1/agents/:idDelete Agent
DELETE /v1/agents/:idMessages
Email messages are sent and read through an inbox. List your inboxes with GET /v1/inboxes, then use the inbox ID in the routes below. (Inbox routes require an admin-role account key with read:inboxes / write:inboxes scope; agent-bound keys can't call them.)
Send a message
POST /v1/inboxes/:inboxId/messages/sendBody:
{
"to": "customer@example.com",
"subject": "Re: Your inquiry",
"body": "Thanks for reaching out!"
}List messages in an inbox
GET /v1/inboxes/:inboxId/messagesGet a message
GET /v1/inboxes/:inboxId/messages/:messageIdReply to a message
POST /v1/inboxes/:inboxId/messages/:messageId/replyContacts
Contacts belong to an agent, so every contact route is scoped under that agent.
List an agent's contacts
GET /v1/agents/:agentId/contactsGet a contact
GET /v1/agents/:agentId/contacts/:contactIdUpdate a contact
PATCH /v1/agents/:agentId/contacts/:contactIdContacts also support POST /v1/agents/:agentId/contacts (create), POST /v1/agents/:agentId/contacts/bulk, and DELETE /v1/agents/:agentId/contacts/:contactId.
Webhooks
Create Webhook
POST /v1/webhooksBody:
{
"url": "https://yourapp.com/webhook",
"events": ["message.received", "message.sent"]
}Valid events are the inbox.* and message.* events listed in the Webhooks documentation. There is no contact.* or escalation.* webhook event.