HexaVox Developer Guide

Connection

Base URLs and auth headers

Use the API domain for server-to-server integrations. HexaVox also proxies the same API through the dashboard host, but the dedicated API domain is the clean public entry point.

Developer portal https://developer.gohexavox.com

Reference docs, payload examples, and Swagger downloads.

Production API base https://api.gohexavox.com/api/v1

Use this for direct integration traffic.

API key header X-API-KEY

Tenant or merchant integration key issued by HexaVox.

API secret header X-API-SECRET

Paired secret for the same integration credential.

Write idempotency Idempotency-Key

Recommended on all POST calls so the same logical action converges on one final outcome.

Format expectations application/json

Phone numbers in E.164 format, email bodies can be HTML, and reporting dates use YYYY-MM-DD.

Operational rule. HexaVox uses reconcile-first delivery handling for ambiguous provider outcomes. Senders should still include an Idempotency-Key on every write so API retries, queue retries, and webhook replays all converge on the same final state.

Quickstart

Typical integration flow

Most HexaVox integrations follow the same sequence: provision the merchant, capture consent, dispatch the outbound message, then read billing or usage state.

1. Create or update a merchant

curl -X POST "https://api.gohexavox.com/api/v1/merchants" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-API-SECRET: YOUR_API_SECRET" \
  -d '{
    "merchantId": "gym-a",
    "displayName": "Gym A",
    "active": true,
    "smsLimit": 5000,
    "voiceMinutesLimit": 1000,
    "emailLimit": 25000
  }'
{
  "merchantId": "gym-a",
  "displayName": "Gym A",
  "active": true,
  "limits": {
    "smsLimit": 5000,
    "voiceMinutesLimit": 1000,
    "emailLimit": 25000
  },
  "credits": {
    "smsCredits": 0,
    "voiceMinutesCredits": 0,
    "emailCredits": 0
  },
  "usage": {
    "smsUsed": 0,
    "voiceUsed": 0,
    "emailUsed": 0,
    "periodStart": "2026-04-01"
  }
}

2. Upsert recipient consent

curl -X POST "https://api.gohexavox.com/api/v1/consents" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-API-SECRET: YOUR_API_SECRET" \
  -d '{
    "merchantId": "gym-a",
    "channel": "SMS",
    "contact": "+18135551234",
    "status": "OPT_IN",
    "source": "checkout-form"
  }'
{
  "merchantId": "gym-a",
  "channel": "SMS",
  "contact": "+18135551234",
  "status": "OPT_IN",
  "source": "checkout-form",
  "updatedAt": "2026-04-16T13:20:32.942Z"
}

3. Send SMS, voice, or email

curl -X POST "https://api.gohexavox.com/api/v1/messages/sms" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-API-SECRET: YOUR_API_SECRET" \
  -H "Idempotency-Key: merchant-gym-a-otp-20260416-001" \
  -d '{
    "merchantId": "gym-a",
    "to": "+18135551234",
    "message": "Your OTP is 123456",
    "type": "OTP"
  }'
{
  "merchantId": "gym-a",
  "channel": "SMS",
  "messageId": "10441",
  "status": "QUEUED"
}

4. Read usage state

curl "https://api.gohexavox.com/api/v1/reports/usage?from=2026-04-01&to=2026-04-16" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-API-SECRET: YOUR_API_SECRET"
{
  "from": "2026-04-01",
  "to": "2026-04-16",
  "totalSmsCount": 1482,
  "totalEmailCount": 304,
  "awsCost": 0.00,
  "hqMarkup": 27.14,
  "finalCharges": 91.32,
  "freshnessState": "PROVISIONAL",
  "freshnessReason": "Provider finalization still pending for one or more messages."
}

Reporting state matters. Usage responses include freshnessState and freshnessReason. Treat PROVISIONAL as unsettled operational state and FINAL as billing-safe finalized state.

Reference

Public API catalog

These are the public `/api/v1/**` endpoints currently documented in Swagger. The interactive UI shows the exact request and response schemas for every endpoint below.

