Voxiomni Developers
OpenAPI 3.1 Open app
API v1 · Production

Build on the Voxiomni voice platform.

Create and publish voice agents, purchase and manage phone numbers, retrieve calls and recordings, inspect quality audits, and receive signed events when processing finishes.

Base URLhttps://api.voxiomni.com/api/v1

Authentication

Create an API key in Settings → Development. Send it as a Bearer token on every request. A key belongs to one workspace and is shown only once when it is created.

Granular scopes

Grant only the permissions an integration needs. Scope checks are performed independently for every operation.

  • agents:readRead agents
  • agents:writeCreate and update agent drafts
  • agents:publishPublish agent drafts
  • phone_numbers:readRead phone numbers
  • phone_numbers:writeSearch, purchase, and release numbers
  • calls:readRead calls, transcripts, and analysis
  • recordings:readDownload recordings
  • quality:readRead quality audits
cURL
curl https://api.voxiomni.com/api/v1/agents \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY" \
  -H "Accept: application/json"
Keep keys server-side.

Never expose an API key in browser code, mobile applications, public repositories, logs, or support screenshots. Revoke a key immediately if it is disclosed.

Responses and errors

JSON properties use camelCase. Enum values returned by the API use lower camel case. Send Content-Type: application/json whenever a request has a JSON body.

Error response
{
  "code": "validation_error",
  "message": "Complete the required agent fields."
}
200Request succeeded
201Resource created
204Succeeded with no body
400Invalid input or query
401Missing, invalid, or revoked key
403Required scope is missing
404Resource not found
409State or ownership conflict
500Unexpected server error

Error codes

codeHTTP statusMeaning
validation_error400The request body, path, date range, or query is invalid.
unauthorized401The Bearer token is missing, malformed, invalid, or revoked.
forbidden403The key does not contain the required scope.
not_found404The resource does not exist in the key's workspace.
conflict409The state change cannot be completed, for example because a number is assigned.
internal_error500An unexpected error occurred.

Agents

Agent changes are saved as a draft. Creating or updating an agent does not make the draft live; call the publish operation after the draft is ready. Phone number associations are controlled by phoneNumberIds.

GET/agentsagents:read

List agents

Returns every agent in the authenticated workspace. No query parameters are accepted.

200 OKAgent[] — an array that may be empty.
Request
curl https://api.voxiomni.com/api/v1/agents \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"
Response example
[
  {
    "id": "agent_8d41f3d4f6324af2b77b3b183f923f4c",
    "name": "Collections assistant",
    "purpose": "Negotiate overdue invoices",
    "status": "active",
    "language": "Português (Brasil)",
    "voice": "Clara",
    "model": "advanced",
    "greeting": "Hello, may I speak with {{name}}?",
    "instructions": "Confirm identity before discussing an invoice.",
    "transferNumber": "+551130000000",
    "phoneNumberIds": ["pn_38a04ad5"],
    "phoneNumbers": ["+55 11 3000-0000"],
    "knowledgeSources": [],
    "toolIds": [],
    "structuredDataSources": [],
    "recording": { "enabled": true, "retentionDays": 30 },
    "advanced": { "responseStyle": "Balanced", "voiceExpressiveness": "Moderate", "inactivityTimeoutSeconds": 60, "interruptionSensitivity": "Medium" },
    "quality": { "enabled": false, "auditPercentage": 10, "criteria": [] },
    "published": true,
    "updatedAt": "2026-10-11T18:32:14Z"
  }
]
GET/agents/{agentId}agents:read

Retrieve an agent

Returns one agent from the authenticated workspace.

Path parameterTypeRequiredDescription
agentIdstringYesThe agent ID, such as agent_8d41....
Request
curl https://api.voxiomni.com/api/v1/agents/agent_8d41f3d4f6324af2b77b3b183f923f4c \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"

Errors: 401, 403, 404.

PUT/agents/{agentId}agents:write

Replace an agent draft

Replaces the draft configuration. This is a full update, not a patch: send every required field and every association that must remain. Omitting an optional collection clears it.

