Skip to main content

Verify (OTP check)

API for creating and verifying one-time passwords (OTP) via SMS, Email and other channels.

POST requests must include the header Content-Type: application/json. Code verification (verify) also supports the GET method.


Create code — synchronous

Creates a verification code and sends it via SMS or Email. The gateway processes the request immediately and returns verify_id.

URI: /api/verify.php

HTTP method: POST

Request example

{
"auth": "API_KEY",
"command": "verify/create",
"phone": "441501234567",
"type": "sms",
"sender_name": "MyBrand",
"lang": "en",
"code_length": 6,
"code_type": "numeric",
"service_id": 1,
"custom_id": "abcdef1234567",
"hook": "https://example.com/webhook"
}

Example response:

{
"success": true,
"verify_id": "14fb5f3d-20be-41ef-b31a-b9f5e499bc7a"
}

HTTP errors: 400 (invalid format/JSON), 401 (invalid auth), 413 (request body too large).


Create code — asynchronous

Queues code creation for background processing. Request body is the same as for synchronous create, except the command field is optional (the worker sets verify/create automatically).

URI: /v1/verify/create

HTTP method: POST

Content-Type: application/json

Example response:

{
"request_id": "cf-ray-1234567890-ABC",
"success": true
}

verify_id is not returned in this response. If the request is rejected during processing, the reason is delivered to the hook URL — see Webhook. The result of the check itself is obtained with the verify command.

HTTP error codes:

CodeDescription
400Invalid JSON
401Missing or invalid auth
405Method other than POST
413Request body too large
415Missing or invalid Content-Type (must be application/json)
503Queue unavailable

Verify code

URI: /api/verify.php

This request checks the code entered by the user and returns the verification status (only the sync API).

Request example (GET)

/api/verify.php?auth=API_KEY&command=verify&phone=380501234567&code=123456&verify_id=14fb5f3d-20be-41ef-b31a-b9f5e499bc7a

Request example (POST, JSON)

{
"auth": "API_KEY",
"command": "verify",
"phone": "380501234567",
"code": "123456",
"verify_id": "14fb5f3d-20be-41ef-b31a-b9f5e499bc7a"
}

Example of a successful response:

{
"success": true,
"verify_id": "14fb5f3d-20be-41ef-b31a-b9f5e499bc7a",
"phone": "441501234567",
"type": "sms",
"status": "approved",
"service_id": 1
}

Possible values of status:

statusDescription
approvedCode is correct, verification successful
pendingCode is incorrect, but attempts are still available
expiredCode has expired
blockedAttempt limit exceeded

HTTP error codes:

  • 400 — invalid request format or JSON
  • 401 — missing or invalid auth
  • 413 — request body too large

Webhook

If the hook parameter was passed and the request was rejected during processing, the gateway sends a notification to that address.

The payload repeats the format of the message webhook: a flat object with status and the reason in error. There is no separate payload for errors.

HTTP method: POST
Content-Type: application/json
X-Signature: sha256(json_body + api_key)

ParameterTypeDescription
verify_idstringIdentifier of the verification
statusstringAlways REJECTED — the request was rejected during processing
errorstringReason why the request was rejected
updatedstringDate and time of the event
Format: YYYY-MM-DDThh:mm:ss±hh:mm
request_idstringIdentifier of the request, returned by the asynchronous API

Request example

{
"verify_id": "14fb5f3d-20be-41ef-b31a-b9f5e499bc7a",
"status": "REJECTED",
"error": "Access denied",
"updated": "2026-08-21T10:12:33+03:00",
"request_id": "a1436d496bf11a59"
}

Response

You will receive code 200 in response. The webhook is sent once, without retries.


Limits

  • Code lifetime: by default 300 seconds (5 minutes), range 60–3600 seconds.
  • Maximum attempts: by default 5.