Перейти к содержимому
cleat.

Для разработчиков и QA

SMS на настоящий номер США — прямо в ваш код.

Настоящая мобильная линия США, не VoIP, которая передаёт каждое входящее SMS вашему коду. Подписанный вебхук срабатывает, как только SMS сохранено. REST API отдаёт список и позволяет опрашивать. У остальных в команде по-прежнему есть входящие в реальном времени, почта и Telegram. Одна линия, 24,99 $ в месяц, отменить можно в любой момент.

Почему не номер телеком-платформы?

Программируемые номера телеком-платформ обычно классифицируются как VoIP. В статье самой Twilio о фильтрации VoIP перед отправкой кодов её Lookup помечает номер Twilio как nonFixedVoip (Twilio). Если сервис фильтрует VoIP, его код до номера платформы не дойдёт. Линия Cleat — мобильная. В этом и весь смысл. Подробнее о типах номеров.

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

  1. Получите линию. Зарегистрируйтесь и оформите подписку. Список линий доступен сразу; чтение SMS на линии отвечает 403, пока владелец аккаунта не подтвердит личность.
  2. Создайте API-ключ в разделе Settings. Он начинается с clt_ и показывается один раз. Если удобнее сгенерировать клиент, весь контракт API описан в OpenAPI.
  3. Добавьте эндпоинт вебхука в разделе Settings, если нужны push-уведомления: публичный HTTPS-адрес. Его секрет подписи начинается с whsec_ и показывается один раз.
  4. Получите список линий, затем опрашивайте API или ждите вебхуков.
Список линий в рабочем пространстве
curl https://cleat.so/api/v1/lines \
  -H "Authorization: Bearer $CLEAT_API_KEY"
Ответ
{
  "data": [
    {
      "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10",
      "phone": "13055550100",
      "label": "Staging sign-ups",
      "status": "active",
      "createdAt": "2026-09-11T10:00:00.000Z"
    }
  ]
}
SMS, полученные после указанного момента, от старых к новым
curl "https://cleat.so/api/v1/lines/$LINE_ID/messages?after=2026-09-11T10:00:00Z&limit=50" \
  -H "Authorization: Bearer $CLEAT_API_KEY"
