TikoSMS API Documentation

Last updated: October 12, 2026

Introduction

This documentation aims to provide all the information you need to work with our API. As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile). You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).

Getting Started

All API endpoints require authentication using Bearer tokens.

Obtaining API Token

  1. Register at https://tikosms.com/register
  2. Login to your account
  3. Navigate to your profile at https://tikosms.com/profile
  4. Generate your API token in the API section

Using API Token

Include your token in every request header:

Authorization: Bearer YOUR_API_TOKEN_HERE
Content-Type: application/json

Webhooks (Callbacks)

TikoSMS can send delivery reports to your server via HTTP POST requests.

Setting up callbacks:

  1. Include callback_url parameter in your SMS request
  2. Ensure your endpoint accepts POST requests
  3. Return HTTP 200 status to acknowledge receipt

Callback types:

  • create - Initial callback when SMS is accepted (status: SENT)
  • update - Final callback with delivery status (status: DELIVRD, UNDELIV, etc.)

Callback security:

  • All callbacks include a timestamp for verification
  • Callbacks are sent from TikoSMS servers with User-Agent: TikoSMS-Callback/1.0
  • Implement proper validation on your endpoint

Example "create" callback (SMS accepted):

{
  "create": {
    "message_id": "6fcfcd12-8ea5-4e45-b1b7-66e3f5e67600",
    "from": "MySender",
    "to": "380501234567",
    "status": "SENT",
    "sent_at": "2025-08-06 15:32:18"
    "callback_url": "https://yoursite.com/callback",
    "client_ref": "order-123",
    "mccmnc": "255001",
    "cost": 0.045,
    "part": 1,
    "total_parts": 1,
  }
}

Example "update" callback (final status):

{
  "update": {
    "message_id": "6fcfcd12-8ea5-4e45-b1b7-66e3f5e67600",
    "from": "MySender",
    "to": "380501234567",
    "status": "DELIVRD",
    "delivered_at": "2025-08-06 15:33:45",
    "callback_url": "https://yoursite.com/callback",
    "client_ref": "order-123",
    "mccmnc": "255001",
    "cost": 0.045,
    "part": 1,
    "total_parts": 1,
    "timestamp": "2025-08-06T15:33:45.123"
  }
}

### SMS Status Values

All SMS operations use these standard status codes:

- `SENT` - Message accepted for delivery
- `DELIVRD` - Successfully delivered to handset
- `UNDELIV` - Failed to deliver
- `EXPIRED` - Message expired before delivery
- `REJECTD` - Rejected by carrier
- `UNKNOWN` - Status unknown

### Example Request

