Developers

API Reference

Full REST API for agents, calls, campaigns, and analytics. Authenticate with your workspace API key.


Base URL and auth

bash
https://api.katexs.com/v1

Authorization: Bearer <KATEXS_API_KEY>

Endpoints

MethodPathDescription
GET/agentsList agents
POST/agentsCreate an agent
GET/agents/:id/callsList calls for one agent
GET/callsList calls with filters
POST/callsCreate one outbound call
GET/calls/:idFetch a transcript and outcome
GET/phone-numbersList phone numbers
POST/phone-numbersCreate or import a phone number
GET/phone-numbers/:idGet one phone number
PATCH/phone-numbers/:idUpdate label/status/assistant assignment
GET/providersList available model/voice providers
GET/modelsList model catalog (optional provider filter)
GET/voicesList voices (supports live ElevenLabs mode)
POST/campaignsCreate a campaign
GET/campaigns/:idRead one campaign
PATCH/campaigns/:idUpdate campaign fields
POST/campaigns/:id/actionsStart, pause, resume, or complete
POST/campaigns/:id/dispatchDispatch queued targets now
POST/campaigns/:id/callsCreate one campaign call now
GET/campaigns/:id/callsList campaign call logs
GET/campaigns/:id/targetsList campaign targets
POST/campaigns/:id/targetsUpsert targets via JSON or CSV

Campaign target import (JSON and CSV)

bash
curl -X POST https://api.katexs.com/v1/campaigns/cmp_123/targets \
  -H "Authorization: Bearer $KATEXS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "targets": [
      {
        "phone": "+14155550123",
        "first_name": "Ava",
        "variables": { "city": "Austin", "lead_score": 92 }
      }
    ]
  }'
bash
curl -X POST https://api.katexs.com/v1/campaigns/cmp_123/targets \
  -H "Authorization: Bearer $KATEXS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "csv": "phone,first_name,last_name,timezone,lead_source\n+"+14155550123","Ava","Lopez","America/Chicago","web"",
    "column_map": {
      "phone": "phone",
      "first_name": "first_name",
      "last_name": "last_name",
      "timezone": "timezone",
      "variables": {
        "source": "lead_source"
      }
    }
  }'

CSV parsing supports quoted values, escaped quotes, embedded commas, and embedded newlines. Unknown columns are added to variables automatically unless mapped to a reserved field.

Campaign dispatch

bash
curl -X POST https://api.katexs.com/v1/campaigns/cmp_123/dispatch \
  -H "Authorization: Bearer $KATEXS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "max_calls": 5 }'
json
{
  "campaign_id": "cmp_123",
  "requested": 5,
  "dispatched": 3,
  "retried": 1,
  "failed": 0,
  "attempted": 4,
  "active_calls": 2,
  "concurrency_limit": 10,
  "call_ids": ["vapi_call_1", "vapi_call_2", "vapi_call_3"],
  "target_ids": ["tgt_1", "tgt_2", "tgt_3", "tgt_4"]
}

Automated scheduler trigger (internal)

Use an external scheduler (GitHub Actions, Cloud Scheduler, cron-job.org, etc.) to call the internal dispatch endpoint every minute.

bash
curl -X POST https://api.katexs.com/api/internal/campaigns/dispatch \
  -H "x-cron-secret: $INTERNAL_CRON_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "max_campaigns": 25, "max_calls_per_campaign": 5 }'
Set INTERNAL_CRON_SECRET in your runtime and send the same value in x-cron-secret (or Authorization: Bearer). The route rejects unauthenticated requests.

Manual outcome override webhook (ops)

When human operators need to force a target result, send a signed request to the webhook-safe endpoint.

bash
curl -X POST https://api.katexs.com/api/public/campaign-targets/outcome \
  -H "Content-Type: application/json" \
  -H "x-webhook-timestamp: <unix-seconds>" \
  -H "x-webhook-signature: <hex-or-base64-hmac>" \
  -d '{
    "target_id": "tgt_123",
    "status": "retry",
    "reason": "Carrier congestion, retrying in 2h",
    "next_attempt_at": "2026-08-13T17:00:00.000Z"
  }'

Signature format: compute HMAC-SHA256 over `${timestamp}.${rawBody}` (or rawBody when no timestamp is sent), using OPS_WEBHOOK_SECRET or MANUAL_OPS_WEBHOOK_SECRET. Send digest as hex or base64 in x-webhook-signature.

FieldTypeNotes
target_idstringRequired campaign target id
statusenumcompleted, failed, do_not_call, retry, queued
reasonstringOptional audit note stored as last_error
next_attempt_atISO timestampOptional; only used for retry status

End-to-end workflow

  1. 1

    Import targets

    Upsert campaign targets using JSON or CSV with optional column_map.

  2. 2

    Activate campaign

    Set campaign status to active with POST /campaigns/:id/actions.

  3. 3

    Auto-dispatch

    Scheduler calls /api/internal/campaigns/dispatch every minute within concurrency limits.

  4. 4

    Webhook completion

    Vapi webhook marks target status, schedules retry for transient failures, and recomputes campaign progress.

  5. 5

    Manual ops override

    If needed, signed override webhook forces final target status and updates campaign metrics.

Create an agent

bash
curl -X POST https://api.katexs.com/v1/agents \
  -H "Authorization: Bearer $KATEXS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Front Desk",
    "type": "voice",
    "voice_id": "elevenlabs:rachel",
    "prompt": "You are the receptionist for Bright Dental...",
    "tools": ["check_calendar", "book_appointment"]
  }'

Errors and limits

StatusMeaning
400Validation error โ€” see the details array
401Missing or invalid API key
403API key is valid but missing the required scope
409Resource state conflict (for example unsynced assistant/number)
429Rate limit, quota, or concurrency limit reached
5xxRetry with exponential backoff