Reference

API Reference

Complete reference for all Novauth verification endpoints. Every channel shares the same authentication model and base URL — only the path and payload differ.

BASE URLhttps://api.novauth.com/api/v1/connect-hub

Authentication

Every request must include two headers. You can find your credentials in the Developer → API Keys section of the dashboard. Credentials are cached server-side for 5 minutes, so newly created keys are active within seconds.

x-api-keyYour API key. Treat like a password — never expose in client-side code.
x-account-idYour account identifier. Shown on the dashboard beside each API key.
x-request-idOptional correlation ID. Pass any UUID; returned in error responses for tracing.

Store credentials in environment variables (BETATEL_API_KEY, BETATEL_ACCOUNT_ID). Never hardcode them in source files.

Keys prefixed with sk_test_ are sandbox keys — they never touch real carriers and incur no charges. Use them during development, then swap to your BTEL_ key when you go live. Sandbox Mode →

IP Whitelisting

When creating an API key you can optionally attach one or more IP addresses or CIDR ranges. If an IP whitelist is configured, any request arriving from an IP not in the list is rejected with 401 Unauthorized, even if the API key itself is valid. This lets you lock a key to your server's IP so it cannot be used if leaked.

Example authenticated request
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/call/flash \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{"callee": "+14155552671"}'

Verify Call

Initiates a short-duration ring-and-hangup call. The caller ID encodes the OTP — your mobile SDK reads the incoming number without the user having to answer.

Send a Verify Call
POST/api/v1/connect-hub/call/flash
Request body
calleestringrequired
Recipient phone in E.164 format (e.g. +14155552671).
callerstring
Caller ID in E.164 format. Defaults to the account's configured number.
max_ring_timenumber
Ring duration in seconds before auto-hangup. Defaults to a random value between the account min/max ring times.
Response — 200 OK
uuidstring (ULID)
Unique call identifier. Store this — needed for CDR lookup and webhook reporting.
callerstring
Actual caller ID used (may differ from request if defaulted).
calleestring
Recipient number (echo).
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/call/flash \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "callee": "+14155552671",
    "caller": "+38761000001",
    "max_ring_time": 5
  }'

# Response:
# {
#   "uuid": "01KAK9KATW01A437PSXS5EVDCR",
#   "caller": "+38761000001",
#   "callee": "+14155552671"
# }
Get Call Detail Record
GET/api/v1/connect-hub/call/flash/:uuid/cdr
Response — 200 OK
hangup_causestring
SIP hangup reason (e.g. NORMAL_CLEARING, NO_ANSWER, ORIGINATOR_CANCEL).
durationnumber
Total call duration in seconds (ringing + connected).
billsecnumber
Billed duration in seconds (answer to hangup).
pddnumber
Post-dial delay in seconds (time to first ring).
destination_countrystring
Resolved destination country name.
start_stampstring (ISO 8601)
UTC timestamp when the call was initiated.
bash
curl https://api.novauth.com/api/v1/connect-hub/call/flash/01KAK9KATW01A437PSXS5EVDCR/cdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID"

# Response:
# {
#   "uuid": "01KAK9KATW01A437PSXS5EVDCR",
#   "caller": "+38761000001",
#   "callee": "+14155552671",
#   "hangup_cause": "NORMAL_CLEARING",
#   "duration": 6,
#   "billsec": 0,
#   "pdd": 2,
#   "start_stamp": "2024-06-01T10:30:00.000Z",
#   "destination_country": "United States",
#   "destination_country_code": "US"
# }
List Call Records
POST/api/v1/connect-hub/call/flash/cdr

Returns a paginated list of all calls for your account. Use filter to narrow results by any CDR field (e.g. callee, hangup_cause).

Request body
pagenumber
Page number (min: 1, default: 1).
rows_per_pagenumber
Records per page (1–100, default: 20).
sort_bystring
Field to sort by (e.g. start_stamp, callee).
sort_direction"ASC" | "DESC"
Sort order.
filterobject
Optional key/value filters applied to the CDR fields.
Response — 200 OK
totalnumber
Total records matching the filter.
total_pagesnumber
Total number of pages.
has_next_pageboolean
Whether a next page exists.
has_previous_pageboolean
Whether a previous page exists.
listCDR[]
Array of call detail records for the current page.
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/call/flash/cdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "page": 1,
    "rows_per_page": 20,
    "sort_by": "start_stamp",
    "sort_direction": "DESC"
  }'
Hang Up a Call
DELETE/api/v1/connect-hub/call/flash/:uuid

Terminates an active call before it naturally ends. Returns 204 No Content on success.

