Документация API

v1.0.0

Программный доступ к виртуальным номерам, заказам и балансу аккаунта.

Аутентификация

Все API-запросы требуют Bearer token. Сгенерируйте его в разделе Настройки аккаунта в личном кабинете и включайте в каждый запрос:

Authorization: Bearer YOUR_API_TOKEN

Запросы без валидного токена получат ответ 401 UNAUTHORIZED.

Базовый URL

Все пути endpoint ниже указаны относительно:

https://api.smscode.gg/v1

Формат ответов

Каждый ответ возвращает JSON в едином формате. Все ответы содержат заголовок x-request-id для отладки.

Успех
{
  "success": true,
  "data": { ... }
}
Ошибка
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message"
  }
}
GET /catalog/countries

Возвращает список всех доступных стран.

Параметры

Нет

Пример запроса

curl -s https://api.smscode.gg/v1/catalog/countries \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/countries", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/countries",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": [
    {
      "id": 6,
      "code": "ID",
      "name": "Indonesia",
      "dial_code": "+62",
      "emoji": "🇮🇩",
      "active": true
    }
  ]
}
GET /catalog/services

Возвращает список доступных сервисов (платформ). Опционально можно фильтровать по стране.

Query-параметры

НазваниеТипОбязательныйОписание
country_idintegerНетФильтрация сервисов для указанной страны

Пример запроса

curl -s "https://api.smscode.gg/v1/catalog/services?country_id=6" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/services?country_id=6", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/services",
    params={"country_id": 6},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": [
    {
      "id": 3,
      "code": "wa",
      "name": "WhatsApp",
      "active": true
    }
  ]
}
GET /catalog/products

Возвращает постраничный список доступных продуктов. Фильтрация по стране и/или платформе.

Query-параметры

НазваниеТипОбязательныйОписание
country_idintegerНетФильтр по ID страны
platform_idintegerНетФильтр по ID платформы/сервиса
sortstringНетПорядок сортировки: price_asc (по умолчанию), price_desc, available_asc, available_desc, name_asc, name_desc
limitintegerНетРезультатов на странице (1-10 000, по умолчанию 1 000)
pageintegerНетНомер страницы (мин. 1, по умолчанию 1)

Пример запроса

curl -s "https://api.smscode.gg/v1/catalog/products?country_id=6&platform_id=3&limit=10&page=1" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const params = new URLSearchParams({
  country_id: "6", platform_id: "3", limit: "10", page: "1",
});
const res = await fetch(`https://api.smscode.gg/v1/catalog/products?${params}`, {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/products",
    params={"country_id": 6, "platform_id": 3, "limit": 10, "page": 1},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": [
    {
      "id": 142,
      "name": "WhatsApp Indonesia",
      "country_id": 6,
      "platform_id": 3,
      "available": 42,
      "price": 15000,
      "active": true
    }
  ],
  "meta": { "page": 1, "limit": 10, "count": 1 }
}
GET /catalog/exchange-rate

Возвращает текущий обменный курс для валютной пары. Полезно для конвертации цен.

Query-параметры

НазваниеТипОбязательныйОписание
pairstringНетВалютная пара (по умолчанию: USD/IDR)

Пример запроса

curl -s "https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/exchange-rate",
    params={"pair": "USD/IDR"},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "pair": "USD/IDR",
    "base_currency": "USD",
    "quote_currency": "IDR",
    "rate": 16250
  }
}
GET /balance

Возвращает баланс аутентифицированного пользователя в IDR.

Параметры

Нет

Пример запроса

curl -s https://api.smscode.gg/v1/balance \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/balance", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/balance",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "currency": "IDR",
    "balance": 500000
  }
}
GET /orders

Возвращает список заказов аутентифицированного пользователя, отсортированный по дате (новые первыми). Поддерживает фильтрацию по статусу и пагинацию через offset.

Query-параметры

НазваниеТипОбязательныйОписание
limitintegerНетМакс. результатов (1-100, по умолчанию 20)
offsetintegerНетКоличество пропускаемых результатов (по умолчанию 0)
statusstringНетФильтр по статусу: ACTIVE, OTP_RECEIVED, COMPLETED, CANCELED, EXPIRED (регистронезависимый)

Пример запроса

curl -s "https://api.smscode.gg/v1/orders?limit=5&status=ACTIVE" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const params = new URLSearchParams({
  limit: "5", status: "ACTIVE", offset: "0",
});
const res = await fetch(`https://api.smscode.gg/v1/orders?${params}`, {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders",
    params={"limit": 5, "status": "ACTIVE", "offset": 0},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": [
    {
      "id": 1001,
      "status": "ACTIVE",
      "created_at": "2026-02-25T10:00:00Z",
      "product_id": 142,
      "phone_number": "+6281234567890",
      "amount": 15000,
      "otp_code": null,
      "otp_received_at": null,
      "expires_at": "2026-02-25T10:20:00Z",
      "canceled_at": null,
      "failed_reason": null
    }
  ]
}
GET /orders/{id}

