Sowa API Documentation
REST API for Sowa Answers. Provision numbers, list calls, and receive call-completed webhooks.
Authentication
Include your API key in the Authorization header:
Authorization: Bearer lsk_live_xxx
Create API keys in Dashboard → API Keys.
Base URL
https://sowaanswers.com/api/v1
Endpoints
POST /numbers
Provision a number and configure call handling. Requires webhook_url (HTTPS).
// Request
{
"business_name": "Acme Plumbing",
"webhook_url": "https://your-app.com/webhooks/Sowa",
"booking_link": "https://acme.com/book",
"forward_to": "+1234567890"
}
// Response
{
"data": {
"id": "num_xxx",
"phone_number": "+15875347708",
"status": "active",
"webhook_url": "https://your-app.com/webhooks/Sowa"
}
}GET /numbers
List numbers provisioned for this API key.
// Response
{
"data": [
{
"id": "num_xxx",
"phone_number": "+15875347708",
"status": "active",
"webhook_url": "https://your-app.com/webhooks/Sowa",
"created_at": "2025-03-01T12:00:00Z"
}
]
}GET /numbers/:id
Get a single number by ID.
DELETE /numbers/:id
Release a number from this API key. Returns { "data": { "deleted": true } }.
GET /calls
List calls. Query params: limit (default 20, max 100), offset.
// Response
{
"data": [
{
"id": "call_xxx",
"phone_number": "+15551234567",
"timestamp": "2025-03-01T14:30:00Z",
"duration_seconds": 45,
"intent_summary": "Customer needs same-day plumbing repair"
}
],
"meta": { "total": 150, "limit": 20, "offset": 0 }
}GET /calls/:id
Fetch a single call with full transcript and intent.
// Response
{
"data": {
"id": "call_xxx",
"phone_number": "+15551234567",
"timestamp": "2025-03-01T14:30:00Z",
"duration_seconds": 45,
"intent": {
"summary": "Customer needs same-day plumbing repair",
"urgency": "high",
"requested_action": "schedule_visit",
"extracted_data": {}
},
"transcript": "Full transcript text..."
}
}POST /calls/:id/follow-up
Send SMS follow-up to the caller. Optional body: { "message": "Custom text" } (max 1600 chars). Omit for default thanks + booking link.
// Response
{
"data": { "sent": true }
}Webhooks
When a call completes, we POST to your webhook_url with:
{
"event": "call.completed",
"id": "call_xxx",
"phone_number": "+15551234567",
"timestamp": "2025-03-01T14:30:00Z",
"duration_seconds": 45,
"intent": {
"summary": "Customer needs same-day plumbing repair",
"urgency": "high",
"requested_action": "schedule_visit",
"extracted_data": {}
},
"transcript": "Full transcript..."
}We include X-Sowa-Signature (HMAC-SHA256 of the body). Verify it using Sowa_WEBHOOK_SECRET (contact support for the secret). Respond with 200 within 10 seconds. We retry up to 3 times on failure.
Quick start
Provision a number:
curl -X POST https://sowaanswers.com/api/v1/numbers \
-H "Authorization: Bearer lsk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"webhook_url":"https://your-app.com/webhooks/Sowa","business_name":"Acme"}'List numbers:
curl -X GET "https://sowaanswers.com/api/v1/numbers" \ -H "Authorization: Bearer lsk_live_YOUR_KEY"
List calls:
curl -X GET "https://sowaanswers.com/api/v1/calls?limit=20" \ -H "Authorization: Bearer lsk_live_YOUR_KEY"
Send follow-up SMS to a caller:
curl -X POST "https://sowaanswers.com/api/v1/calls/call_xxx/follow-up" \
-H "Authorization: Bearer lsk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"Thanks for calling! Book here: https://acme.com/book"}'Error responses
Errors use a consistent format:
{
"error": {
"code": "invalid_request",
"message": "Missing required field: webhook_url"
}
}HTTP codes: 400 (validation), 401 (invalid key), 403 (forbidden), 404 (not found), 429 (rate limit), 500 (server error).