bash
# Terminate an active call before it naturally ends
curl -X DELETE https://api.novauth.com/api/v1/connect-hub/call/flash/01KAK9KATW01A437PSXS5EVDCR \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID"

# Returns 204 No Content on success

SMS

Delivers a text message via SMPP. Typically used to send a numeric OTP code that the user types into your app.

Send an SMS
POST/api/v1/connect-hub/sms
Request body
tostringrequired
Recipient phone in E.164 format.
textstringrequired
Message body. Up to 4096 characters; longer messages are split into concatenated parts.
fromstring
Sender ID (alphanumeric or phone). Defaults to the account's configured sender.
Response — 200 OK
messageIdstring (UUID)
Unique message identifier. Store this — needed for SDR lookup and webhook reporting.
fromstring
Sender ID used.
tostring
Recipient number (echo).
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/sms \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "text": "Your verification code is 482910. Valid for 5 minutes.",
    "from": "Novauth"
  }'

# Response:
# {
#   "messageId": "0a62face-6d15-11f0-962f-d89d6729654c",
#   "from": "Novauth",
#   "to": "14155552671"
# }
Get Message Status
GET/api/v1/connect-hub/sms/:messageId/sdr

Retrieves the delivery status for a sent message. Status is updated asynchronously as carrier delivery reports (DLRs) arrive.

Response — status values
deliveredConfirmed delivery to handset.
sentDispatched to carrier; awaiting DLR.
failedDelivery failed (invalid number, blocked).
undeliveredCarrier accepted but delivery not confirmed.
bash
curl https://api.novauth.com/api/v1/connect-hub/sms/0a62face-6d15-11f0-962f-d89d6729654c/sdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID"

# Response:
# {
#   "uuid": "...",
#   "messageId": "0a62face-6d15-11f0-962f-d89d6729654c",
#   "from": "Novauth",
#   "to": "+14155552671",
#   "status": "delivered",
#   "timestamp": "2024-06-01T10:30:00.000Z"
# }
List Messages
POST/api/v1/connect-hub/sms/sdr

Returns a paginated list of all sent messages. Accepts the same pagination body as other list endpoints (page, rows_per_page, sort_by, filter).

bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/sms/sdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "page": 1,
    "rows_per_page": 20,
    "sort_direction": "DESC"
  }'

Telegram OTP

Sends a numeric OTP via Telegram's official Gateway API. Supports delivery-ability checks, server-side code validation, and revocation with automatic refund.

Send Telegram OTP
POST/api/v1/connect-hub/telegram
Request body
tostringrequired
Recipient phone in E.164 format.
codestringrequired
OTP code to deliver (4–8 digits).
ttlnumber
Code validity in seconds (30–3600). Default: 300.
sender_usernamestring
Verified Telegram channel username. Omit to use the account default.
callback_urlstring
Per-request webhook override. Telegram Gateway will POST status events directly to this URL.
Response — 200 OK
uuidstring (ULID)
Novauth correlation ID. Use for webhook reporting.
request_idstring
Telegram Gateway request ID. Use for status checks and revocation.
statusstring
Normalized delivery status (sent, delivered, …).
request_costnumber
Charge for this request in EUR.
remaining_balancenumber
Account balance after the charge.
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "code": "482910",
    "ttl": 300
  }'

# Response:
# {
#   "uuid": "01KNV9CWW9ZEYVDFBJ1N7M1DVR",
#   "request_id": "tg_req_abc123",
#   "to": "14155552671",
#   "status": "sent",
#   "request_cost": 0.05,
#   "remaining_balance": 49.95
# }
Check Reachability
POST/api/v1/connect-hub/telegram/check-send-ability

Probes whether the number has a Telegram account before sending. If is_refunded is true, the user has no Telegram account — the probe cost is refunded and you should fall back to SMS or Verify Call.

bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram/check-send-ability \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{"to": "+14155552671"}'

# Response:
# {
#   "request_id": "tg_req_abc123",
#   "phone_number": "14155552671",
#   "request_cost": 0.01,
#   "is_refunded": false,
#   "remaining_balance": 49.99,
#   "delivery_status": { "status": "sent", "updated_at": 1713350400 }
# }
Check Verification Status
POST/api/v1/connect-hub/telegram/check-verification-status

Queries the code-entry outcome for a given request_id. Optionally pass the user-entered code for server-side validation.

verification_status values
code_validUser entered the correct code.
code_invalidUser entered a wrong code.
code_max_attempts_exceededToo many failed attempts.
expiredCode TTL elapsed before entry.
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram/check-verification-status \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "tg_req_abc123",
    "code": "482910"
  }'

