Supafone Labs ยท Documentation

๐ŸŽ›๏ธ BYOK Providers#

BYOK means "bring your own keys." It is powerful, but it should not be the default path. The default path is Supafone-managed infrastructure with one Supafone key.

Managed First#

json
{
  "labs": {
    "enabled": true,
    "mode": "supafone_managed",
    "managedInfrastructure": true,
    "model": "gemma"
  },
  "telephony": {
    "mode": "supafone_managed",
    "provider": "supafone"
  }
}

Use this when the developer wants to launch quickly and bill usage through Supafone.

Independent provider domains#

Do not collapse BYOK into one generic "provider keys" bucket. Hosted delivery has three independent provisioning lanes; Watcher deployments add independent STT and supervisor-LLM credentials:

LaneWhat it meansCommon providers
Agent/provider stackThe realtime agent, orchestration, or model runtime the customer already runsAny of the 14 audited runtime adapters
TelephonyThe carrier, trunk, SIP, and phone-network layerTwilio, Telnyx, Plivo, SignalWire, SIP/custom trunks
TTSThe voice-rendering providerCartesia, ElevenLabs, Inworld, Deepgram, custom TTS
STTThe transcript and language-authority providerDeepgram or provider-native streams
Supervisor LLMThe model that forms Watcher directivesSupafone hosted, Anthropic, OpenAI, xAI, custom LLM

These are five independent credential lanes. A key in one lane never satisfies another lane, even when the same vendor appears in both. Each domain can be managed by Supafone or brought by the customer. For example, a customer can bring Telnyx telephony and Cartesia TTS while still using Supafone's managed watcher, or bring an entire Ultravox stack and use Supafone only for self-healing directives and logs.

Native / BYOK Ultravox Runtime#

The hosted-agent runtime โ€” where Supafone actually places and monitors the call โ€” runs on Ultravox. By default it uses Supafone's managed platform key (managed billing). You can instead run agents on your own Ultravox account: your key, your billing. The agent is then both placed and monitored on your key, and runtime_mode becomes "byok". Managed remains the default.

Two ways to connect it:

1. At agent create, in the byok block:

json
{
  "byok": {
    "ultravox": {
      "api_key": "uvx_...",
      "base_url": "https://api.ultravox.ai/api"
    }
  }
}

base_url is optional. A byok.credentials object is also accepted as the key holder. The key is stored encrypted on your account, never in the agent doc.

2. Later or standalone, via PUT /api/v1/labs/runtime:

bash
curl https://api.supafone.ai/api/v1/labs/runtime \
  -X PUT \
  -H "Authorization: Bearer $SUPAFONE_LABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "ultravox",
    "credentials": { "api_key": "uvx_...", "base_url": "https://api.ultravox.ai/api" }
  }'

A blank api_key keeps the stored key, so you can re-save other fields. A non-ultravox provider returns 400 "coming soon" โ€” Ultravox is the only runtime today, managed or BYOK. GET /api/v1/labs/runtime returns the same status shape:

json
{
  "account_id": "...",
  "provider": "ultravox",
  "managed": false,
  "byok_connected": true,
  "base_url": "https://api.ultravox.ai/api",
  "updated_at": "2026-07-11T00:00:00Z"
}

This runtime lane is distinct from the watcher provider keys below: those bring your own STT/LLM/TTS for supervision, while this runs the agent itself on your Ultravox account. See Hosted Agents API for the full create/runtime contract and the runtime block returned on agent create.

The SDK's fourteen audited adapters describe event parsing and action compilation for customer-owned runtimes. They do not imply fourteen hosted runtime choices. Supafone-hosted Agent Factory execution currently supports Ultravox only (managed or Ultravox BYOK); other adapters run in the developer's provider/framework environment unless a later hosted contract explicitly says otherwise.

BYOK Watcher Providers#

json
{
  "labs": {
    "enabled": true,
    "mode": "byok",
    "managedInfrastructure": false,
    "stt": { "provider": "deepgram", "model": "nova-3" },
    "llm": { "provider": "openai", "model": "gpt-4.1-mini" },
    "tts": { "provider": "elevenlabs" }
  },
  "byok": {
    "llm": { "provider": "openai", "apiKey": "$OPENAI_API_KEY" },
    "stt": { "provider": "deepgram", "apiKey": "$DEEPGRAM_API_KEY" },
    "tts": { "provider": "elevenlabs", "apiKey": "$ELEVENLABS_API_KEY" }
  }
}

Supported agent/provider-stack fields include:

ProviderField
UltravoxultravoxApiKey
RetellretellApiKey
VapivapiApiKey
BlandblandApiKey
LiveKitlivekitApiKey, livekitApiSecret
PipecatpipecatApiKey
OpenAI RealtimeopenaiApiKey
Grok/xAIxaiApiKey
Gemini LivegeminiApiKey or Google Cloud credentials
Inworld RealtimeinworldApiKey

Supported TTS/STT fields include:

ProviderField
DeepgramdeepgramApiKey
CartesiacartesiaApiKey
ElevenLabselevenlabsApiKey
InworldinworldApiKey

BYOK Telephony#

ts
await supafone.labs.telephony.configure({
  mode: "byok",
  provider: "twilio",
  credentials: {
    accountSid: process.env.TWILIO_ACCOUNT_SID!,
    apiKey: process.env.TWILIO_API_KEY_SID!,
    apiSecret: process.env.TWILIO_API_KEY_SECRET!,
    fromNumber: "+14155550123"
  }
});

The telephony BYOK provider can be twilio, telnyx, plivo, sip, or any provider label the hosted API supports for that account. The UI should show the common carriers but the SDK should pass through custom provider labels.

Common carrier credential fields:

ProviderCommon fields
TwilioaccountSid, authToken, apiKey, apiSecret, fromNumber
TelnyxapiKey, connectionId, fromNumber
PlivoauthId, authToken, fromNumber
SignalWireprojectId, token, signalwireSpaceUrl, fromNumber
SIP/customsipTrunkUri, sipHost, username, password, headers

Custom SIP:

ts
await supafone.labs.telephony.configure({
  mode: "byok",
  provider: "sip",
  customSip: {
    sipTrunkUri: process.env.SIP_TRUNK_URI!,
    username: process.env.SIP_USERNAME!,
    password: process.env.SIP_PASSWORD!,
    headers: { "X-Customer": "northline" }
  }
});

UI Credential Rules#

Good exported code:

ts
byok: {
  agentProvider: {
    provider: "ultravox",
    apiKey: process.env.ULTRAVOX_API_KEY!
  },
  telephony: {
    mode: "byok",
    provider: "telnyx",
    credentials: { apiKey: process.env.TELNYX_API_KEY! }
  },
  tts: {
    provider: "cartesia",
    apiKey: process.env.CARTESIA_API_KEY!
  }
}

Bad exported code:

ts
providerKeys: {
  cartesiaApiKey: "real-secret-here"
}

When BYOK Is Worth It#

Use BYOK when the customer:

Otherwise, use Supafone-managed.

View raw Markdown