Возвращает один заказ по ID. Доступны только заказы аутентифицированного пользователя.

Path-параметры

НазваниеТипОбязательныйОписание
idintegerДаID заказа (path-параметр)

Пример запроса

curl -s https://api.smscode.gg/v1/orders/1001 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/orders/1001", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders/1001",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "id": 1001,
    "status": "OTP_RECEIVED",
    "created_at": "2026-02-25T10:00:00Z",
    "product_id": 142,
    "phone_number": "+6281234567890",
    "amount": 15000,
    "otp_code": "123456",
    "otp_received_at": "2026-02-25T10:05:00Z",
    "expires_at": "2026-02-25T10:20:00Z",
    "canceled_at": null,
    "failed_reason": null
  }
}
GET /orders/active

Список всех активных заказов (ACTIVE + OTP_RECEIVED). Используйте для отслеживания статуса OTP.

Параметры

Нет

Пример запроса

curl -s https://api.smscode.gg/v1/orders/active \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/orders/active", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders/active",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": [
    {
      "id": 1001,
      "status": "OTP_RECEIVED",
      "otp_code": "123456",
      "otp_message": "Your verification code is 123456",
      "otp_received_at": "2026-02-25T10:05:00Z",
      "expires_at": "2026-02-25T10:20:00Z",
      "failed_reason": null
    },
    {
      "id": 1002,
      "status": "ACTIVE",
      "otp_code": null,
      "otp_message": null,
      "otp_received_at": null,
      "expires_at": "2026-02-25T10:50:00Z",
      "failed_reason": null
    }
  ]
}
POST /orders/create

Создаёт новый заказ виртуального номера. Баланс списывается автоматически. Поддерживает опциональный заголовок Idempotency-Key для предотвращения дублирования заказов при повторных запросах.

Тело запроса

НазваниеТипОбязательныйОписание
product_idintegerДаID продукта для заказа
quantityintegerНетКоличество (1-100, по умолчанию 1)

Передайте заголовок Idempotency-Key (любая уникальная строка) для безопасного повторения запросов без создания дубликатов.

Пример запроса

curl -s -X POST https://api.smscode.gg/v1/orders/create \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-123" \
  -d '{"product_id":142,"quantity":1}'
const res = await fetch("https://api.smscode.gg/v1/orders/create", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
    "Idempotency-Key": "unique-request-id-123",
  },
  body: JSON.stringify({ product_id: 142, quantity: 1 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/create",
    json={"product_id": 142, "quantity": 1},
    headers={
        "Authorization": "Bearer YOUR_API_TOKEN",
        "Idempotency-Key": "unique-request-id-123",
    })
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "orders": [
      {
        "id": 1002,
        "status": "ACTIVE",
        "phone_number": "+6281234567891",
        "otp_code": null,
        "otp_received_at": null,
        "expires_at": "2026-02-25T10:50:00Z",
        "failed_reason": null
      }
    ],
    "failed_count": 0
  }
}
POST /orders/cancel

Отмена активного заказа. Стоимость аренды возвращается на баланс аккаунта.

Тело запроса

НазваниеТипОбязательныйОписание
idintegerДаID заказа для отмены

Пример запроса

curl -s -X POST https://api.smscode.gg/v1/orders/cancel \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/cancel", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/cancel",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "CANCELED",
    "refund_amount": 15000,
    "new_balance": 515000
  }
}
POST /orders/finish

Отметить заказ как завершённый после получения OTP. Номер освобождается сразу, без ожидания истечения срока.

Тело запроса

НазваниеТипОбязательныйОписание
idintegerДаID заказа для завершения

Пример запроса

curl -s -X POST https://api.smscode.gg/v1/orders/finish \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/finish", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/finish",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "COMPLETED"
  }
}
POST /orders/resend

Запросить повторную отправку SMS на арендованный номер. Не все платформы поддерживают повторную отправку — проверяйте поле resent в ответе.

Тело запроса

НазваниеТипОбязательныйОписание
idintegerДаID заказа для повторной отправки SMS

Пример запроса

curl -s -X POST https://api.smscode.gg/v1/orders/resend \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/resend", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/resend",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "ACTIVE",
    "resent": true
  }
}
GET /webhook

Возвращает текущую конфигурацию webhook-уведомлений.

Параметры

Нет

Пример запроса

