• 228 направлений
  • Без KYC — всегда
  • Bitcoin, Monero, USDT и ещё 4 валюты

Быстрый старт

Первое сообщение
за пять шагов.

От пустого аккаунта до доставленного SMS и подтверждающего вебхука. Выберите язык один раз — все примеры на странице переключатся вместе.

Перед началом

  • Адрес электронной почты для создания аккаунта
  • Терминал или любой HTTP-клиент
  • Несколько долларов в криптовалюте для реальных отправок; тестовый ключ бесплатен
  • Около пяти минут

Шаг 1 из 5

Создайте аккаунт и ключ API

Зарегистрируйтесь по адресу электронной почты и подтвердите его. В панели откройте Разработчикам, затем Создать ключ. Выберите области send и read. Ключ показывается один раз: скопируйте его в переменную окружения и никогда не добавляйте в систему контроля версий.

  • Ключ скопирован
  • Экспортирован как SMSMETEOR_KEY
Командная строка
# macOS, Linux
export SMSMETEOR_KEY="sk_test_4b8e...c19d"

# Windows PowerShell
$env:SMSMETEOR_KEY = "sk_test_4b8e...c19d"

Шаг 2 из 5

Пополните баланс

При использовании тестового ключа пропустите этот шаг. Для реальной отправки откройте Баланс, выберите монету и переведите указанную сумму на адрес пополнения. После обнаружения в сети платёж получает статус ожидания, а после подтверждения зачисляется в USD: за несколько секунд в Tron или Solana и за 10–60 минут в Bitcoin.

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

ЗапросGET /v1/balance
curl https://api.smsmeteor.com/v1/balance \
  -H "Authorization: Bearer $SMSMETEOR_KEY"
200 OK
{ "balance": "250.00", "currency": "USD",
  "pending": "0.00", "low_threshold": "25.00" }

Шаг 3 из 5

Отправьте сообщение

Один POST: направление в формате E.164, отправитель и текст. Всегда добавляйте Idempotency-Key; при сетевом сбое и повторе API вернёт исходное сообщение вместо отправки второго.

В ответе сразу указаны количество сегментов и цена. Для направления без покрытия возвращается 422 unsupported_destination, средства не списываются.

  • Получен id, начинающийся с msg_
  • status равен queued либо test для тестового ключа
POST /v1/messages
curl https://api.smsmeteor.com/v1/messages \
  -H "Authorization: Bearer $SMSMETEOR_KEY" \
  -H "Idempotency-Key: first-message-001" \
  -d to="+14155550142" \
  -d from="METEOR" \
  -d text="Привет от SMSMeteor!"
import os, requests

r = requests.post(
    "https://api.smsmeteor.com/v1/messages",
    headers={"Authorization": f"Bearer {os.environ['SMSMETEOR_KEY']}",
             "Idempotency-Key": "first-message-001"},
    json={"to": "+14155550142", "from": "METEOR",
          "text": "Привет от SMSMeteor!"},
)
msg = r.json()
print(msg["id"], msg["status"], msg["price"])
const r = await fetch("https://api.smsmeteor.com/v1/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMSMETEOR_KEY}`,
    "Idempotency-Key": "first-message-001",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ to: "+14155550142", from: "METEOR",
    text: "Привет от SMSMeteor!" }),
});
const msg = await r.json();
console.log(msg.id, msg.status, msg.price);
$ch = curl_init('https://api.smsmeteor.com/v1/messages');
curl_setopt_array($ch, [
  CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('SMSMETEOR_KEY'),
    'Idempotency-Key: first-message-001', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS => json_encode(['to' => '+14155550142',
    'from' => 'METEOR', 'text' => 'Привет от SMSMeteor!']),
]);
$msg = json_decode(curl_exec($ch), true);
echo $msg['id'], ' ', $msg['status'], ' ', $msg['price'];
201 Created
{
  "id": "msg_9Kd2fQ",
  "status": "queued",
  "to": "+14155550142",
  "from": "METEOR",
  "segments": 1,
  "encoding": "gsm7",
  "price": "0.0084",
  "currency": "USD",
  "created_at": "2026-09-21T11:42:07Z"
}

Шаг 4 из 5

Получите статус

Получите сообщение по идентификатору. Статусы изменяются только вперёд: В очередиОтправлено, затем Доставлено, Ошибка или Срок истёк. Большинство доставок подтверждается за несколько секунд; некоторые операторы связи отправляют отчёты пакетами.

Для одного сообщения подойдёт опрос. Для большего объёма используйте вебхук из следующего шага.

GET /v1/messages/{id}
curl https://api.smsmeteor.com/v1/messages/msg_9Kd2fQ \
  -H "Authorization: Bearer $SMSMETEOR_KEY"