InputRequiredDescription
agentId path parameterYesID of the agent to update.
JSON bodyYesComplete Agent write object, using the same shape as POST /agents.
200 OKThe updated Agent response object. Production keeps using the previous published version until you publish again.
Request
curl -X PUT \
  https://api.voxiomni.com/api/v1/agents/agent_8d41f3d4f6324af2b77b3b183f923f4c \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY" \
  -H "Content-Type: application/json" \
  --data @agent.json

Errors: 400, 404, 409.

POST/agents/{agentId}/publishagents:publish

Publish an agent draft

Promotes the current draft to production and applies its phone number routing. This request has no body.

200 OKThe published Agent response object, with published: true.
Request
curl -X POST \
  https://api.voxiomni.com/api/v1/agents/agent_8d41f3d4f6324af2b77b3b183f923f4c/publish \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"

Errors: 404 if the agent does not exist; 409 if a selected number is no longer available.

Phone numbers

Search and purchase Voxiomni numbers, inspect workspace numbers, and release numbers that are no longer assigned. Custom routing configuration is not exposed in API v1.

GET/phone-numbersphone_numbers:read

List owned phone numbers

Returns all phone numbers owned by the workspace, sorted by number.

200 OKPhoneNumber[] — an array that may be empty.
Request
curl https://api.voxiomni.com/api/v1/phone-numbers \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"
Response example
[
  {
    "id": "pn_38a04ad5",
    "number": "+551130000000",
    "formatted": "+55 11 3000-0000",
    "locality": "São Paulo",
    "region": "SP",
    "country": "BR",
    "currency": "BRL",
    "monthlyPrice": 47.90,
    "status": "active",
    "agentId": "agent_8d41f3d4f6324af2b77b3b183f923f4c",
    "connectionType": "voxiomniNumber",
    "purchasedAt": "2026-10-11T18:32:14Z"
  }
]
GET/phone-numbers/availablephone_numbers:write

Search available phone numbers

Searches provider inventory. Use the returned id as providerNumberId when purchasing.

Query parameterTypeRequiredDescription
containsstringNoDigits or area code that should appear in the number.
200 OKPhoneNumber[] with status: "available".
Request
curl "https://api.voxiomni.com/api/v1/phone-numbers/available?contains=11" \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"
GET/phone-numbers/{phoneNumberId}phone_numbers:read

Retrieve a phone number

Returns one number owned by the authenticated workspace.

Path parameterTypeRequiredDescription
phoneNumberIdstringYesThe Voxiomni phone number ID, not the E.164 number.
200 OKA PhoneNumber object, using the fields in the purchase example.
Request
curl https://api.voxiomni.com/api/v1/phone-numbers/pn_38a04ad5 \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"

Errors: 404 if the number is not owned by the workspace.

DELETE/phone-numbers/{phoneNumberId}phone_numbers:write

Release a phone number

Permanently releases the number at the provider. Remove it from its agent, save the agent, and publish that agent before releasing the number.

204 No ContentNo response body.
Request
curl -X DELETE \
  https://api.voxiomni.com/api/v1/phone-numbers/pn_38a04ad5 \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"

Errors: 404 if it does not exist; 409 if still assigned.

Calls

Read calls and post-processing results. Calls are retained for 90 days. A request may cover at most 90 days; when dates are omitted, the API returns the latest 30-day window.

GET/calls/{callId}calls:read

Retrieve a call

Returns one call including recording state, transcription state, transcript, analysis, and quality state.

Path parameterTypeRequiredDescription
callIdstringYesThe Voxiomni call ID.
200 OKA complete Call object.
Request
curl https://api.voxiomni.com/api/v1/calls/call_748cfe8c \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY"

Errors: 404 when the call does not exist or passed retention.

GET/calls/{callId}/recordingrecordings:read

Download a call recording

Streams recording bytes. The response is not JSON. Use the response Content-Type to determine the format. HTTP range requests are supported.

200 OKBinary response body with the stored recording's media type.
Request
curl https://api.voxiomni.com/api/v1/calls/call_748cfe8c/recording \
  -H "Authorization: Bearer $VOXIOMNI_API_KEY" \
  --output recording.bin

Errors: 404 when the call or recording is absent, disabled, pending, or expired.

Quality audits

Read audits selected by each agent's quality sampling configuration. The API is read-only; reviewers complete or correct reviews in the Voxiomni app.

