v1 REST API Reference

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.

API Key Format
ovrtxt_sk_live_...

Use your secret API key from the dashboard to authenticate all requests.

Authorization Header
Authorization: Bearer ovrtxt_sk_live_9283472abc...
cURL Example
curl https://api.ovrtxt.com/v1/verify \
  -H "Authorization: Bearer $OVRTXT_SECRET_KEY" \
  -H "Content-Type: application/json"

Base URL

https://api.ovrtxt.com

All API requests must be made over HTTPS. TLS 1.3 is enforced. Plain HTTP is rejected.

POST /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.

// Generated in browser:
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"
    }
  }'
200 Successful Response
{
  "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."
422 Validation Error
{
  "error": {
    "code": "INVALID_PHONE",
    "message": "Phone number must be in E.164 format.",
    "field": "phone",
    "docUrl": "https://ovrtxt.com/api#errors"
  }
}
GET /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}.
authEntropy: A 64-character (32-byte) hex string returned only when 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).
Request
curl https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A \
  -H "Authorization: Bearer $OVRTXT_SECRET_KEY"
200 Approved Session
{
  "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"
  }
}
POST /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
curl -X POST \
  https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A/send-sms \
  -H "Content-Type: application/json"
Response (200 OK)
{
  "success": true,
  "message": "Verification code sent via SMS.",
  "phone": "+14155552671"
}
POST /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
curl -X POST \
  https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A/check \
  -H "Content-Type: application/json" \
  -d '{"code": "492018"}'
Response (200 OK)
{
  "id": "sess_01HZXVK29S8T4MFQNPQ7RBK93A",
  "status": "approved",
  "phone": "+14155552671",
  "authEntropy": "a4f8e12b79c3d4e08f51a2b96c8d7e01fa4b8c9d0e1f2a3b4c5d6e7f8a9b0c1d",
  "e2eeKeyShare": "a4f8e12b79c3d4e08f51a2b96c8d7e01fa4b8c9d0e1f2a3b4c5d6e7f8a9b0c1d"
}
DELETE /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
curl -X DELETE \
  https://api.ovrtxt.com/v1/verify/sess_01HZXVK29S8T4MFQNPQ7RBK93A \
  -H "Authorization: Bearer $OVRTXT_SECRET_KEY"
# → HTTP 204 No Content
GET /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 datetime

Start of the reporting window. Defaults to current billing period start.

toOPTIONALISO 8601 datetime

End of the reporting window. Defaults to the current moment.

200 Usage Response
{
  "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
idstringUnique session identifier. Prefixed sess_.
statusenumpending | approved | expired | denied | cancelled
channelenumrcs | sms_fallback. Delivery path chosen by Ovrtxt.
fallbackUristring | nullThe sms: deep link. Non-null only when channel = sms_fallback.
phonestringThe E.164 phone number for this session.
accountIdstringThe account identifier provided in the request.
brandIdstringThe brand identifier used for this session. Brand details (name, logo, RCS agent) are resolved server-side from your Dashboard configuration.
brandSlugstringThe uppercase custom slug code used to prefix SMS tokens (e.g. AUTH-JOESGYM-XXXXXX).
latencyMsinteger | nullMilliseconds from session creation to approval. Null until approved.
approvedAtdatetime | nullISO 8601 timestamp of approval. Null until approved.
expiresAtdatetimeWhen this session's token becomes invalid.
createdAtdatetimeISO 8601 creation timestamp.
metadataobjectCaller-supplied key-value pairs. Echoed back verbatim.

Error Codes

HTTP Status Error Code Description
200—Success. Session created.
204—Success. No body. (DELETE responses)
400MALFORMED_REQUESTRequest body is not valid JSON.
401UNAUTHORIZEDMissing or invalid API key.
403FORBIDDENAPI key lacks permission for this action.
404SESSION_NOT_FOUNDSession ID not found or expired.
422INVALID_PHONEPhone not in E.164 format, or not a routable number.
429RATE_LIMITEDToo many requests. See Retry-After header.
500INTERNAL_ERRORUnexpected server error. Check status.ovrtxt.com.

Rate Limits

All limits are applied per API key. Rate limit headers are present on every response.

500
requests / minute
Developer tier
Custom
negotiated limit
Enterprise tier
X-RateLimit-Limit: 500 X-RateLimit-Remaining: 487 X-RateLimit-Reset: 1723250400