Supafone Labs ยท Documentation
Documentation menu

Pricing and Credits#

Labs Cloud uses a prepaid minute ledger. One Supafone minute covers hosted agent runtime, Supafone Supervisor work, managed model/TTS/STT access, logs, QA, and optimizer reports.

Pricing data is exposed publicly:

bash
curl https://api.labs.supafone.ai/v1/pricing

Plans#

PlanPriceIncluded minutesOverageIncluded numbers
Developer$49/mo300$0.14/min0
Growth$249/mo2,500$0.11/min3
Scale$999/mo12,000$0.085/min20

The trial signup grants five managed-runtime minutes to the account, not five minutes per API key, agent, device, or process. Browser WebRTC, PSTN, SDK, CLI, and MCP calls that use Supafone-managed infrastructure debit the same account ledger.

Before a managed call starts, Supafone atomically reserves that call's allowed runtime from the account balance. Concurrent calls therefore cannot each spend the same remaining seconds. When a call ends, Supafone settles the connected seconds and refunds the unused reservation. A provider failure cancels the reservation; expired abandoned reservations are reclaimed. The balance response may include active_reserved_seconds so clients can distinguish spendable time from time held by calls already starting or in progress.

What a recording costs#

Supafone does not add a second fee just because a call is recorded. Hosted calls debit the connected voice-agent runtime from the minute ledger. The recording artifact is included. Transcription, supervisor/Supafone Supervisor work, QA, and longer-term storage remain separate internal meters so usage and margins stay auditable; the customer still sees one clear Supafone balance.

Usage Meters#

MeterUnitNotes
agent_minuteminuteLive hosted voice-agent runtime
self_healingsecondSupervisor, QA, optimizer, and silent-guidance work
ttsspoken secondHosted voice output
sttaudio secondPrerecorded and live transcription
shared_number_poolpooled routeDefault shared Supafone number pool
managed_numbernumber-monthDedicated Supafone-managed phone number
premium_numbernumber-month$3/month premium number

Balance#

bash
curl https://api.labs.supafone.ai/v1/billing/balance \
  -H "Authorization: Bearer $SUPAFONE_LABS_API_KEY"

Response shape:

json
{
  "plan": "growth",
  "seconds_remaining": 150000,
  "minutes_remaining": 2500,
  "top_up": {
    "developer": "https://...",
    "growth": "https://...",
    "scale": "https://...",
    "pricing": "/v1/pricing"
  }
}

Hosted Stripe Checkout#

The SDK and MCP create Checkout Sessions on the server, so a secret Stripe key never enters a client application or model context:

python
checkout = client.labs.billing.checkout(
    kind="plan",
    plan_key="growth",
)
print(checkout["checkout_url"])

After payment, poll client.labs.billing.status(checkout_session_id). Use client.labs.billing.portal() to return an authenticated Stripe Customer Portal link for payment methods, invoices, and cancellation. Stripe webhook events are signature-verified and deduplicated before credits or entitlements are granted.

Structured 402 Payment Flow#

When the account cannot reserve another managed call, the API returns HTTP 402 Payment Required before opening a provider session:

json
{
  "detail": {
    "code": "managed_minutes_exhausted",
    "message": "Add managed minutes to start this call.",
    "minutes_remaining": 0,
    "checkout_endpoint": "/v1/billing/checkout"
  }
}

Treat detail.code, not the English message, as the programmatic branch. Create a server-authored Checkout Session through POST /v1/billing/checkout, open the returned checkout_url, and poll GET /v1/billing/checkout/{session_id} until it reports paid. Then retry the original call request. Do not retry a 402 in a tight loop and do not collect card data yourself.

The public clients expose the same flow:

ts
const checkout = await supafone.labs.billing.checkout({
  sku: "sf_voice_minutes_400_v1"
});
console.log(checkout.checkout_url);
python
checkout = supafone.labs.billing.checkout(sku="sf_voice_minutes_400_v1")
print(checkout["checkout_url"])
bash
supafone account checkout --sku sf_voice_minutes_400_v1

The CLI also recognizes a structured 402, requests a Checkout link, and returns it under data.payment while preserving the original error status and usage detail. MCP uses start_billing_checkout followed by get_billing_checkout.

Stripe Checkout Metadata#

Stripe grants are controlled by checkout metadata:

json
{
  "plan_key": "developer",
  "included_minutes": "300",
  "credits_minutes": "400"
}

Rules:

Number Billing#

The safe default is the shared pool:

json
{
  "default_strategy": "default_pool",
  "default_pool_price_monthly": 0
}

Dedicated and premium numbers are paid number-month choices:

json
{
  "dedicated_number_price_monthly": 3,
  "premium_number_price_monthly": 3
}

Product flows should make number purchases explicit. Do not silently upgrade a shared-pool user to a dedicated or premium number.

For SDK and MCP callers, the first paid-number request returns a hosted checkout_url. After Stripe reports paid, repeat the purchase with the billing_checkout_session_id. Supafone claims the single-use entitlement, provisions the carrier number, then consumes the entitlement. A retry returns the already-provisioned number rather than buying another one.

View raw Markdown