r = requests.get(
    "https://api.smsmeteor.com/v1/messages/msg_9Kd2fQ",
    headers={"Authorization": f"Bearer {os.environ['SMSMETEOR_KEY']}"},
)
print(r.json()["status"])
const r = await fetch("https://api.smsmeteor.com/v1/messages/msg_9Kd2fQ", {
  headers: { Authorization: `Bearer ${process.env.SMSMETEOR_KEY}` },
});
console.log((await r.json()).status);
$ch = curl_init('https://api.smsmeteor.com/v1/messages/msg_9Kd2fQ');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('SMSMETEOR_KEY')]]);
echo json_decode(curl_exec($ch), true)['status'];
200 OK
{ "id": "msg_9Kd2fQ", "status": "delivered",
  "sent_at": "2026-09-21T11:42:08Z",
  "delivered_at": "2026-09-21T11:42:10Z",
  "carrier_code": null, "price": "0.0084" }

Шаг 5 из 5

Получите вебхук

В панели откройте РазработчикамВебхукиДобавить конечную точку. Укажите HTTPS URL, подпишитесь на message.delivered и message.failed и скопируйте секрет конечной точки. Проверяйте подпись до обработки данных, затем возвращайте любой 2xx в течение 5 секунд.

  • Конечная точка отвечает 200
  • Подпись проверена по исходному телу
Ваша конечная точка
# Имитация подписанного события для локальной конечной точки
TS=$(date +%s)
BODY='{"id":"evt_test","type":"message.delivered","data":{"message_id":"msg_9Kd2fQ"}}'
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$HOOK_SECRET" | awk '{print $2}')

curl -X POST http://localhost:3000/hooks/sms \
  -H "X-Meteor-Timestamp: $TS" \
  -H "X-Meteor-Signature: t=$TS,v1=$SIG" \
  -H "Content-Type: application/json" -d "$BODY"
import hmac, hashlib, time
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/hooks/sms")
def hook():
    ts = request.headers["X-Meteor-Timestamp"]
    sig = request.headers["X-Meteor-Signature"].split("v1=")[1]
    mac = hmac.new(SECRET.encode(), f"{ts}.".encode() + request.data,
                   hashlib.sha256).hexdigest()
    if abs(time.time() - int(ts)) > 300 or not hmac.compare_digest(mac, sig):
        abort(400)
    event = request.get_json()
    print(event["type"], event["data"]["message_id"])
    return "", 200
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";

const app = express();
app.post("/hooks/sms", express.raw({ type: "application/json" }), (req, res) => {
  const ts = req.get("X-Meteor-Timestamp");
  const sig = req.get("X-Meteor-Signature").split("v1=")[1];
  const mac = createHmac("sha256", process.env.HOOK_SECRET)
    .update(`${ts}.${req.body}`).digest("hex");
  if (!timingSafeEqual(Buffer.from(mac), Buffer.from(sig))) return res.sendStatus(400);
  const event = JSON.parse(req.body);
  console.log(event.type, event.data.message_id);
  res.sendStatus(200);
});
$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_METEOR_TIMESTAMP'];
$sig = explode('v1=', $_SERVER['HTTP_X_METEOR_SIGNATURE'])[1];
$mac = hash_hmac('sha256', $ts . '.' . $raw, getenv('HOOK_SECRET'));
if (abs(time() - (int) $ts) > 300 || !hash_equals($mac, $sig)) { http_response_code(400); exit; }
$event = json_decode($raw, true);
error_log($event['type'] . ' ' . $event['data']['message_id']);
http_response_code(200);
Тело события
{ "id": "evt_4Qm8Xz", "type": "message.delivered",
  "created_at": "2026-09-21T11:42:10Z",
  "data": { "message_id": "msg_9Kd2fQ", "status": "delivered",
            "to": "+14155550142", "price": "0.0084" } }

Устранение неполадок

401 unauthorized

Заголовок должен иметь вид Authorization: Bearer sk_… без кавычек вокруг ключа. Убедитесь, что ключ не отозван, имеет область send, а ваш IP входит в список разрешённых, если он задан.

402 insufficient_balance

Доступный баланс меньше цены сообщения. Во время интеграции используйте тестовый ключ или пополните баланс; пополнение со статусом pending пока нельзя потратить.

400 invalid_number

Номер должен соответствовать E.164: плюс, код страны и национальный номер без начального нуля и пробелов. Например, +447700900123, а не 07700 900123.

Сообщение остаётся в статусе sent

Некоторые операторы связи возвращают отчёты пакетами или не возвращают вовсе; это указано на странице страны. Через 48 часов без отчёта сообщение получает статус expired.

Получатель видит номер вместо моего имени

В этом направлении буквенно-цифровые отправители не поддерживаются или требуют регистрации. Поле from показывает фактически использованного отправителя. См. имена отправителей и маршруты.

Вебхук не срабатывает

Конечная точка должна использовать HTTPS с действительным сертификатом и отвечать в течение 5 секунд. В панели перечислены все попытки и полученные ответы; после исправления повторите событие оттуда.

Следующие шаги