VoixCall

VoixCall for developers

Changelog

Dated entries, each tagged additive or breaking. Subscribe by RSS to hear about new endpoints, tools and deprecations.

RSS feed

How to read this page

  • additive New endpoints, tools, fields or enum values. Clients must tolerate unknown fields and values, so these never need action.
  • breaking A behaviour change. It ships under a new dated VoixCall-Version; existing keys and connections stay pinned to the version they were created with until you upgrade them. The old version then gets Deprecation and Sunset headers and, after the sunset date, answers 410 version_sunset with a migration link.

Current API version: 2026-10-01. No version is deprecated.

Call summaries, transcripts and text messages (phase 4) additive

Connected apps can read call summaries and transcripts, and text messages on numbers the user opts in, each behind a sharing switch the user turns on in Settings → Connected apps (both off by default). Transcript text is redacted before it leaves VoixCall. New scopes are offered: transcripts:read, messages:read and messages:history.

  • GET /v1/calls/{id}/transcript (transcripts:read): the transcript object with summary, action_items, reference_numbers, language, duration_seconds, completed_at and status (pending, processing, completed, failed, expired). include=utterances adds the speaker-by-speaker transcript, paged under the 32 KB cap with next_utterance_offset and utterance_offset. Errors: call_not_found, transcript_not_found (the message says whether one can be requested and its price).
  • POST /v1/calls/{id}/transcript (transcripts:read and calls:place, Idempotency-Key required): requests a transcript of a recorded call through the same pipeline as the app's Transcribe button; 202 with status pending and cost {amount, currency} (the transcription rate per started minute, charged only when it completes). Errors: insufficient_credits (402, with billing_url), call_too_short (402), transcript_exists, transcription_in_progress, recording_unavailable (409). Budget: 5 requests a minute.
  • GET /v1/calls/{id}?expand[]=transcript now returns the redacted summary-level transcript. The 403 summaries_not_enabled answer is replaced by 403 not_enabled with a settings_url, returned only while the user's “Allow connected apps to read call summaries” switch is off.
  • Redaction: utterances are shared with every number (digits or spelled out) and keypad (DTMF) entry replaced by [redacted]. The summary, each action item and each reference number (label and value together) have every number replaced when the item holds six or more digits in total (number words in English, Hindi, Spanish, French, German, Portuguese and Italian count, and so do digits in other scripts), or a word such as code, OTP, PIN, password, card or account (also recognised in Hindi, Spanish, French, German, Portuguese, Italian, Turkish, Russian, Chinese, Japanese and Korean); otherwise its short numbers stay readable. A wholly sensitive reference number stays in the list as [redacted].
  • GET /v1/messages?number= (messages:read): inbound text messages on a number the user opted in, from the last 10 minutes by default; window_minutes up to 60 needs messages:history. Bodies up to 500 bytes (body_truncated), picture links valid for 5 minutes. GET /v1/messages/threads?number= (messages:history) lists conversations with the most recent message of each, whatever its age. Errors: not_enabled (number not opted in, with settings_url), number_not_found, invalid_number, invalid_window. 10 reads a minute per number.
  • MCP: voixcall_get_call_summary (transcripts:read) returns the redacted summary, action items and reference numbers; it never requests a transcript and never returns utterances; not_enabled and not_available (with can_request and cost) are normal results. voixcall_read_messages (messages:read) reads recent messages on an opted-in number; its description tells the assistant never to forward codes.
  • Sharing switches: “Allow connected apps to read call summaries” (account) and “Allow connected apps to read messages on this number” (per number; turning it on needs the password again, or a fresh sign-in for Google and Apple accounts). A number's switch turns itself off when the number is released or leaves the account. Every read and request is written to the audit log with the app's identity; audit entries are deleted after 400 days.
  • scopes_supported adds transcripts:read, messages:read and messages:history. calls:place is still not advertised.

MCP read tools; claude.ai and ChatGPT connectors verified additive

The MCP server now has six read tools besides voixcall_whoami: rates, balance, contact search, call history, call details and numbers. Connecting from claude.ai custom connectors and from ChatGPT now works end to end and is verified against production.

  • New tools: voixcall_get_rate (rates:read), voixcall_get_balance (credits:read), voixcall_search_contacts (contacts:read), voixcall_list_calls and voixcall_get_call (calls:read), voixcall_list_numbers (numbers:read). All read-only, with titles, output schemas and a one-line spoken summary.
  • Each tool advertises its scope in tools/list _meta.securitySchemes. Calling a tool without its scope returns HTTP 403 with WWW-Authenticate: Bearer error="insufficient_scope", scope and resource_metadata, so clients can ask the user to allow it.
  • Argument errors are returned as isError tool results the model can correct; /mcp request bodies are capped at 64 KiB and results at 32 KB (long lists are trimmed with has_more).
  • OAuth: client metadata documents that list extra grant types (claude.ai) or prefer private_key_jwt while supporting none (ChatGPT) are accepted. The server remains public-client only with PKCE.

TypeScript SDK @voixcall/sdk 0.1.0 additive

