Quickstart
Overview
TACNow is a delivery-only SMS OTP API. You send a message with a {{code}} placeholder; TACNow substitutes a generated code and delivers it via SMS. You handle verification on your side — TACNow never stores or checks codes.
Base URL
https://api.tacnow.co/v1
All requests require Content-Type: application/json and an Authorization header.
Authentication
Authenticate every request with a Bearer token using an API key from your project dashboard.
Authorization: Bearer sk_live_your_api_key_here
TACNow issues two key types per project:
| Key prefix | Behaviour |
|---|---|
sk_live_ | Sends real SMS, deducts credits |
sk_test_ | No real SMS, no credit deduction |
Keep your live keys secret. Rotate them from the console at any time.
Send OTP
POST /v1/otp/send
Send an OTP to a phone number. TACNow generates a numeric code, replaces {{code}} in your message, and delivers it.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | ✓ | E.164 format — e.g. +60123456789 |
message | string | ✓ | Message template. Must contain {{code}}. Max 160 chars. |
codeLength | integer | — | OTP length, 4–8 digits. Default: 6 |
expiresIn | integer | — | TTL in seconds (informational only — TACNow doesn't verify). Default: 300 |
Response
{
"ok": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "enqueued",
"mode": "live",
"phoneMasked": "****6789"
}
}
Test Mode
Use a sk_test_ API key to develop and test without sending real messages or spending credits.
Authorization: Bearer sk_test_your_test_key
In test mode:
- No SMS is delivered to the recipient
- Credits are not deducted from your project wallet
- The response shape is identical to live mode — your code doesn't need to change
- Delivery logs show
mode: "test"so you can distinguish them in the dashboard
Switch to a sk_live_ key when you're ready to go live. No other code changes needed.
Error Codes
All error responses follow this shape:
{
"ok": false,
"error": "ERROR_CODE",
"message": "Human-readable description"
}
| Code | HTTP | Description |
|---|---|---|
INVALID_API_KEY | 401 | The API key is missing, malformed, or revoked |
INVALID_PHONE | 422 | Phone number is not in E.164 format or is unsupported |
INVALID_TEMPLATE | 422 | Message template is missing {{code}} or exceeds 160 characters |
INSUFFICIENT_CREDITS | 402 | Project wallet has insufficient credits to send |
RATE_LIMITED | 429 | Request rate exceeds the project's per-minute or per-day limit |
PROJECT_ARCHIVED | 403 | The project associated with this API key has been archived |
IP_NOT_ALLOWED | 403 | Request IP is not in the API key's allowlist |
INTERNAL_ERROR | 500 | An unexpected server error occurred — retry with exponential backoff |