GET/quality-audits/{callId}quality:read

Retrieve a quality audit

Looks up an audit by call ID and returns the audit, associated transcript, and recording availability.

Path parameterTypeRequiredDescription
callIdstringYesThe call ID, not the audit's own id.
200 OKAn object with audit, transcript, and recordingAvailable.
Response JSON
{
  "audit": {
    "id": "audit_2c7076aa",
    "callId": "call_748cfe8c",
    "agentId": "agent_8d41f3d4f6324af2b77b3b183f923f4c",
    "agentName": "Collections assistant",
    "caller": "+5511999999999",
    "callStartedAt": "2026-10-11T18:30:00Z",
    "callDurationSeconds": 134,
    "status": "completed",
    "score": 96,
    "summary": "The required identity check was completed.",
    "improvementSuggestion": "Repeat the due date before closing.",
    "findings": [{
      "criterionId": "criterion_identity",
      "criterionName": "Confirm identity",
      "severity": "critical",
      "verdict": "passed",
      "explanation": "The customer confirmed their identity.",
      "confidence": 0.98,
      "evidence": [{ "timestamp": "00:00:03", "speaker": "customer", "quote": "Yes, this is Carlos." }],
      "review": null
    }],
    "error": null,
    "completedAt": "2026-10-11T18:34:00Z",
    "reviewStatus": "pending",
    "reviewedAt": null
  },
  "transcript": [
    { "id": "msg_1", "role": "agent", "speaker": "Agent", "text": "May I speak with Carlos?", "timestamp": "00:00:00" },
    { "id": "msg_2", "role": "customer", "speaker": "Customer", "text": "Yes, this is Carlos.", "timestamp": "00:00:03" }
  ],
  "recordingAvailable": true
}

Errors: 404 when no audit exists for the call.

Agent models

Agent write object

This complete object is required by both POST /agents and PUT /agents/{agentId}. Optional fields use the documented defaults.

PropertyTypeRequiredAccepted values / behavior
namestringYesDisplay name. Outer whitespace is removed.
purposestringYesBusiness objective.
statusenumYesinactive or active.
languageenumYesExact label from Supported languages.
voiceenumYesExact, case-sensitive voice name compatible with model. See Models and voices.
greetingstringYesFirst message spoken by the agent.
instructionsstringYesSystem instructions and operational rules.
transferNumberstring | nullNoE.164 human transfer destination; blank becomes null.
phoneNumberIdsstring[]NoOwned number IDs. Every number must be unassigned or already assigned to this agent. Default [].
modelenumYesstandard, advanced, or premium. See Models and voices.
knowledgeSourcesobject[]NoRequired knowledgeBaseId and usageInstructions per item. Default [].
toolIdsstring[]NoExisting REST tool IDs in the workspace. Default [].
structuredDataSourcesobject[]NoRequired schemaId and usageInstructions per item. Default [].
recording.enabledbooleanNoDefault false.
recording.retentionDaysintegerNo7, 30, 60, or 90; otherwise normalized to 30.
advanced.responseStylestringNoCase-sensitive: Precise, Balanced, or Creative. Default Balanced.
advanced.voiceExpressivenessstringNoCase-sensitive: Low, Moderate, or High. Default Moderate.
advanced.inactivityTimeoutSecondsintegerNo30, 60, or 90. Default 60.
advanced.interruptionSensitivitystringNoCase-sensitive: Low, Medium, or High. Default Medium.
quality.enabledbooleanNoEnables quality sampling. Default false.
quality.auditPercentageintegerNo0–100; must be greater than zero when enabled. Default 10.
quality.criteriaobject[]NoUp to 50. Each has optional id, required name (max 120) and rule (max 2,000), severity (low, medium, high, critical), and enabled.
testCallerNumberstring | nullNoCaller number allowed to test the current draft when supported.

Agent response object

PropertyTypeDescription
idstringStable agent ID.
name, purpose, status, language, voice, model, greeting, instructions, transferNumbermixedThe saved draft configuration.
phoneNumberIdsstring[]Associated number IDs.
phoneNumbersstring[]Formatted associated numbers.
knowledgeSources, toolIds, structuredDataSourcesarraysSaved workspace resource associations.
recording, advanced, qualityobjectsNormalized versions of the corresponding write objects.
publishedbooleanWhether a production version exists; it does not mean the latest draft is published.
updatedAtdate-timeLast draft or publish update.