Method Path Purpose Primary payload / response
POST /api/v1/merchants Create or update a merchant under the authenticated tenant. V1MerchantUpsertRequest -> MerchantView
GET /api/v1/merchants List merchants with limits, credits, and current usage. MerchantView[]
GET /api/v1/merchants/{merchantId} Fetch one merchant by external merchant identifier. MerchantView
POST /api/v1/consents Upsert recipient consent for SMS, voice, or email. V1MerchantConsentRequest -> ConsentView
GET /api/v1/consents List consent records, optionally filtered by merchant. ConsentView[]
POST /api/v1/messages/sms Queue and dispatch an outbound merchant SMS. V1OmniSmsSendRequest -> DispatchResponse
POST /api/v1/messages/voice Start an outbound text-to-speech merchant voice call. V1OmniVoiceSendRequest -> DispatchResponse
POST /api/v1/messages/email Dispatch an outbound merchant email. V1OmniEmailSendRequest -> DispatchResponse
POST /api/v1/email/send Simple direct email send endpoint for integrations that do not need the omni wrapper. V1EmailSendRequest -> V1MessageResponse
POST /api/v1/billing/upgrade Request additional SMS, voice, or email units for a merchant. V1MerchantUpgradeRequest -> MerchantUpgradeView
GET /api/v1/alerts List merchant usage and provider alerts for the tenant. AlertView[]
GET /api/v1/reports/usage Read summarized usage, cost, markup, and freshness state. V1UsageReportResponse
GET / POST /api/v1/voice/provisioning* Read SIP/browser voice provisioning details and post SIP presence state. V1VoiceProvisioningResponse, V1VoiceSipPresenceRequest
POST / GET /api/v1/merchants/{merchantId}/messaging/* Manage SMS brand, campaign, messaging numbers, assignment, and 10DLC status. V1MerchantMessaging* payloads and compliance views

Payloads

Common request and response patterns

Use the interactive Swagger UI for the full schema list. These examples cover the most common integration payloads teams wire first.

POST /api/v1/messages/voice

Outbound voice

{
  "merchantId": "gym-a",
  "to": "+18135551234",
  "text": "Your appointment is tomorrow at 10 AM",
  "type": "REMINDER",
  "record": false,
  "timeoutSeconds": 30
}
{
  "merchantId": "gym-a",
  "channel": "VOICE",
  "messageId": "7821",
  "status": "QUEUED"
}
POST /api/v1/messages/email

Outbound email

{
  "merchantId": "gym-a",
  "to": "member@example.com",
  "subject": "Payment reminder",
  "body": "<p>Your membership renews tomorrow.</p>",
  "type": "TRANSACTIONAL"
}
{
  "merchantId": "gym-a",
  "channel": "EMAIL",
  "messageId": "8802",
  "status": "QUEUED"
}
POST /api/v1/billing/upgrade

Merchant upgrade request

{
  "merchantId": "gym-a",
  "channel": "SMS",
  "units": 2500,
  "amountCents": 4900,
  "paymentMethodId": "pm_123",
  "referenceId": "upgrade-apr-16",
  "note": "Seasonal reminder volume",
  "currency": "USD"
}
{
  "merchantId": "gym-a",
  "channel": "SMS",
  "unitsRequested": 2500,
  "amountCents": 4900,
  "currency": "USD",
  "paymentId": "pay_987",
  "paymentStatus": "PENDING",
  "fulfilled": false,
  "remainingCredits": 0
}

Voice and message writes support idempotency. Reuse the same Idempotency-Key for a retried logical action instead of generating a new one. That lets HexaVox collapse duplicate API retries into the same final message or call state.

Swagger

Interactive docs and downloadable specs

These links are wired to the live public `/api/v1/**` OpenAPI contract. Use them for SDK generation, Postman imports, internal docs, and interactive endpoint inspection.

Swagger UI

Interactive reference with request and response schemas, auth support, and try-it-out for the public HexaVox API.

OpenAPI JSON

Use the JSON spec for code generation, contract snapshots, and machine-readable API imports.

OpenAPI YAML

Use the YAML spec if your tooling prefers YAML over JSON for source control or gateway imports.

Public contract scope. The downloadable Swagger files describe the public HexaVox integration surface under /api/v1/**. Internal dashboard, HQ, and provider-webhook internals are intentionally kept out of this public developer contract.