```bash
curl -X POST https://api.tikosms.com/api/v1/message \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "MySender",
    "to": "380501234567",
    "message": "Your OTP is 1234",
    "callback_url": "https://yoursite.com/sms-callback"
  }'

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your token in your profile settings.

Balance

Get current user's SMS balance

GET
https://api.tikosms.com
/v1/balance
requires authentication

Requires authentication via Bearer token.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json
Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/balance" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "balance_updated": "2025.07.03 13:34:34",
    "currency_code": "EUR",
    "balance": 634.9288,
    "in_credit_limit": 1000
}
{
    "error": "User not authenticated"
}

SMS API

POST v1/messages

POST
https://api.tikosms.com
/v1/messages
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://api.tikosms.com/v1/messages" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"from\": \"MyBrand\",
    \"message\": \"Big sale today!\",
    \"recipients\": [
        {
            \"to\": \"380501234567\",
            \"client_ref\": \"order-1\"
        }
    ],
    \"callback_url\": \"https:\\/\\/example.com\\/callback\",
    \"scheduled_at\": \"2025-08-12 10:00:00\",
    \"concurrency\": 20
}"
Example response:
{
    "success": true,
    "campaign_id": "bc7f100a-bebb-4449-8f5a-cf5154ef2fcf",
    "recipients_count": 3,
    "duplicates_removed": 0,
    "message": "Campaign queued successfully"
}
{
    "success": false,
    "error": "Validation failed",
    "errors": {
        "recipients.1.message": [
            "Provide a message here, or a shared `message` for the whole batch."
        ]
    }
}
{
    "success": false,
    "error": "Invalid callback URL provided"
}

POST v1/message

POST
https://api.tikosms.com
/v1/message
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://api.tikosms.com/v1/message" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"from\": \"MySender\",
    \"message\": \"Your OTP is 1234\",
    \"to\": \"380501234567\",
    \"callback_url\": \"https:\\/\\/yourdomain.com\\/sms-callback\",
    \"client_ref\": \"invoice-10294\"
}"
Example response:
{
    "success": true,
    "message_id": "d3b0e5a1-2224-4a7e-8b12-7c61d3a7bfb9",
    "campaign_id": "7e9d2a5c-3b8e-4b8d-9b5f-1a2c3d4e5f60"
}
{
    "success": false,
    "error": "No SMS rate is available for this destination for your account. Please contact sales team."
}
{
    "success": false,
    "error": "Oops! We couldn't find this number in any country on Earth. Mind giving it another look?"
}

GET v1/get_messages

GET
https://api.tikosms.com
/v1/get_messages
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

campaign_id
string

uuid Filter to a single campaign.

Body Parameters

Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/get_messages" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"campaign_id\": \"6ff8f7f6-1eb3-3525-be4a-3932c805afed\"
}"
Example response:
{
    "success": true,
    "campaigns": [
        {
            "campaign_id": "bc7f100a-bebb-4449-8f5a-cf5154ef2fcf",
            "sender": "MyBrand",
            "message": "Big sale today!",
            "recipients": 1,
            "created_at": "2025-08-11T13:12:34.000000Z",
            "updated_at": "2025-08-11T13:12:34.000000Z"
        }
    ]
}
{
    "success": false,
    "error": "Campaign not found"
}

GET v1/get_message

GET
https://api.tikosms.com
/v1/get_message
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

message_id
string

The UUID of the message.

Example:
d3b0e5a1-2224-4a7e-8b12-7c61d3a7bfb9
campaign_id
string

The UUID of the campaign.

Example:
7e9d2a5c-3b8e-4b8d-9b5f-1a2c3d4e5f60

Body Parameters

Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/get_message?message_id=d3b0e5a1-2224-4a7e-8b12-7c61d3a7bfb9&campaign_id=7e9d2a5c-3b8e-4b8d-9b5f-1a2c3d4e5f60" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"message_id\": \"b\",
    \"campaign_id\": \"n\"
}"
Example response:
{
    "success": true,
    "data": [
        {
            "message_id": "d3b0e5a1-2224-4a7e-8b12-7c61d3a7bfb9",
            "campaign_id": "7e9d2a5c-3b8e-4b8d-9b5f-1a2c3d4e5f60",
            "to": "380501234567",
            "message": "Your code is 1234",
            "from": "MySender",
            "sender_type": "Alpha",
            "status": "DELIVRD",
            "data_coding": 0,
            "mccmnc": "25501",
            "cost": "0.050",
            "part": 1,
            "total_parts": 1,
            "sent_at": "2025-08-06 12:35:18",
            "delivered_at": "2025-08-06 12:35:19",
            "client_ref": "order-123",
            "callback_url": "https://example.com/sms-callback"
        }
    ]
}
{
    "success": false,
    "error": "Message(s) not found"
}

SMS Rates

GET v1/sms-rates

GET
https://api.tikosms.com
/v1/sms-rates
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

mccmnc
string
required

MCCMNC code (e.g. 255001 or 255).

Example:
255001
country
string

Country name.

Example:
Ukraine
Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/sms-rates?mccmnc=255001&country=Ukraine" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "success": true,
    "rate": {
        "mcc": "255",
        "mnc": "001",
        "mccmnc": "255001",
        "country": "Ukraine",
        "rate": "0.045000",
        "rate_start_date": "2025-08-01 00:00:00",
        "rate_end_date": "2100-01-01 00:00:00"
    }
}
{
    "success": false,
    "error": "No SMS rate found for this destination."
}

Number Lookup (HLR)

Find out where a mobile number is right now: the network that serves it, whether it was ported away from the network it was issued by, and whether the network confirms the subscriber is active.

How it works

  1. Optionally price your list with POST /v1/lookups/quote. It is free and holds nothing.
  2. Submit the list with POST /v1/lookups. The quoted amount is held on your balance.
  3. Poll GET /v1/lookups/{id} until status is completed.
  4. Fetch the answers with GET /v1/lookups/{id}/results.

What you pay. Each number is charged at its actual price when its result arrives. The held amount is an upper bound: whatever is not used goes back to your balance when the batch completes. Numbers that cannot be looked up (an invalid number, an unsupported destination) are not charged.

Price a list

POST
https://api.tikosms.com
/v1/lookups/quote
requires authentication

Returns the price of a list and what your balance allows, without submitting anything. Nothing is held or charged.

The total is an upper bound (ceiling: true): the actual charge per number is known only once its result arrives, and is often lower.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Response Fields

Example request:
curl --request POST \
    "https://api.tikosms.com/v1/lookups/quote" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"numbers\": [
        \"37253004550\",
        \"37253004551\"
    ]
}"
Example response:
{
    "numbers": 2,
    "balance": {
        "account": 100,
        "held": 0,
        "pending_charges": 0,
        "available": 100,
        "currency": "EUR"
    },
    "methods": {
        "auto": {
            "method": "auto",
            "numbers": 2,
            "total": 0.09,
            "currency": "EUR",
            "ceiling": true,
            "breakdown": [
                {
                    "country_code": "372",
                    "count": 2,
                    "unit_price": 0.045,
                    "subtotal": 0.09
                }
            ],
            "unknown_country": 0,
            "unpriced": 0,
            "affordable": true,
            "shortfall": 0
        }
    }
}

Submit numbers for lookup

POST
https://api.tikosms.com
/v1/lookups
requires authentication

Holds the quoted amount on your balance and starts the lookup. Returns 202 straight away; results arrive over the next minutes.

A list longer than 10,000 numbers is split into several batches, each with its own id. Send an Idempotency-Key header to make a retry safe: the same key returns the batches the first request created instead of starting — and paying for — the lookup again.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Idempotency-Key
Example:
A unique value per list, e.g. a UUID. Example: 2f6b1c9e-8a43-4d2e-9b71-0c5d3e8f4a12
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://api.tikosms.com/v1/lookups" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Idempotency-Key: A unique value per list, e.g. a UUID. Example: 2f6b1c9e-8a43-4d2e-9b71-0c5d3e8f4a12" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"numbers\": [
        \"37253004550\",
        \"37253004551\"
    ],
    \"method\": \"auto\"
}"
Example response:
{
    "estimated_total": 0.09,
    "currency": "EUR",
    "batches": [
        {
            "id": "9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10",
            "method": "auto",
            "status": "submitted",
            "numbers": 2,
            "completed": 0,
            "failed": 0,
            "skipped": 0,
            "estimated_total": 0.09,
            "charged_total": 0,
            "currency": "EUR",
            "created_at": "2026-10-07T10:15:00+00:00",
            "completed_at": null
        }
    ]
}
{
    "error": "insufficient_funds",
    "message": "Insufficient funds: 12.40 EUR available, 67.50 EUR required.",
    "available": 12.4,
    "required": 67.5,
    "shortfall": 55.1,
    "currency": "EUR"
}
{
    "error": "unpriced",
    "message": "No auto rate covers 3 of these numbers.",
    "quote": {}
}
{
    "error": "service_unavailable",
    "message": "The lookup service is temporarily unavailable. Nothing was charged — please try again shortly.",
    "retryable": true
}

Get batch progress

GET
https://api.tikosms.com
/v1/lookups/{batch}
requires authentication

Poll this until status is completed. Do not wait for completed to equal numbers: a network may never answer for some numbers, and the batch completes without them.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

batch
string
required

The batch id from the submit response.

Example:
9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10

Response Fields

Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/lookups/9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "id": "9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10",
    "method": "auto",
    "status": "running",
    "numbers": 2,
    "completed": 1,
    "failed": 0,
    "skipped": 0,
    "estimated_total": 0.09,
    "charged_total": 0.0023,
    "currency": "EUR",
    "created_at": "2026-10-07T10:15:00+00:00",
    "completed_at": null
}
{
    "message": "Batch not found."
}

Get batch results

GET
https://api.tikosms.com
/v1/lookups/{batch}/results
requires authentication

One row per number, available while the batch is running and after it completes.

Read answer before trusting the network fields. live means a network was queried and the fields describe where the number is now. prefix means no network answered: the fields describe the range the number was issued in, which is exactly what a ported number gets wrong.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

batch
string
required

The batch id.

Example:
9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10

Query Parameters

status
string

Only rows with this status: ok, failed or skipped.

Example:
ok
answer
string

Only live or only prefix answers.

Example:
live
ported
boolean

1 for ported numbers only, 0 for numbers known not to be ported.

Example:
true
present
boolean

1 for numbers the network confirmed active.

Example:
true
page
integer

Page number.

Example:
1
per_page
integer

Rows per page, up to 1000. Default: 500.

Example:
500

Response Fields

Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/lookups/9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10/results?status=ok&answer=live&ported=1&present=1&page=1&per_page=500" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "batch_id": "9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10",
    "data": [
        {
            "number": "37253004550",
            "status": "ok",
            "answer": "live",
            "network": "Elisa Eesti",
            "country": "Estonia",
            "mcc_mnc": "248002",
            "original_network": "Telia Eesti",
            "original_mcc_mnc": "248001",
            "ported": true,
            "present": true,
            "mnc_ambiguous": false,
            "imsi": "248021234567890",
            "msc": "37256000001",
            "error": null,
            "skip_reason": null,
            "price": 0.0023,
            "checked_at": "2026-10-07T10:15:42+00:00"
        }
    ],
    "page": 1,
    "per_page": 500,
    "total": 1,
    "total_pages": 1
}

List batches

GET
https://api.tikosms.com
/v1/lookups
requires authentication

Your batches, newest first.

Headers

Authorization
Example:
Bearer {YOUR_TOKEN}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

page
integer

Page number.

Example:
1
per_page
integer

Batches per page, up to 100. Default: 25.

Example:
25
Example request:
curl --request GET \
    --get "https://api.tikosms.com/v1/lookups?page=1&per_page=25" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "data": [
        {
            "id": "9c1f6a52-3e2b-4b8e-a1d4-5f0c2e7b9a10",
            "method": "auto",
            "status": "completed",
            "numbers": 2,
            "completed": 2,
            "failed": 0,
            "skipped": 0,
            "estimated_total": 0.09,
            "charged_total": 0.0046,
            "currency": "EUR",
            "created_at": "2026-10-07T10:15:00+00:00",
            "completed_at": "2026-10-07T10:16:12+00:00"
        }
    ],
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
}