Enums and supported values

Send enum values exactly as shown. JSON enums use lower camel case unless a field is explicitly marked as case-sensitive.

Agent models and compatible voices

The public API exposes Voxiomni's commercial tiers only. Send and receive one of the three model values below; internal implementation identifiers are not part of the public contract.

Tiermodel valueCompatible voice values
EconomystandardMarin, Cedar, Coral, Sage, Verse, Alloy, Ash, Ballad, Echo, Shimmer
AdvancedadvancedClara, Rafael
PremiumpremiumFernanda, Joana, Roberta, Cassia, Carla, Karen, Ana, Wil, Diego, Ale, Mario, Matheus, Jon, Adam
Model and voice must match.

Voice names are case-sensitive. Select a voice from the same row as the requested model; changing tiers normally requires changing the voice as well.

Supported languages

The following exact labels are supported by the agent editor and public API:

English (US)Português (Brasil)EspañolFrançaisDeutschItalianoNederlandsPolskiРусскийУкраїнськаالعربيةעבריתहिन्दीاردوفارسی中文日本語한국어Bahasa IndonesiaBahasa MelayuไทยTiếng ViệtTürkçeSvenskaNorskDanskSuomiČeštinaSlovenčinaMagyarRomânăБългарскиΕλληνικάCatalàHrvatskiSrpskiSlovenščinaEestiLatviešuLietuviųÍslenskaМакедонскиBosanskiՀայերենAzərbaycan diliБеларускаяҚазақ тіліKiswahiliTagalogதமிழ்ಕನ್ನಡमराठीनेपालीGalegoCymraegMāoriAfrikaans

Enum reference

Context / propertyAccepted or returned values
Agent statusinactive, active
recording.retentionDays7, 30, 60, 90
advanced.responseStyle (case-sensitive)Precise, Balanced, Creative
advanced.voiceExpressiveness (case-sensitive)Low, Moderate, High
advanced.inactivityTimeoutSeconds30, 60, 90
advanced.interruptionSensitivity (case-sensitive)Low, Medium, High
Quality criterion severitylow, medium, high, critical
Phone number statusavailable, reserved, active
Phone number connectionTypevoxiomniNumber, callForwarding, sipTrunk
Call statusinProgress, completed, transferred, missed, failed
Call outcomeunresolved, resolved, transferred
Recording statusdisabled, pending, recording, available, absent, failed, expired
Transcription / analysis statuspending, processing, completed, failed
Analysis sentimentpositive, neutral, negative, mixed, unknown
Analysis resolutionStatusresolved, partiallyResolved, unresolved, unknown
Next step ownercustomer, company, agent, unknown
Quality audit statuspending, completed, failed
Quality reviewStatuspending, reviewed
Quality finding verdictpassed, failed, notApplicable
Quality review decisionconfirmed, falsePositive, incorrect
Webhook typecall.ended, call.processed, call.failed, quality.completed, quality.failed, quality.reviewed

Call models

Call object

PropertyTypeDescription
idstringStable ID used by call, recording, audit, and webhook operations.
caller, calledNumberstringCustomer and destination numbers.
agentId, agentNamestringAgent identity captured for the call.
startedAtdate-timeCall start time.
endedAtdate-time | nullNull while in progress.
durationSecondsintegerTotal duration.
statusenuminProgress, completed, transferred, missed, or failed.
outcomeenumunresolved, resolved, or transferred.
summarystringMay be empty until processing completes.
recordingobjectavailable, status (disabled, pending, recording, available, absent, failed, expired), contentType, durationSeconds, and expiresAt.
transcriptionobjectstatus (pending, processing, completed, failed), completedAt, and error.
analysisobjectstatus, summary, primaryReason, result, sentiment, resolutionStatus, topics, nextSteps, completedAt, and error.
analysis.sentimentenumpositive, neutral, negative, mixed, or unknown.
analysis.resolutionStatusenumresolved, partiallyResolved, unresolved, or unknown.
analysis.nextSteps[]object[]owner (customer, company, agent, unknown), action, and nullable dueDate.
transcript[]object[]id, role, speaker, text, and timestamp.
qualityobjectselected, status, nullable score, and nullable completedAt.
processedAtdate-time | nullWhen all post-call processing finished.