Ответ
{
  "data": [
    {
      "id": "c9a7e0d2-5b1f-4e8a-9f3c-6d2b1a0e4f77",
      "line": { "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "phone": "13055550100", "label": "Staging sign-ups" },
      "from": "32665",
      "body": "704118 is your Facebook confirmation code",
      "code": "704118",
      "receivedAt": "2026-09-11T10:02:41.000Z",
      "service": { "id": "facebook", "name": "Facebook", "color": "#0866FF" },
      "contact": null,
      "label": "Facebook"
    }
  ]
}

Вебхуки

Когда приходит SMS, Cleat отправляет POST на каждый ваш эндпоинт с таким JSON-телом, заголовком cleat-signature и User-Agent Cleat-Webhooks/1.0:

Тело запроса
{
  "type": "message.received",
  "data": {
    "id": "c9a7e0d2-5b1f-4e8a-9f3c-6d2b1a0e4f77",
    "line": { "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "phone": "13055550100", "label": "Staging sign-ups" },
    "from": "32665",
    "body": "704118 is your Facebook confirmation code",
    "code": "704118",
    "receivedAt": "2026-09-11T10:02:41.000Z",
    "service": { "id": "facebook", "name": "Facebook", "color": "#0866FF" },
    "contact": null,
    "label": "Facebook"
  }
}

Заголовок подписи выглядит так: t=1789120961,v1=5d41…. v1 — HMAC-SHA256 в шестнадцатеричном виде от метки времени, точки и сырого тела запроса; ключ — секрет подписи эндпоинта. Проверяйте подпись по сырым байтам, до разбора тела. Отклоняйте старые метки времени, чтобы защититься от повторной отправки.

Проверка и обработка доставки (Node.js, Express)
import crypto from "node:crypto";
import express from "express";

const app = express();
const secret = process.env.CLEAT_WEBHOOK_SECRET; // whsec_…

// cleat-signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "t.body">
function verified(header, body) {
  const parts = Object.fromEntries(String(header).split(",").map((part) => part.split("=")));
  const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return fresh && parts.v1?.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}

app.post("/cleat-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const body = req.body.toString("utf8");
  if (!verified(req.get("cleat-signature"), body)) return res.sendStatus(401);

  const { type, data } = JSON.parse(body);
  if (type === "message.received") {
    // data.code is Cleat's best guess at a one-time code; data.body is the full text.
    console.log(data.line.phone, data.from, data.code ?? data.body);
  }
  res.sendStatus(200);
});

app.listen(3000);

Как работает доставка

  • Эндпоинты должны быть публичными адресами https://. Cleat не переходит по редиректам.
  • Ответьте любым статусом 2xx в течение 10 секунд.
  • Доставка выполняется не менее одного раза. Неудачную или истёкшую по времени доставку повторяем: всего пять попыток — сразу, затем через 30 секунд, 2 минуты, 10 минут и час, — каждая отправляет те же байты с новой подписью. Сделайте обработчик идемпотентным по data.id; id сообщения никогда не меняется. В разделе Settings сохраняется каждая попытка, и любую доставку можно отправить повторно.
  • Если все пять попыток не удались, заберите пропущенное через API: ?after= и receivedAt последнего обработанного SMS.
  • Пока линия приостановлена или её владелец не подтвердил личность, не отправляется ничего. Такие SMS сохраняются и становятся доступны сразу после снятия причины, но вебхук по ним потом не уходит — читайте их через ?after=.
  • До пяти эндпоинтов на рабочее пространство. В разделе Settings видно последний статус каждого эндпоинта и сколько доставок подряд не удалось.
  • type — это message.received, а для тестовой доставки из Settings — test: та же структура data, но со своими id. На незнакомый тип отвечайте 200: могут появиться новые.
  • Если вместо своего адреса вставить входящий webhook Slack или ссылку на workflow Microsoft Teams, такой эндпоинт получит формат сообщений самого мессенджера и без cleat-signature: общего секрета с мессенджером нет.
  • code — одноразовый код, который Cleat счёл наиболее вероятным, или null. Полный body есть всегда.
  • label словами говорит, от кого SMS: контакт, сохранённый вашей командой, иначе сервис, который Cleat распознал по тексту; за ними стоят contact и service. Все три равны null, когда уверенности нет. Поля добавлены позже и ничего не убирают: from, body и code прежние.
  • Код, продиктованный в автоматическом звонке, приходит так же. Звонок расшифровывается и доставляется как message.received: расшифровка в body, номер звонившего в from, code заполнен. Ничто в теле запроса не отличает звонок от SMS.

Справочник API

ЭндпоинтЧто возвращает
GET /api/v1/linesЛинии в рабочем пространстве API-ключа, от новых к старым: id, phone, label, status (active, grace или released) и createdAt.
GET /api/v1/lines/{lineId}/messagesSMS на одной линии. after (ISO 8601) возвращает SMS, полученные после этого момента, от старых к новым, — для опроса. before листает назад, от новых к старым. limit от 1 до 200, по умолчанию 50.
Базовый URL: https://cleat.so. Аутентификация: Authorization: Bearer clt_…. limit вне диапазона 1–200 приводится к границе, а не отклоняется. Ошибки: 400 — неверный формат метки времени, 401 — ключа нет, он отозван или истёк (code — key_expired), 402 — линия приостановлена, 403 — владелец рабочего пространства ещё не подтвердил личность (code — verify_first), 404 — линия вне рабочего пространства ключа либо вне области действия ключа: ответ намеренно один и тот же, 429 — превышено ограничение частоты запросов, 503 — область действия ключа не удалось проверить.

Ограничения и права

120 запросов в минуту на один API-ключ; сверх этого API отвечает 429 — без заголовка Retry-After, так что задержку выбираете вы сами. Создавать API-ключи и эндпоинты вебхуков может только владелец рабочего пространства, а отозванный ключ перестаёт работать сразу. Ключ можно и сузить при создании: до конкретных линий и до даты, когда он перестанет работать, — именно это позволяет отдать его агенту, CI-задаче или подрядчику. Линия вне области действия отвечает 404, а истёкший ключ — 401 с code key_expired.

Для чего подходит

  • Аккаунты вашей компании: облачные консоли, регистраторы доменов, платёжные сервисы. Коды приходят в канал, который читает дежурный инженер.
  • Тестирование ваших собственных сценариев регистрации и входа в тестовой среде и QA — на номере, который ведёт себя как телефон клиента.
  • Личные проекты, где нужно указать мобильный номер США.

Для чего не подходит

  • Отправка SMS. Cleat Line работает только на приём: не отправляет SMS, не звонит и не набирает 911.
  • Нагрузочное тестирование или пулы номеров. Каждая линия — отдельная подписка со своим проверенным владельцем. Cleat не рассчитан на пулы номеров.
  • Аккаунты, которые не принадлежат вам или вашей компании.
  • Всё, что требует живого голоса. Через API нельзя позвонить. Звонок нельзя принять, аудиопотока нет, записи для скачивания тоже. Расшифровку звонка вы получаете после его окончания. Звонки Cleat Full принимают и совершают в веб-приложении, а не через API.

Сравнение

Номер телеком-платформыНомера MailSlurpCleat Line
Тип номераЧасто VoIP по классификации; Lookup от Twilio помечает номер Twilio как nonFixedVoip“dedicated, non-VoIP mobile numbers” («выделенные мобильные номера, не VoIP», MailSlurp)Настоящая мобильная линия США, не VoIP
Для чегоОтправка и приём в больших объёмахQA и тестирование при разработкеВаши собственные аккаунты, QA и небольшие команды
Проверка владельцаKYC компании и регистрация 10DLCНе указаноГосударственный документ и селфи или проверка только по документу (её проводит человек)
Доставка SMS в кодВебхуки и APIAPI и вебхукиПодписанные вебхуки и REST API, а также Telegram, почта и входящие
ЦенаЗа номер плюс за сообщениеНа странице не указана24,99 $ в месяц, входящие SMS включены
Данные о других компаниях взяты с их собственных страниц и проверены в сентябре 2026 года.

Нужно делиться кодами с коллегами, которые не пишут код? Смотрите общий номер для 2FA в команде. Почему Google Voice и другие интернет-номера не получают коды: Google Voice и коды подтверждения. Как мы проверяем личность: доверие и безопасность. Все правила оплаты: цены.

Читайте также

SMS в Telegram

Вопросы

Есть ли бесплатный тариф или песочница?

Нет. Одна линия стоит 24,99 $ в месяц, отменить можно в любой момент, а SMS на линии недоступны, пока её владелец не подтвердит личность.

Можно ли отправлять SMS через API?

Нет. Cleat Line только принимает и никогда не отправляет.

Что, если сервис диктует код по телефону, а не присылает SMS?

Звонок расшифровывается и приходит на ваш вебхук и в API как обычное сообщение: код извлечён, номер звонившего в from. Ни одно поле не помечает его как звонок.

Есть ли ограничение частоты запросов?

Да: 120 запросов в минуту на один API-ключ. Доставки вебхуков в него не входят.

Как быстро срабатывают вебхуки?

Cleat отправляет запрос на ваши эндпоинты, как только сохранит SMS, одновременно с входящими, почтой и Telegram. Измеренную задержку мы не публиковали, поэтому и не называем её.

Можно ли получить больше одного номера?

Вы можете добавлять линии в рабочее пространство, и каждая — отдельная подписка за 24,99 $. Cleat не рассчитан на пулы номеров.

Вы храните мои SMS?

SMS хранятся, пока вы не удалите рабочее пространство или аккаунт. Подробности — в Политике конфиденциальности.

Источники

Сведения о других компаниях взяты с их собственных страниц и проверены: сентябрь 2026 г..

  1. Twilio, filtering VoIP numbers before sending codes https://www.twilio.com/en-us/blog/filter-voip-before-otp-verification
  2. MailSlurp, phone numbers https://www.mailslurp.com/product/phone-number-sms-service/

Получите линию и API-ключ.

24,99 $ в месяц, отменить можно в любой момент.

  • Личность каждого владельца подтверждена
  • SMS видит только ваша команда
  • Отменить можно в любой момент