Complete REST API reference for the AIVO Connect platform. Manage calls, contacts, appointments, knowledge base, and business info programmatically.
https://aivo.bz/api/v1Bearer aivo_...JSON (application/json)The AIVO Connect API allows you to programmatically manage your AI voice assistant. You can list and search call logs, manage contacts, create and update appointments, maintain your knowledge base, and retrieve business information.
All API access requires authentication via API key. You can generate keys with specific scopes from your Settings → API Keys page.
All API requests require a Bearer token
Include your API key in the Authorization header of every request.
Authorization: Bearer aivo_sk_your_api_key_hereAPI keys are prefixed with aivo_sk_ and have scoped permissions. Available scopes:
calls:read - Read call logs and transcriptscontacts:read / contacts:write - Read and manage contactsappointments:read / appointments:write - Read and manage appointmentsmessages:read / messages:write - Read and send SMS/MMS messagesknowledge:read / knowledge:write - Read and manage knowledge base articlesbusiness:read - Read business profile informationcurl -s -H 'Authorization: Bearer aivo_sk_your_api_key_here' \
'https://aivo.bz/api/v1/calls?limit=5'If the API key is missing or invalid, you'll receive a 401 Unauthorized response:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid API key"
}
}All API endpoints are served under /api/v1. Requests and responses use JSON (application/json).
Base URL: https://aivo.bz/api/v1
Content-Type: application/json
Accept: application/jsonThe following resources are available:
| Method | Endpoint | Description | Scope |
|---|---|---|---|
| GET | /calls | List call logs | calls:read |
| GET | /calls/:id | Get call details | calls:read |
| GET | /contacts | List contacts | contacts:read |
| POST | /contacts | Create a contact | contacts:write |
| GET | /contacts/:id | Get contact details | contacts:read |
| PATCH | /contacts/:id | Update a contact | contacts:write |
| DELETE | /contacts/:id | Delete a contact | contacts:write |
| GET | /appointments | List appointments | appointments:read |
| POST | /appointments | Create an appointment | appointments:write |
| GET | /appointments/available-slots | Get available time slots | appointments:read |
| GET | /messages | List messages | messages:read |
| POST | /messages | Send a message (SMS/MMS) | messages:write |
| GET | /messages/:id | Get message details | messages:read |
| GET | /knowledge | List knowledge articles | knowledge:read |
| POST | /knowledge | Create a knowledge article | knowledge:write |
| GET | /business | Get business profile | business:read |
| GET | /openapi.json | OpenAPI 3.1 spec | none |
List and retrieve call logs with optional filtering.
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/calls?limit=2&status=completed'{
"data": [
{
"id": "clx1abc...",
"callerNumber": "+5012279446",
"from": "+5012279446",
"to": "+5012001234",
"direction": "inbound",
"durationSeconds": 142,
"status": "completed",
"summary": "Customer asked about business hours and booked an appointment for Tuesday.",
"aiConfidenceScore": 0.94,
"costCents": 12,
"startedAt": "2026-03-29T10:15:00Z",
"endedAt": "2026-03-29T10:17:22Z",
"createdAt": "2026-03-29T10:15:00Z"
}
],
"meta": {
"cursor": "clx1abc...",
"hasMore": true
}
}Query parameters:
limit - Number of results (1–100, default: 20)cursor - Cursor for paginationstatus - Filter by status: completed, missed, faileddirection - Filter: inbound or outboundCreate, list, update, and delete contacts.
curl -s -X POST -H 'Authorization: Bearer aivo_sk_...' \
-H 'Content-Type: application/json' \
'https://aivo.bz/api/v1/contacts' \
-d '{
"name": "Maria Santos",
"phone": "+5016123456",
"email": "maria@example.com",
"notes": "Prefers morning appointments"
}'{
"data": {
"id": "clx2def...",
"name": "Maria Santos",
"phone": "+5016123456",
"email": "maria@example.com",
"notes": "Prefers morning appointments",
"createdAt": "2026-03-29T11:00:00Z",
"updatedAt": "2026-03-29T11:00:00Z"
}
}List appointments and check available time slots.
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/appointments/available-slots?date=2026-04-01'{
"data": [
{ "start": "2026-04-01T09:00:00Z", "end": "2026-04-01T09:30:00Z" },
{ "start": "2026-04-01T09:30:00Z", "end": "2026-04-01T10:00:00Z" },
{ "start": "2026-04-01T10:00:00Z", "end": "2026-04-01T10:30:00Z" }
]
}Send and retrieve SMS/MMS messages through your AIVO phone number. Messages can be sent to contacts or arbitrary phone numbers.
curl -s -X POST -H 'Authorization: Bearer aivo_sk_...' \
-H 'Content-Type: application/json' \
'https://aivo.bz/api/v1/messages' \
-d '{
"to": "+5016001234",
"body": "Your appointment is confirmed for tomorrow at 10:00 AM.",
"type": "sms"
}'{
"data": {
"id": "msg_abc123",
"to": "+5016001234",
"from": "+5012279446",
"body": "Your appointment is confirmed for tomorrow at 10:00 AM.",
"type": "sms",
"status": "queued",
"direction": "outbound",
"createdAt": "2026-04-01T14:30:00Z"
}
}To send MMS (multimedia messages), include a mediaUrl field:
curl -s -X POST -H 'Authorization: Bearer aivo_sk_...' \
-H 'Content-Type: application/json' \
'https://aivo.bz/api/v1/messages' \
-d '{
"to": "+5016001234",
"body": "Here is your receipt",
"type": "mms",
"mediaUrl": "https://aivo.bz/receipts/inv-001.pdf"
}'Retrieve message history with optional filters:
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/messages?direction=inbound&limit=20'Message statuses: queued → sent → delivered (or failed). Inbound messages trigger the message.received webhook event.
Manage the articles that train your AI voice agent.
curl -s -X POST -H 'Authorization: Bearer aivo_sk_...' \
-H 'Content-Type: application/json' \
'https://aivo.bz/api/v1/knowledge' \
-d '{
"title": "Business Hours",
"content": "We are open Monday through Friday, 8am to 5pm. Closed on weekends and public holidays.",
"type": "faq"
}'Retrieve your business profile and settings.
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/business'{
"data": {
"name": "Casa Maya Restaurant",
"phone": "+5012279446",
"timezone": "America/Belize",
"plan": "professional",
"businessHours": {
"monday": { "open": "08:00", "close": "22:00" },
"tuesday": { "open": "08:00", "close": "22:00" }
}
}
}Real-time event notifications
Configure webhook URLs in your dashboard to receive HTTP POST callbacks when events occur in your account.
Available webhook events:
call.completed - Fired when a call endscall.missed - Fired when a call goes unansweredappointment.created - Fired when AIVO AI books an appointmentappointment.cancelled - Fired when an appointment is cancelledcontact.created - Fired when a new contact is createdmessage.received - Fired when an SMS/MMS is receivedPOST https://your-app.com/webhooks/aivo
Content-Type: application/json
X-AIVO-Signature: ed25519:<base64-signature>
X-AIVO-Timestamp: 1711699200
{
"event": "call.completed",
"timestamp": "2026-03-29T12:00:00Z",
"data": {
"id": "clx1abc...",
"direction": "inbound",
"from": "+5012279446",
"to": "+5012001234",
"durationSeconds": 142,
"status": "completed",
"summary": "Customer booked an appointment for Tuesday."
}
}Every webhook request includes an Ed25519 signature in the X-AIVO-Signature header. You should verify this signature to ensure the request originated from AIVO and was not tampered with.
Verification steps:
X-AIVO-Timestamp and X-AIVO-Signature headers from the requesttimestamp + "." + raw_bodyimport { verify } from "crypto";
function verifyWebhook(req: Request, publicKey: string): boolean {
const signature = req.headers.get("X-AIVO-Signature")?.replace("ed25519:", "");
const timestamp = req.headers.get("X-AIVO-Timestamp");
const body = await req.text();
if (!signature || !timestamp) return false;
// Check timestamp freshness (5 min window)
const age = Date.now() / 1000 - parseInt(timestamp);
if (Math.abs(age) > 300) return false;
// Verify Ed25519 signature
const payload = timestamp + "." + body;
return verify(
null,
Buffer.from(payload),
{ key: publicKey, format: "pem" },
Buffer.from(signature, "base64")
);
}Plan-based rate limits
Rate limits are enforced per API key. Higher plans get higher limits.
| Plan | Standard Requests | Bulk Operations |
|---|---|---|
| Starter | 60 req/min | 10 req/min |
| Professional | 100 req/min | 20 req/min |
| Enterprise | 500 req/min | 100 req/min |
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1711699260When rate limited, you'll receive a 429 Too Many Requests response with a Retry-After header indicating seconds until the limit resets.
All errors return a consistent JSON format with an error code and human-readable message:
{
"error": {
"code": "NOT_FOUND",
"message": "The requested resource was not found"
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Invalid parameters or malformed request body |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | API key lacks required scope |
| 404 | NOT_FOUND | Resource does not exist |
| 429 | RATE_LIMITED | Too many requests - see Retry-After header |
| 500 | INTERNAL_ERROR | Unexpected server error |
All list endpoints use cursor-based pagination. Response includes a meta object with pagination info:
{
"data": [...],
"meta": {
"cursor": "clx1abc...", // Pass as ?cursor= for next page
"hasMore": true // false when no more results
}
}# First page
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/calls?limit=20'
# Next page (use cursor from previous response)
curl -s -H 'Authorization: Bearer aivo_sk_...' \
'https://aivo.bz/api/v1/calls?limit=20&cursor=clx1abc...'