REST API Reference

Complete reference for all 47 endpoints. All requests use HTTPS and return JSON. Authenticate with Authorization: Bearer YOUR_API_KEY.

Base URL: https://app.convoai.cloud/api/v1/

Agents

An Agent is a configured AI instance connected to a WhatsApp phone number. Agents have a knowledge base, personality settings, and conversation history.

The agent object

json
{
  "id":             "agt_01HXYZ1234ABCD",
  "name":           "My Sales Agent",
  "status":         "active",          // active | paused | draft
  "phone_number":   "+14155550123",
  "waba_id":        "123456789012345",
  "language":       "en",
  "ai_model":       "convoai-standard",
  "timezone":       "America/New_York",
  "knowledge_count": 12,
  "conversations_today": 47,
  "created_at":    "2026-01-15T10:30:00Z",
  "updated_at":    "2026-05-10T08:14:22Z"
}
GET/agents/List all agents
POST/agents/Create an agent
GET/agents/{id}/Retrieve an agent
PATCH/agents/{id}/Update an agent
DELETE/agents/{id}/Delete an agent
POST/agents/{id}/activate/Set agent to active
POST/agents/{id}/pause/Pause message handling

POST /agents/ — Parameters

FieldTypeRequiredDescription
namestringrequiredDisplay name for the agent
phone_number_idstringrequiredMeta Phone Number ID from your WABA
waba_idstringrequiredWhatsApp Business Account ID
access_tokenstringrequiredMeta System User access token (stored encrypted)
languagestringoptionalISO 639-1 code. Default: "en"
timezonestringoptionalIANA timezone. Default: "UTC"
personalitystringoptionalFree-text instructions for the AI's tone and persona
business_namestringoptionalBusiness name injected into AI context

Conversations

A Conversation represents a 24-hour WhatsApp messaging session with a single contact. It contains all messages exchanged in that window, plus AI metadata (intent, lead score, resolved status).

The conversation object

json
{
  "id":           "conv_01HABC9876WXYZ",
  "agent_id":     "agt_01HXYZ1234ABCD",
  "contact_id":   "cnt_01HJKL5678MNOP",
  "status":       "open",             // open | resolved | handed_off
  "channel":      "whatsapp",
  "lead_score":   87,
  "intent":       "booking_inquiry",
  "ai_handled":   true,
  "messages_count": 14,
  "started_at":   "2026-05-10T09:00:00Z",
  "last_message_at": "2026-05-10T09:47:12Z"
}
GET/agents/{agent_id}/conversations/List conversations
GET/conversations/{id}/Retrieve a conversation
GET/conversations/{id}/messages/List messages in conversation
POST/conversations/{id}/resolve/Mark conversation resolved
POST/conversations/{id}/handoff/Trigger human handoff
POST/conversations/{id}/resume-ai/Resume AI after handoff

GET /agents/{agent_id}/conversations/ — Query parameters

ParameterTypeDescription
statusstringFilter by status: open, resolved, handed_off
sinceISO 8601Return conversations started after this datetime
untilISO 8601Return conversations started before this datetime
lead_score_minintegerMinimum lead score (0–100)
pageintegerPage number. Default: 1
page_sizeintegerResults per page. Max: 100. Default: 20

Contacts

Contacts are the people who have sent messages to your agents. ConvoAI automatically creates a contact record on first message and enriches it over time from conversation data.

The contact object

json
{
  "id":           "cnt_01HJKL5678MNOP",
  "agent_id":     "agt_01HXYZ1234ABCD",
  "phone":        "+14155559876",
  "name":         "Sofia Ramirez",
  "email":        "sofia@example.com",   // null if not collected
  "tags":         ["hot-lead", "enterprise"],
  "pipeline_stage": "qualified",
  "lead_score":   91,
  "opted_in":     true,
  "last_seen_at": "2026-05-10T09:47:12Z",
  "created_at":   "2026-04-01T14:00:00Z",
  "metadata": {
    "company": "Acme Inc",
    "budget":  "$5k-$10k"
  }
}
GET/agents/{agent_id}/contacts/List contacts
POST/agents/{agent_id}/contacts/Create a contact
GET/contacts/{id}/Retrieve a contact
PATCH/contacts/{id}/Update a contact
DELETE/contacts/{id}/Delete a contact and all data
POST/contacts/{id}/tags/Add tags to contact
DELETE/contacts/{id}/tags/{tag}/Remove a tag
POST/contacts/{id}/opt-out/Mark contact as opted out

POST /agents/{agent_id}/contacts/ — Parameters

FieldTypeRequiredDescription
phonestringrequiredE.164 format: +14155559876
namestringoptionalFull display name
emailstringoptionalEmail address
tagsstring[]optionalArray of tag strings
pipeline_stagestringoptionalCRM pipeline stage slug
metadataobjectoptionalArbitrary key-value pairs stored on the contact

Knowledge Base

Knowledge documents are indexed by the RAG (Retrieval-Augmented Generation) engine. Every time the AI agent generates a reply, it searches the knowledge base first to ground the answer in your content.

