Overview
OTP sessions generate a numeric code, store only its hash, return the code when the session is created, and send it by SMS. OTP sends use the same SMS pipeline and credit charging as regular messages, and the generated message has type otp. For localized copy, create a multilingual template in Dashboard → Templates with {{code}} as its only placeholder, get it approved, then select its ID and language.
POST /v1/otp/sessions
curl https://api.bar9.dev/v1/otp/sessions \
-H "Authorization: Bearer $BAR9_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+213555000000",
"template_id": "tpl_otp",
"language": "en",
"code_length": 6,
"ttl_seconds": 300
}'
The endpoint returns 202 Accepted. Use a production key with otp:create; test keys must use the corresponding test endpoint.
Create fields
| Field | Required | Notes |
|---|---|---|
to |
Yes | Algerian mobile number. |
template_id |
No | Accepted account template whose only placeholder is {{code}}. |
language |
With ID | One of the selected template's language tags. |
template |
No | Legacy inline copy; must include {{code}} and cannot be combined with template_id. |
code_length |
No | Integer from 4 to 8; defaults to 6. |
ttl_seconds |
No | Integer from 60 to 900; defaults to 300. |
When neither template field is supplied, the message defaults to Your verification code is {{code}}.
Session response
{
"ok": true,
"data": {
"id": "otp_...",
"message_id": "msg_...",
"code": "773421",
"to": "+213555000000",
"status": "pending",
"expires_at": 1778407500,
"created_at": 1778407200,
"verified_at": null
}
}
The generated code appears only in the creation response so your trusted server can coordinate the verification flow. Do not expose the Bar9 API key or log the code.
GET /v1/otp/sessions/:id
Read a session owned by the API-key account:
curl https://api.bar9.dev/v1/otp/sessions/otp_123 \
-H "Authorization: Bearer $BAR9_API_KEY"
This endpoint requires otp:read and returns the session representation without code. status is pending until successful verification, then verified; verified_at is null until verification succeeds. Unknown or foreign session IDs return 404.
POST /v1/otp/sessions/:id/verify
curl https://api.bar9.dev/v1/otp/sessions/otp_123/verify \
-H "Content-Type: application/json" \
-d '{ "code": "773421" }'
This endpoint is public because the unguessable session ID and the OTP code form the verification credential. It does not accept an API key requirement. The code must be 4 to 8 digits.
A successful response is 200 OK and returns the session with status: "verified" and a populated verified_at. Already verified, expired, and incorrect-code attempts return API errors.
Common errors
| Status | Typical cause |
|---|---|
400 |
Invalid phone, template, code length, TTL, or code format. |
401 |
Missing or invalid API key on create/get. |
403 |
Wrong key environment or missing otp:create/otp:read. |
404 |
Session does not exist or is not owned by the API-key account. |
409 |
Session is expired, already verified, or cannot change state. |
402 |
Insufficient credits to create and send the production OTP SMS. |