The official TypeScript SDK is on npm: npm install @voixcall/sdk (Node 20 or later, ES module). It covers every live /v1 read endpoint with typed methods and handles authentication, pagination, retries and errors for you. No API change.

  • Install with npm install @voixcall/sdk. ES module with bundled types and no runtime dependencies; runs on Node 20 or later and in modern browsers. Package page: https://www.npmjs.com/package/@voixcall/sdk.
  • Authenticate with new VoixCall({ accessToken }) for an OAuth access token (vcat_) or new VoixCall({ apiKey }) for a personal key (vc_live_ / vc_test_), as a string or a function returning one.
  • Methods: me.get(), rates.get({ to }), credits.balance(), credits.transactions.list(), calls.list(), calls.get(id), contacts.search({ q }), numbers.list() and callerId.get(). Generated from the OpenAPI document and pinned to VoixCall-Version 2026-10-01.
  • Pagination: await a list for one page, or iterate it with for await to walk every page; toArray(n) and pages() are also available. Short pages caused by the 32 KB cap are followed correctly.
  • Retries 429 and 503 (and 502, 504 and network errors on GET only) up to twice by default, honouring Retry-After. Every POST gets an automatic Idempotency-Key that is reused across retries.
  • Typed errors: each failure is a VoixCallError subclass chosen by the error type (AuthenticationError, PermissionError, NotFoundError, RateLimitError with retryAfter, InvalidRequestError, APIError, APIConnectionError and others) with code, message, status, requestId and docUrl.
  • Money stays a decimal string with a currency, never a float. Like the API, the SDK reads the personal account only; organization data is never reachable.

Read endpoints: rates, credits, calls, contacts, numbers, caller ID additive

Eight read endpoints on /v1 for the connected personal account, each behind its read scope, and scopes_supported narrowed to the five scopes that now have a live operation. The MCP server still offers only voixcall_whoami; MCP read tools come next.

  • GET /v1/rates?to=<E.164> (rates:read): the per-minute rate the app quotes, billing_increment_seconds, destination_type and rate_basis. The rate actually charged is fixed at call setup and shown on the call. Errors: invalid_destination (400), destination_blocked (422), rate_unavailable (503).
  • GET /v1/credits/balance and GET /v1/credits/transactions (credits:read): balance with low_balance and billing_url; purchases, call and service charges, app-store refunds and the initial account credit. amount is the signed change to the balance: negative for deduction and refund, positive for purchase and addition.
  • GET /v1/calls (calls:read): call history filterable by direction, started_at[gte], started_at[lte] and to (invalid_filter on a bad filter). cost is null unless the call completed; counterparty_name only with contacts:read.
  • GET /v1/calls/{id} (calls:read): adds cost_so_far (only while active), max_duration_seconds (only while active and with credits:read) and transcript (always null). expand[]=transcript answers 403 summaries_not_enabled until the “Allow connected apps to read call summaries” setting ships; other expand values are invalid_expand; an unknown or foreign id is call_not_found.
  • GET /v1/contacts?q= (contacts:read): search by name, company or number fragment, 2 to 64 characters (invalid_query otherwise).
  • GET /v1/numbers and GET /v1/caller-id (numbers:read): virtual numbers (released ones excluded) with status, renewal_at and capabilities; the current caller ID, every selectable option and verified numbers.
  • Lists share one shape ({object: "list", data, has_more}), newest first, limit 1 to 100 (default 10), starting_after / ending_before cursors. A list response is capped at 32 KB, so a page can hold fewer than limit items with has_more true.
  • Money is a decimal string with a currency (amounts two decimals, per-minute rates four). Organization data is never included. Test keys (vc_test_) read a separate test partition: a 10.00 USD test balance, empty lists and a fixed rate of 0.0200 per minute for any valid number except the magic numbers +15005550001 (invalid_destination) and +15005550010 (destination_blocked).
  • scopes_supported in the authorization-server and protected-resource metadata is now exactly rates:read, credits:read, calls:read, contacts:read, numbers:read. calls:place, messages:read, messages:history, transcripts:read and webhooks:manage are not advertised until their features ship; explicit requests for them are still accepted, so existing grants keep working.

Public API and MCP server, phase 1 additive

The first public surface on api.voixcall.com: an OAuth 2.1 authorization server, the /v1/me endpoint, an MCP server with one tool, API-key management endpoints and rate limiting.

  • OAuth 2.1 authorization code flow with PKCE (S256) at https://api.voixcall.com/oauth/authorize and /oauth/token, with refresh-token rotation and RFC 7009 revocation at /oauth/revoke.
  • Client registration by Client ID Metadata Document (an https client_id that serves its own metadata) and by Dynamic Client Registration at /oauth/register.
  • Discovery: /.well-known/oauth-authorization-server and protected-resource metadata at /.well-known/oauth-protected-resource/v1 and /mcp.
  • GET /v1/me returns the connected account (object, id, email, display_name, country_code, time_zone, livemode). OpenAPI 3.1 at https://api.voixcall.com/v1/openapi.json.
  • MCP server at https://api.voixcall.com/mcp (Streamable HTTP, JSON responses, OAuth only) with the voixcall_whoami tool.
  • Personal API keys (vc_live_ and vc_test_): management endpoints under /v1/api-keys for signed-in dashboard sessions. The Settings screen to create keys ships later.
  • Rate limiting with RateLimit, RateLimit-Policy, X-RateLimit-* and Retry-After headers on rate-limited public responses.
  • Error envelope with type, code, message, param, doc_url and request_id; every doc_url points at https://voixcall.com/developers/errors.
  • VoixCall-Version header (current version 2026-10-01) echoed on every /v1 response.
  • Settings → Connected apps in the web app lists connected assistants and lets you disconnect them.