Indexing latency: New documents are indexed within 30 seconds and applied to the next incoming message. There is no re-training step.

The knowledge document object

json
{
  "id":          "kdoc_01HDEF2345GHIJ",
  "agent_id":    "agt_01HXYZ1234ABCD",
  "title":       "Pricing Plans 2026",
  "doc_type":    "text",              // text | url | file
  "content":     "Starter $49/mo includes...",
  "word_count":  320,
  "is_active":   true,
  "indexed_at":  "2026-05-10T09:05:12Z",
  "created_at":  "2026-05-10T09:05:00Z"
}
GET/agents/{agent_id}/knowledge/List knowledge documents
POST/agents/{agent_id}/knowledge/Create a document
GET/knowledge/{id}/Retrieve a document
PATCH/knowledge/{id}/Update a document (triggers re-index)
DELETE/knowledge/{id}/Delete and remove from index
POST/knowledge/{id}/reindex/Force re-indexing

POST /agents/{agent_id}/knowledge/ — Parameters

FieldTypeRequiredDescription
titlestringrequiredHuman-readable title for the document
doc_typestringrequiredtext, url, or file
contentstringConditionally requiredRequired if doc_type is text
urlstringConditionally requiredRequired if doc_type is url. We scrape and index the page.
is_activebooleanoptionalWhether to include in RAG searches. Default: true

Messages

Send outbound WhatsApp messages programmatically from your backend. Messages must comply with Meta's WhatsApp Business Policy — free-form text can only be sent within the 24-hour customer service window. Outside that window, use a template type.

Opt-in required. You may only send messages to contacts who have explicitly opted in to receive communications from your business. ConvoAI will reject sends to opted-out contacts with 403 Forbidden.

POST/agents/{agent_id}/messages/Send a message
GET/messages/{id}/Get message status

POST /agents/{agent_id}/messages/ — Parameters

FieldTypeRequiredDescription
tostringrequiredRecipient phone number in E.164 format
typestringrequiredtext or template
textstringConditionally requiredMessage body. Required when type is text. Max 4096 chars.
template_namestringConditionally requiredMeta-approved template name. Required when type is template.
template_paramsstring[]optionalVariable substitutions for template placeholders, in order.
language_codestringoptionalBCP 47 language code for template. Default: "en_US"
json · text message
{
  "to":   "+14155559876",
  "type": "text",
  "text": "Hi Sofia! Your appointment on May 15 is confirmed. Reply CANCEL to cancel."
}
json · template message
{
  "to":              "+14155559876",
  "type":            "template",
  "template_name":   "appointment_reminder",
  "template_params": ["Sofia", "May 15", "10:00 AM"],
  "language_code":   "en_US"
}

Analytics

Pull performance metrics for an agent or the whole account. All metrics are pre-aggregated and returned instantly with no pagination.

GET/agents/{agent_id}/analytics/Summary for date range
GET/agents/{agent_id}/analytics/conversations/Conversation volume over time
GET/agents/{agent_id}/analytics/leads/Lead qualification metrics
GET/agents/{agent_id}/analytics/csat/CSAT scores and distribution
json · GET /analytics/ response
{
  "period":              "2026-05-01 / 2026-05-10",
  "conversations_total":  1247,
  "ai_resolved_pct":      91.4,
  "handoff_pct":          8.6,
  "leads_qualified":      284,
  "appointments_booked":  67,
  "avg_response_time_ms": 1840,
  "avg_csat":             4.7,
  "messages_sent":        5832,
  "messages_received":    4109
}

Error Codes

ConvoAI uses standard HTTP status codes. All errors return a JSON body with error and detail fields.

json · error response
{
  "error":  "validation_error",
  "detail": "The 'to' field must be a valid E.164 phone number.",
  "field":  "to",        // present for field-specific errors
  "code":   "invalid_phone"
}
StatusError codeMeaning
400bad_requestMalformed JSON or missing required parameter
400validation_errorA field value is invalid (wrong type, format, or constraint)
401authentication_requiredMissing or malformed Authorization header
401invalid_api_keyThe API key is not recognised or has been revoked
403forbiddenAuthenticated but not permitted (e.g. cross-account access)
403contact_opted_outAttempted to send a message to an opted-out contact
403plan_limitAction requires a higher subscription plan
404not_foundThe requested resource does not exist
409conflictResource already exists (e.g. duplicate phone number)
422unprocessableRequest understood but unable to process (e.g. WhatsApp window expired)
429rate_limitedToo many requests. See Retry-After header.
500server_errorInternal error. Automatically reported to our team.
503meta_unavailableMeta's WhatsApp API is unreachable. Retry with exponential backoff.

Idempotency

All POST requests accept an optional Idempotency-Key header. Sending the same key twice within 24 hours returns the original response without performing the action again. Use this to safely retry failed requests.

bash
curl -X POST https://app.convoai.cloud/api/v1/agents/agt_xxx/messages/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: order-confirm-12345" \
  -H "Content-Type: application/json" \
  -d '{"to":"+14155559876","type":"text","text":"Your order is confirmed!"}'