curl -s https://api.smscode.gg/v1/webhook \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/webhook", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/webhook",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "webhook_url": "https://example.com/webhook",
    "webhook_secret": "a1b2c3d4e5f6..."
  }
}
PATCH /webhook

Обновить URL и/или секрет webhook. Секрет генерируется автоматически при первой установке URL. Отправьте пустую строку для очистки. URL должен использовать HTTPS.

Тело запроса

НазваниеТипОбязательныйОписание
webhook_urlstringНетHTTPS URL для получения webhook-событий (пустая строка для очистки)
webhook_secretstringНетОбщий секрет для подписи HMAC-SHA256 (генерируется автоматически, если не указан при первой настройке)

Необходимо указать хотя бы одно поле.

Пример запроса

curl -s -X PATCH https://api.smscode.gg/v1/webhook \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhook_url":"https://example.com/webhook"}'
const res = await fetch("https://api.smscode.gg/v1/webhook", {
  method: "PATCH",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ webhook_url: "https://example.com/webhook" }),
});
const data = await res.json();
import requests

res = requests.patch("https://api.smscode.gg/v1/webhook",
    json={"webhook_url": "https://example.com/webhook"},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "webhook_url": "https://example.com/webhook",
    "webhook_secret": "a1b2c3d4e5f6..."
  }
}
POST /webhook/test

Отправить тестовое событие на настроенный webhook URL. Возвращает HTTP-код ответа вашего сервера. Полезно для проверки работоспособности endpoint перед боевым использованием.

Параметры

Нет

Пример запроса

curl -s -X POST https://api.smscode.gg/v1/webhook/test \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/webhook/test", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/webhook/test",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Пример ответа

200 OK
{
  "success": true,
  "data": {
    "status_code": 200
  }
}

Webhook-уведомления

Настройте webhook URL для получения push-уведомлений в реальном времени о событиях заказов вместо периодического опроса. Рекомендуемый подход для бот-скриптов.

События

СобытиеТриггер
order.otp_receivedOTP-код доставлен на арендованный номер
order.completedЗаказ отмечен как завершённый (вручную или по истечении срока)
order.expiredЗаказ истёк без OTP (баланс возвращён)
order.canceledЗаказ отменён пользователем (баланс возвращён)

Тело запроса

Тело POST-запроса webhook
{
  "event": "order.otp_received",
  "timestamp": "2026-02-25T12:00:00Z",
  "data": {
    "order_id": 1001,
    "phone_number": "+628123456789",
    "otp_code": "1234",
    "otp_message": "Your verification code is 1234",
    "product_id": 42,
    "country": "Indonesia",
    "platform": "WhatsApp"
  }
}

Проверка подписи

Каждый webhook-запрос содержит заголовок X-Webhook-Signature с HMAC-SHA256 подписью тела запроса, используя ваш webhook_secret в качестве ключа:

X-Webhook-Signature: sha256={HMAC-SHA256(body, webhook_secret)}

Проверяйте эту подпись на своём сервере для подтверждения подлинности запроса. Доставка — однократная, с таймаутом 3 секунды, без повторов.

Rate Limits

API-запросы ограничены по частоте для каждой группы endpoint. Превышение лимита возвращает 429 Too Many Requests с заголовком Retry-After, указывающим время ожидания в секундах.

Группа endpointЛимитОкно
Каталог (countries, services, products, exchange-rate)1 200 запросов60 секунд
Баланс600 запросов60 секунд
Чтение заказов (list, get, active)1 200 запросов60 секунд
Создание заказа1 200 запросов60 секунд
Отмена заказа600 запросов60 секунд
Действия с заказом (finish, resend)600 запросов60 секунд
Настройка webhook (get, update, test)120 запросов60 секунд

Коды ошибок

Ответы с ошибкой содержат один из следующих кодов в error.code:

КодHTTPОписание
UNAUTHORIZED401Отсутствует или недействителен API-токен
FORBIDDEN403Доступ запрещён
NOT_FOUND404Ресурс не найден (заказ, обменный курс и т.д.)
CONFLICT409Дублирующий запрос или конфликт ресурсов
INSUFFICIENT_BALANCE409Недостаточно средств на балансе
VALIDATION_ERROR422Параметры запроса не прошли валидацию
RATE_LIMIT_EXCEEDED429Слишком много запросов (проверьте заголовок Retry-After)
INTERNAL_ERROR500Внутренняя ошибка сервера
PROVIDER_ERROR422Вышестоящий SMS-провайдер отклонил запрос
CANCEL_TOO_EARLY409Заказ слишком новый для отмены — подождите 2 минуты
SERVICE_UNAVAILABLE503Сервис временно недоступен (обслуживание)