Quality models

PropertyTypeDescription
id, callId, agentId, agentName, callerstringAudit, call, agent, and caller identity.
callStartedAtdate-timeStart time.
callDurationSecondsintegerDuration.
statusenumpending, completed, or failed.
scoreinteger | nullOverall score from 0 to 100 when completed.
summarystringOverall audit explanation.
improvementSuggestionstring | nullSuggested coaching action.
findings[]object[]One result per criterion.
findings[].severityenumlow, medium, high, or critical.
findings[].verdictenumpassed, failed, or notApplicable.
findings[].confidencedecimalNormally 0–1.
findings[].evidence[]object[]timestamp, speaker, and quote.
findings[].reviewobject | nulldecision (confirmed, falsePositive, incorrect), note, reviewer identity, and reviewedAt.
errorstring | nullFailure detail.
completedAtdate-time | nullAutomatic audit completion time.
reviewStatusenumpending or reviewed.
reviewedAtdate-time | nullHuman review completion time.

One endpoint, multiple event types

Create an HTTPS endpoint in Settings → Development and select its events. Voxiomni sends an HTTP POST with Content-Type: application/json. Route by type and deduplicate by id.

Event envelope
{
  "id": "evt_7df2d10f",
  "type": "call.processed",
  "apiVersion": "2026-10-01",
  "createdAt": "2026-10-11T18:34:01Z",
  "tenantId": "tenant_43a6f21c",
  "data": {
    "id": "call_748cfe8c",
    "status": "completed",
    "summary": "Customer accepted the payment plan."
  }
}
PropertyTypeDescription
idstringUnique event ID for idempotency.
typeenumThe event type below.
apiVersionstringCurrent contract version: 2026-10-01.
createdAtdate-timeEvent creation time.
tenantIdstringWorkspace that owns the event.
dataobjectA Call object or Quality audit object.
Acknowledge first.

Verify the signature, persist the event, return a 2xx response quickly, and run heavier work asynchronously.

Verify webhook signatures

Read the exact raw body before JSON parsing. Compute HMAC-SHA256 over {timestamp}.{rawBody} with the endpoint signing secret, then compare the lowercase hexadecimal digest with the value after v1=.

Voxiomni-Event-IdEvent ID for deduplication.
Voxiomni-TimestampUnix timestamp for this attempt.
Voxiomni-Signaturev1=<64-character SHA-256 hex>
User-AgentVoxiomni-Webhooks/1.0
Node.js verification
import crypto from 'node:crypto'

export function verifyVoxiomniWebhook(rawBody, headers, secret) {
  const timestamp = headers['voxiomni-timestamp']
  const header = headers['voxiomni-signature'] ?? ''
  const receivedHex = header.startsWith('v1=') ? header.slice(3) : ''

  if (!timestamp || !/^[a-f0-9]{64}$/.test(receivedHex)) return false

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest()
  const received = Buffer.from(receivedHex, 'hex')
  return received.length === expected.length &&
    crypto.timingSafeEqual(received, expected)
}
Replay protection

Reject timestamps outside your tolerance and ignore event IDs already processed.

Event types

call.ended

The call ended. data is a Call object, but post-processing may still be pending.

call.processed

All post-call processing finished. data is the final Call object.

call.failed

The call ended in a failed state. data is a Call object and may be partial.

quality.completed

The automatic audit completed. data is a Quality audit object.

quality.failed

The audit failed. data has status: "failed" and an error.

quality.reviewed

A human completed the review. data contains the updated audit and decisions.

Delivery and retries

Delivery is at least once. The same event can arrive more than once, so consumers must be idempotent. Any 2xx response marks success.

Immediate+1 minute+5 minutes+30 minutes+2 hours+12 hours

Voxiomni retries network failures and HTTP 408, 409, 425, 429, and 5xx. Other non-2xx responses fail without an automatic retry. Delivery records are retained in the app for 30 days and can be retried manually.

Endpoint requirements

The URL must use HTTPS, resolve only to public IP addresses, and contain no embedded credentials or fragment.