# Response:
# {
#   "request_id": "tg_req_abc123",
#   "verification_status": {
#     "status": "code_valid",
#     "updated_at": 1713350400
#   }
# }
Revoke Verification
POST/api/v1/connect-hub/telegram/revoke-verification

Cancels an active OTP request before the user completes it. If the message has not yet been read, is_refunded will be true and the charge is returned to your balance.

bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram/revoke-verification \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{"request_id": "tg_req_abc123"}'

# Response:
# {
#   "request_id": "tg_req_abc123",
#   "is_refunded": true,
#   "remaining_balance": 50.0
# }
Get Delivery Record
GET/api/v1/connect-hub/telegram/:uuid/tdr

Fetches the full Telegram Delivery Record for a given uuid (the Novauth correlation ID returned by the send endpoint). Includes delivery status, verification status, cost, and country.

bash
curl https://api.novauth.com/api/v1/connect-hub/telegram/01KNV9CWW9ZEYVDFBJ1N7M1DVR/tdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID"

# Response includes full TDR:
# {
#   "uuid": "01KNV9CWW9ZEYVDFBJ1N7M1DVR",
#   "to": "+14155552671",
#   "status": "DELIVERED",
#   "delivery_status": "delivered",
#   "verification_status": "code_valid",
#   "request_cost": 0.05,
#   "country": "United States",
#   "created_at": "2024-06-01T10:30:00.000Z"
# }
List Delivery Records
POST/api/v1/connect-hub/telegram/tdr

Returns a paginated list of all Telegram delivery records. Filter by <code>verification_status</code>, <code>delivery_status</code>, or any other TDR field.

bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/telegram/tdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "page": 1,
    "rows_per_page": 20,
    "sort_direction": "DESC"
  }'

WhatsApp

Sends an OTP message via WhatsApp Business API. The user reads the code inside the WhatsApp conversation and types it into your app.

Send WhatsApp OTP
POST/api/v1/connect-hub/whatsapp/otp
Request body
tostringrequired
Recipient phone in E.164 format.
textstringrequired
Message body. Include the OTP code and expiry hint.
Response — 200 OK
uuidstring (ULID)
Unique message identifier. Store this — needed for webhook reporting.
tostring
Recipient number (echo).
bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/whatsapp/otp \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "text": "Your verification code is 482910. Valid for 5 minutes."
  }'

# Response:
# {
#   "uuid": "01KAK9KATW01A437PSXS5EVDCR",
#   "to": "+14155552671"
# }

After sending, report the user's verification outcome back via POST /whatsapp/webhook. See the Webhooks reference for details.

Get Delivery Record
GET/api/v1/connect-hub/whatsapp/:uuid/wdr

Fetches the WhatsApp Delivery Record for a given uuid returned by the send endpoint.

bash
curl https://api.novauth.com/api/v1/connect-hub/whatsapp/01KAK9KATW01A437PSXS5EVDCR/wdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID"

# Response:
# {
#   "uuid": "01KAK9KATW01A437PSXS5EVDCR",
#   "to": "+14155552671",
#   "status": "DELIVERED",
#   "created_at": "2024-06-01T10:30:00.000Z"
# }
List Delivery Records
POST/api/v1/connect-hub/whatsapp/wdr

Returns a paginated list of all WhatsApp delivery records. Supports the same <code>page</code>, <code>rows_per_page</code>, <code>filter</code> body as all other list endpoints.

bash
curl -X POST https://api.novauth.com/api/v1/connect-hub/whatsapp/wdr \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-account-id: YOUR_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "page": 1,
    "rows_per_page": 20,
    "sort_direction": "DESC"
  }'

Error Codes

All error responses follow the same JSON envelope. The error field contains a machine-readable string; pass your x-request-id to support when reporting issues.

StatusCodeDescription
400BAD_REQUESTInvalid request body — missing required field, wrong format, or invalid phone number.
401UNAUTHORIZEDMissing or invalid x-api-key / x-account-id headers.
402PAYMENT_REQUIREDInsufficient account balance. Top up your account to continue.
403FORBIDDENAPI key exists but lacks permission for this operation.
404NOT_FOUNDThe requested UUID or resource does not exist.
409CONFLICTDuplicate request or conflicting state (e.g. revoking an already-expired request).
480TEMPORARY_UNAVAILABLEGateway temporarily unreachable. Retry with exponential back-off.
486BUSY_HERE(Verify Call) Recipient is busy or the call was rejected by the network.
500INTERNAL_SERVER_ERRORUnexpected server error. Contact support with your x-request-id.
503SERVICE_UNAVAILABLEGateway disconnected or service under maintenance. Check the status page.
603DECLINE(Verify Call) Recipient explicitly declined the call.

For a full list of error codes including suggested remediation steps, see the Error Handling guide.