voepy

Voepy Developer Docs

Build voice into your product with one HTTP API. Buy phone numbers, place and receive calls, record audio, stream media in real time, run IVR menus, and get charged per second of actual usage.

This is the customer-facing guide set. Pick a topic and start there; each page is standalone and links to the next logical step.

Start here

GuideWhat you'll learn
Getting startedSign up, grab your API key, place your first outbound call in under five minutes.
Phone numbersSearch the inventory, buy a DID, configure it for voice or messaging, release when done.
CallsPlace outbound calls, accept inbound, control live audio (transfer, bridge, record, IVR menus, real-time transcription, AMD).
WebhooksSubscribe to call events, verify the signature, handle retries and dedup.
BillingTop up your balance, set up auto-recharge, manage payment methods, download invoices.
Error referenceEvery error code the API can return and what to do about each one.

Conventions

  • JSON in, JSON out. All request and response bodies are JSON. Field names are snake_case.
  • Phone numbers are always E.164. Format: + followed by 6–15 digits. Example: +15125550100. No spaces, no dashes.
  • Money is in cents. A $25.00 top-up is amount_cents: 2500. Currency is USD only at launch.
  • IDs are opaque, prefixed strings. A call is voepy_call_01H…, a leg is voepy_leg_…, a recording is voepy_rec_…, a route is voepy_route_…. Treat them as strings.
  • Timestamps are ISO-8601 with timezone. Example: 2026-05-12T14:32:18.000Z.
  • Idempotency: every mutating endpoint accepts an Idempotency-Key header. Retrying with the same key returns the original response instead of executing twice. Use a UUID per logical operation.
  • Pagination: list endpoints take cursor and limit query parameters. The response includes next_cursor (null on the last page). Do not parse the cursor — opaque by design.

Authentication

Every request needs your API key in the Authorization header:

Authorization: Bearer voepy_live_<your-key>

You receive the plaintext key exactly once at signup. Lose it and you'll have to rotate. See Getting started.

Two things to know:

  1. API keys are tenant-scoped. They identify your account and carry the right scopes (e.g. calls:write, billing:read).
  2. Never expose your key in browser code. Treat it like a password. Server-side only. If you need a browser to call us, proxy through your own backend.

Errors

Every 4xx and 5xx response has the same shape:

{
  "error": {
    "code": "balance_insufficient",
    "message": "Tenant balance is exhausted; top up to place new calls."
  }
}

The HTTP status mirrors the category (400/401/402/403/404/409/422/429/ 5xx). Full table in Error reference.

Where to ask for help

  • Bug reports / feature requests: open a ticket in your dashboard.
  • Live integration support during onboarding: your account contact.