API Reference
All endpoints require Authorization: Bearer rtk_... unless noted. Auth endpoints (register, login) are unauthenticated.
POST /api/auth/register
Create an account. No auth required.
Request
{
"email": "you@company.com",
"password": "min_8_chars",
"companyName": "Your Company" // optional
}Response 201
{
"account": {
"id": "clx...",
"email": "you@company.com",
"companyName": "Your Company",
"status": "INACTIVE"
},
"apiKey": "rtk_abc123...",
"token": "eyJhbG...",
"checkoutUrl": "https://checkout.stripe.com/...",
"engineVoiceUrl": "https://engine.veevo.ai/voice"
}Account starts as INACTIVE. Open checkoutUrl to complete payment. The apiKey is shown only once — store it securely. Set your Twilio voice webhook to engineVoiceUrl.
POST /api/auth/login
Get a JWT token. No auth required.
Request
{
"email": "you@company.com",
"password": "your_password"
}Response 200
{
"token": "eyJhbG..."
}GET /api/account
Get account details, status, and resource counts.
Response 200
{
"account": {
"id": "clx...",
"email": "you@company.com",
"companyName": "Your Company",
"status": "ACTIVE",
"createdAt": "2026-04-01T...",
"_count": {
"phoneNumbers": 2,
"apiKeys": 1
}
}
}POST /api/api-keys
Create an additional API key.
Request
{
"label": "Production" // optional
}Response 201
{
"id": "clx...",
"key": "rtk_newkey...",
"keyPrefix": "rtk_new",
"label": "Production",
"createdAt": "2026-04-01T..."
}The full key is shown only once. Store it securely.
GET /api/api-keys
List all active API keys. Only prefixes are returned, not full keys.
Response 200
{
"apiKeys": [
{
"id": "clx...",
"keyPrefix": "rtk_abc",
"label": "Default",
"lastUsedAt": "2026-04-05T...",
"createdAt": "2026-04-01T..."
}
]
}DELETE /api/api-keys/:id
Revoke an API key. It will immediately stop working.
Response 200
{
"revoked": true
}POST /api/phone-numbers
Register a phone number with callback URLs. Must be US E.164 format. Callback URLs must be public HTTPS endpoints.
Request
{
"phoneNumber": "+15551234567",
"onCallStartUrl": "https://your-backend.com/calls/start",
"onCallEndUrl": "https://your-backend.com/calls/end",
"onErrorUrl": "https://your-backend.com/calls/error" // optional
}Response 201
{
"phoneNumber": {
"id": "clx...",
"phoneNumber": "+15551234567",
"onCallStartUrl": "https://your-backend.com/calls/start",
"onCallEndUrl": "https://your-backend.com/calls/end",
"onErrorUrl": null,
"isActive": true,
"createdAt": "2026-04-01T..."
}
}GET /api/phone-numbers
List all registered phone numbers.
Response 200
{
"phoneNumbers": [ ... ]
}DELETE /api/phone-numbers/:id
Remove a registered phone number.
Response 200
{
"deleted": true
}POST /api/outbound
Initiate an outbound call. The from number must be registered to your account.
Request
{
"to": "+15559876543",
"from": "+15551234567",
"onCallStartUrl": "https://your-backend.com/calls/start",
"onCallEndUrl": "https://your-backend.com/calls/end",
"twilioAccountSid": "AC...",
"twilioAuthToken": "...",
"onErrorUrl": "https://your-backend.com/calls/error", // optional
"metadata": { "customerId": "cust_123" }, // optional
"machineDetection": "Enable", // optional: "Enable" | "DetectMessageEnd"
"timeout": 30 // optional: 5-120, default 30
}Response 201
Returns the engine response (call SID and status).
GET /api/usage
Get call history with cost breakdowns.
| Query Param | Type | Default | Description |
|---|---|---|---|
| limit | number | 50 | Max 100 |
| offset | number | 0 | Pagination offset |
Response 200
{
"records": [
{
"id": "clx...",
"callSid": "CA...",
"callerPhone": "+19805551234",
"calledNumber": "+15551234567",
"durationSeconds": 47,
"costBreakdown": { "totalCost": 0.018 },
"createdAt": "2026-04-05T..."
}
],
"total": 142,
"limit": 50,
"offset": 0
}GET /api/usage/current
Current month and all-time usage summary.
Response 200
{
"currentMonth": {
"calls": 23,
"minutes": 47,
"estimatedCost": 2.35
},
"allTime": {
"calls": 142,
"minutes": 310
},
"perMinuteRate": 0.05,
"monthlyBase": 5
}POST /api/billing/portal
Get a Stripe Billing Portal URL to manage subscription, payment method, and invoices.
Response 200
{
"url": "https://billing.stripe.com/p/session/..."
}GET /api/billing/subscription
Get subscription status, pricing, and usage totals.
Response 200
{
"status": "ACTIVE",
"monthlyBase": 5,
"perMinuteRate": 0.05,
"totalCalls": 142,
"totalMinutes": 310,
"hasPaymentMethod": true
}Error Codes
| Code | Meaning |
|---|---|
400 | Invalid request body or callback URL |
401 | Missing or invalid API key / credentials |
402 | Payment required — complete Stripe Checkout |
403 | Account suspended or phone number not owned |
404 | Resource not found |
409 | Phone number already registered by another account |
500 | Internal server error |