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.
Live mode. Real verifications. You are billed.
Sandbox mode. Simulated delivery. Never billed.
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.
brandName
REQUIRED
string
Your product or company name. Rendered prominently on the RCS rich card header and in the OS compose sheet recipient label. Max 64 characters.
logoUrl
OPTIONAL
string (URL)
HTTPS URL to your brand logo. Must be a publicly reachable PNG or WebP, at least 256×256px. Rendered inside the RCS rich card. Falls back to initials avatar if omitted.
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.
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.
curl -X POST https://api.ovrtxt.com/v1/verify \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "+15550192834", "brandName": "Joe'"'"'s Gym", "logoUrl": "https://joesgym.com/logo.png", "webhookUrl": "https://api.joesgym.com/webhooks/ovrtxt", "ttl": 90, "metadata": { "userId": "usr_8a2f3d" } }'
{
"id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
"status": "pending",
"channel": "rcs",
"fallbackUri": null,
"phone": "+15550192834",
"brandName": "Joe's Gym",
"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://docs.ovrtxt.com/errors#INVALID_PHONE"
}
}
/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}.
curl https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A \ -H "Authorization: Bearer $OVRTXT_SECRET_KEY"
{
"id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
"status": "approved",
"channel": "rcs",
"phone": "+15550192834",
"brandName": "Joe's Gym",
"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}
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. |
| brandName | string | Brand name as submitted. |
| 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.