Skip to main content

Documentation Index

Fetch the complete documentation index at: https://katavenai.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Two-step model:
  1. Provider credentials — the API keys for your carrier (Twilio, Plivo, Vobiz). Stored encrypted via the Secret Encryptor service; never returned in plaintext.
  2. Phone numbers — individual E.164 numbers that reference one provider credential and (optionally) pin to one agent.

Providers

Today supported: twilio, plivo, vobiz.

Required credentials JSON

ProviderRequired keys
twilioaccount_sid, auth_token
plivoauth_id, auth_token
vobizauth_id, auth_token
client.telephony.create_provider(
    provider="twilio",
    label="Production Twilio",
    credentials={
        "account_sid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "auth_token": "your_auth_token",
    },
)
The handler validates the JSON shape before accepting it — pasting half a config gets a 400 immediately, not a runtime failure on the first call. A provider with phone numbers attached can’t be deleted (409); you have to remove the numbers first.

Phone numbers

client.telephony.create_number(
    e164="+12025550123",
    provider="twilio",
    credentials_id="<provider uuid>",
    agent_id="<agent uuid>",   # optional — pins the number to one agent
    inbound_enabled=True,
    outbound_enabled=True,
)
e164 is sanity-checked locally (+ + 7–15 digits). The carrier rejects malformed numbers downstream regardless. Reassign a number to a different agent:
client.telephony.update_number(number_id, agent_id="<new agent>")
Or detach it (set agent_id=None).

Outbound origination

POST /api/v1/calls/originate — dispatches an outbound call. Pipeline:
  1. JWT auth (route middleware).
  2. Caller-ID ownershipfrom_number must be a tenant-owned, outbound_enabled number.
  3. Cost caps — concurrent / per-minute / daily / daily-minute counters in Redis. Exceeded cap → 429.
  4. Decrypt credentials via Secret Encryptor.
  5. POST to Call Processor /telephony/originate.
  6. On success, INCR Redis counters.
result = client.calls.originate(
    from_number="+12025550123",
    to_number="+14155550100",
    agent_id="<agent uuid>",
)
print(result["provider_call_id"], result["session_id"])
The session_id lets you deep-link to the conversation viewer while the call is still in progress.

Cost caps

Each tenant has a per-account row controlling the four cap dimensions:
FieldMeaning
concurrent_maxHard ceiling on simultaneous calls.
calls_per_minuteBurst limit.
daily_calls_maxPer-day budget (rolling UTC midnight).
daily_minutes_maxPer-day talk-time budget.
client.call_limits.update(
    concurrent_max=20,
    calls_per_minute=10,
    daily_calls_max=1000,
    daily_minutes_max=2400,
)
Set any field to 0 to block all of that dimension — useful as a kill-switch during an incident.