API Reference
The Ovrtxt API is a REST interface organized around predictable, resource-oriented URLs. It accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes.
🔑 Authentication
Ovrtxt uses API keys to authenticate requests. Your API key carries full privileges — keep it secret, keep it safe. Never commit it to version control or expose it client-side.
Authenticate by passing your key as a Bearer token in the HTTP Authorization header on every request.
Use your secret API key from the dashboard to authenticate all requests.
Authorization: Bearer ovrtxt_sk_live_9283472abc...
curl https://api.ovrtxt.com/v1/verify \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY" \ -H "Content-Type: application/json"
Base URL
All API requests must be made over HTTPS. TLS 1.3 is enforced. Plain HTTP is rejected.
/v1/verify
Initiate a Verification
The primary endpoint of the Ovrtxt API. Providing a user's phone number initiates the two-path verification flow. Ovrtxt first attempts to deliver a Branded RCS Rich Card to the device. If the device is offline or lacks RCS capability, the API returns a pre-built sms: deep link URI that your frontend renders as a "Tap to verify" button — opening the user's native OS compose sheet with a cryptographic token pre-filled.
Request Body Parameters
phone
REQUIRED
string
The end user's phone number in E.164 format. Example: +15550192834. Must be a valid NANP or international number.
accountId
REQUIRED
string
Your Ovrtxt account identifier. Found in the Dashboard → Account Settings. Used to look up your account's active brands and billing context.
brandId
REQUIRED
string
The identifier of the brand to present to the end user. Brand name, logo, and RCS agent configuration are configured once in the Dashboard → Brands and referenced here by ID.
webhookUrl
OPTIONAL
string (URL)
Your server endpoint that receives the verification.completed webhook event when the user's inbound SMS is matched. Overrides the default webhook URL configured on your account. See the Webhook Guide.
ttl
OPTIONAL
integer (seconds)
Session expiry in seconds. Default: 90. Min: 30. Max: 300. After expiry, the session moves to expired status and the token is invalidated.
channel
OPTIONAL
string ('rcs' | 'sms_fallback')
Overrides channel selection. Pass "sms_fallback" to explicitly disable RCS and force instant SMS verification, or "rcs" to prefer Google RBM rich card delivery.
allowSmsOtp
OPTIONAL
boolean
Controls whether outbound SMS OTP codes can be requested via POST /v1/verify/{id}/send-sms. Defaults to true. Set to false to strictly block outbound SMS, guaranteeing 100% protection against SMS toll fraud / AIT pumping.
metadata
OPTIONAL
object
Arbitrary key-value pairs (up to 16 keys, string values only, max 512 chars per value). Echoed back verbatim in webhook payloads. Useful for correlating a session back to your internal user ID.
clientChallenge
REQUIRED
string (hex)
The SHA-256 hash commitment of an ephemeral secret generated in the user's browser (SHA256(clientSecret)). Binds the session cryptographically to the originating device, guaranteeing mathematical zero-knowledge proof against rogue identity providers and session spoofing.
const secret = crypto.randomUUID();
const challenge = await sha256(secret);
curl -X POST https://api.ovrtxt.com/v1/verify \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "+15550192834", "accountId": "acct_01HZXVK29S8T4MFQNPQ7RBK93A", "brandId": "brd_01HZXVK29S8T4MFQNPQ7RBK93B", "clientChallenge": "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069", "webhookUrl": "https://api.joesgym.com/webhooks/ovrtxt", "ttl": 90, "metadata": { "userId": "usr_8a2f3d" } }'
{
"id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
"status": "pending",
"channel": "rcs",
"fallbackUri": null,
"phone": "+15550192834",
"accountId": "acct_01HZXVK29S8T4MFQNPQ7RBK93A",
"brandId": "brd_01HZXVK29S8T4MFQNPQ7RBK93B",
"clientChallenge": "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
"expiresAt": "2026-08-10T01:31:10Z",
"createdAt": "2026-08-10T01:29:40Z",
"metadata": {
"userId": "usr_8a2f3d"
}
}
📱 SMS Fallback Mode
When the target device cannot receive RCS, channel is "sms_fallback" and fallbackUri contains the deep link to render as your CTA button:
"channel": "sms_fallback", "fallbackUri": "sms:+18005550199?body=AUTH-JOESGYM-938472%0ATap%20SEND%20to%20log%20in."
{
"error": {
"code": "INVALID_PHONE",
"message": "Phone number must be in E.164 format.",
"field": "phone",
"docUrl": "https://ovrtxt.com/api#errors"
}
}
/v1/verify/{session_id}
Poll Session Status
Retrieves the current status of a verification session. Use this endpoint if you prefer polling over webhooks, or as a fallback status check. For real-time flows, webhooks or our WebSocket channel are strongly preferred — polling introduces latency and burns request quota.
Path Parameters
session_id
REQUIRED
string
The session identifier returned by POST /v1/verify. Format: sess_01...
Session Status Values
pending
Verification initiated. Awaiting inbound SMS or RCS approval.
approved
Inbound SMS matched. User is authenticated. Session is spent.
expired
TTL elapsed before approval. A new session must be initiated.
denied
User explicitly denied via RCS action button.
cancelled
Cancelled programmatically via DELETE /v1/verify/{id}.
status === "approved". Deterministically derived via HMAC-SHA256 from the verified phone number, accountId, and brandId, guaranteeing each application receives an isolated, zero-knowledge cryptographic entropy seed for cross-device E2EE key recovery (also aliased as e2eeKeyShare).
curl https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY"
{
"id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
"status": "approved",
"channel": "rcs",
"phone": "+15550192834",
"accountId": "acct_01HZXVK29S8T4MFQNPQ7RBK93A",
"brandId": "brd_01HZXVK29S8T4MFQNPQ7RBK93B",
"clientChallenge": "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
"authEntropy": "c84f1092a513b24680fedcba98765432c84f1092a513b24680fedcba98765432",
"approvedAt": "2026-08-10T01:30:00.340Z",
"latencyMs": 340,
"expiresAt": "2026-08-10T01:31:10Z",
"createdAt": "2026-08-10T01:29:40Z",
"metadata": {
"userId": "usr_8a2f3d"
}
}
/v1/verify/{session_id}/send-sms
Send SMS Verification Code (Fallback)
Dispatches an outbound SMS containing the 6-digit OTP code to the user's phone. Use this when the user prefers classic SMS OTP delivery over mobile-originated SMS messaging.
Path Parameters
session_id
REQUIRED
string
The active pending verification session ID.
Example Request & Response
curl -X POST \ https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A/send-sms \ -H "Content-Type: application/json"
{
"success": true,
"message": "Verification code sent via SMS.",
"phone": "+14155552671"
}
/v1/verify/{session_id}/check
Verify SMS Code (Fallback)
Validates the 6-digit OTP code entered by the user. If correct, transitions the session to approved, dispatches the webhook event, and returns the deterministic authEntropy.
Request Body
code
REQUIRED
string
The 6-digit numeric verification code received by the user via SMS.
Example Request & Response
curl -X POST \ https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A/check \ -H "Content-Type: application/json" \ -d '{"code": "492018"}'
{
"id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
"status": "approved",
"phone": "+14155552671",
"authEntropy": "a4f8e12b79c3d4e08f51a2b96c8d7e01fa4b8c9d0e1f2a3b4c5d6e7f8a9b0c1d",
"e2eeKeyShare": "a4f8e12b79c3d4e08f51a2b96c8d7e01fa4b8c9d0e1f2a3b4c5d6e7f8a9b0c1d"
}
/v1/verify/{session_id}
Cancel a Session
Immediately invalidates an active session, moving it to cancelled status. Idempotent — safe to call on already-terminal sessions. Returns a 204 No Content on success.
curl -X DELETE \ https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY" # → HTTP 204 No Content
/v1/usage
Retrieve Usage Statistics
Returns aggregated verification counts and estimated billing for the specified billing period. Useful for building internal dashboards and automated budget alerts.
Query Parameters
fromOPTIONALISO 8601 datetimeStart of the reporting window. Defaults to current billing period start.
toOPTIONALISO 8601 datetimeEnd of the reporting window. Defaults to the current moment.
{
"period": {
"from": "2026-08-01T00:00:00Z",
"to": "2026-08-10T00:00:00Z"
},
"verifications": {
"total": 48293,
"approved": 47811,
"expired": 312,
"denied": 170
},
"channels": {
"rcs": 29344,
"sms_fallback": 18467
},
"estimatedCostUsd": "1434.33"
}
The Session Object
The core resource returned by all verification endpoints. Every field is present on both API responses and webhook payloads, ensuring a single schema to handle across your codebase.
| Field | Type | Description |
|---|---|---|
| id | string | Unique session identifier. Prefixed sess_. |
| status | enum | pending | approved | expired | denied | cancelled |
| channel | enum | rcs | sms_fallback. Delivery path chosen by Ovrtxt. |
| fallbackUri | string | null | The sms: deep link. Non-null only when channel = sms_fallback. |
| phone | string | The E.164 phone number for this session. |
| accountId | string | The account identifier provided in the request. |
| brandId | string | The brand identifier used for this session. Brand details (name, logo, RCS agent) are resolved server-side from your Dashboard configuration. |
| brandSlug | string | The uppercase custom slug code used to prefix SMS tokens (e.g. AUTH-JOESGYM-XXXXXX). |
| latencyMs | integer | null | Milliseconds from session creation to approval. Null until approved. |
| approvedAt | datetime | null | ISO 8601 timestamp of approval. Null until approved. |
| expiresAt | datetime | When this session's token becomes invalid. |
| createdAt | datetime | ISO 8601 creation timestamp. |
| metadata | object | Caller-supplied key-value pairs. Echoed back verbatim. |
Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 200 | — | Success. Session created. |
| 204 | — | Success. No body. (DELETE responses) |
| 400 | MALFORMED_REQUEST | Request body is not valid JSON. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 403 | FORBIDDEN | API key lacks permission for this action. |
| 404 | SESSION_NOT_FOUND | Session ID not found or expired. |
| 422 | INVALID_PHONE | Phone not in E.164 format, or not a routable number. |
| 429 | RATE_LIMITED | Too many requests. See Retry-After header. |
| 500 | INTERNAL_ERROR | Unexpected server error. Check status.ovrtxt.com. |
Rate Limits
All limits are applied per API key. Rate limit headers are present on every response.