Incognum

Разработчикам

Справочник API.

Закажите настоящий номер, прочитайте поступившие коды и ответьте на них за четыре HTTP-вызова. Условия те же, что в панели: без личности и договора, оплата с криптовалютного баланса.

  • REST + JSON
  • Один Bearer-ключ
  • Подписанные вебхуки
  • 47 стран
  • Номер готов примерно за 60 с
Базовый URL
https://api.incognum.com/v1
Версия
v1 — только обратно совместимые дополнения
Аутентификация
Authorization: Bearer nkp_live_…
Тип содержимого
application/json или кодировка формы

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

Четыре вызова отделяют вас от работающего номера с входящими. Всё ниже можно скопировать и вставить; замените ключ — и можно работать.

  1. Создайте учётную запись в панели и сгенерируйте ключ в разделе Ключи API. Ключи начинаются с nkp_live_ и показываются один раз.
  2. Пополните баланс криптовалютой. Номер оплачивается с баланса, но никогда с карты.
  3. Закажите линию. Она активируется примерно через минуту после получения ответа на вызов.
  4. Читайте входящие или укажите свою конечную точку для вебхука и прекратите опрос.
POST /v1/numbers
# заказать французскую мобильную линию на один месяц
curl -X POST https://api.incognum.com/v1/numbers \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…" \
  -H "Idempotency-Key: 7d1e4c22-90aa-4d1f-8b0e-1c2f9a55b311" \
  -H "Content-Type: application/json" \
  -d '{"country":"fr","type":"mobile","period":1,"label":"signups"}'

# 201 Created
{
  "id": "num_8f2c1a94",
  "e164": "+33647189022",
  "country": "fr",
  "type": "mobile",
  "status": "active",
  "label": "signups",
  "auto_renew": true,
  "created_at": "2026-09-21T09:14:02Z",
  "renews_at": "2026-10-21T09:14:02Z",
  "charged": { "monthly": 12.90, "activation": 10.00, "total": 22.90, "currency": "USD" },
  "balance_after": 77.10
}
GET /v1/numbers/{id}/messages
# прочитать входящие, начиная с новых — код уже извлечён
curl "https://api.incognum.com/v1/numbers/num_8f2c1a94/messages?limit=2" \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

# 200 OK
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "msg_5b1f77c0",
      "direction": "inbound",
      "from": "Telegram",
      "to": "+33647189022",
      "body": "Ваш код входа: 72194. Не сообщайте его.",
      "code": "72194",
      "received_at": "2026-09-21T09:15:41Z"
    },
    {
      "id": "msg_5b1f7411",
      "direction": "inbound",
      "from": "+14155550142",
      "to": "+33647189022",
      "body": "Ваш код подтверждения: 408-113",
      "code": "408113",
      "received_at": "2026-09-21T09:14:58Z"
    }
  ]
}

Поле code выполняет скучную работу. Мы применяем те же правила извлечения, что и панель: группы из четырёх–восьми цифр, без пробелов и дефисов, с игнорированием собственного номера отправителя. Если ничто не похоже на код, code равен null, а текст сообщения сохраняется.

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

Каждый вызов передаёт Bearer-ключ в заголовке Authorization. По умолчанию нет второго фактора, подписи запроса и списка разрешённых IP: ключ и есть учётные данные, поэтому обращайтесь с ним соответственно.

Заголовок Authorization
Authorization: Bearer nkp_live_9f2c8a41d0b7e5…

Создание и ротация ключей

  • Создайте ключ в разделе Ключи API панели. Полное значение показывается один раз; мы храним хеш, а не ключ.
  • Выдавайте каждой интеграции отдельный ключ и метку. Отзыв одного не затрагивает остальные.
  • Отзыв действует немедленно. Текущие запросы завершатся, следующий вернёт 401.
  • Учётная запись может иметь до десяти активных ключей. Сами по себе ключи не истекают.

Области доступа

Ключ получает одну из трёх областей доступа, выбранную при создании.

ОбластьВозможностиОбычное применение
readСписок и получение номеров, сообщений, звонков и баланса.Панели, мониторинг, бот, который только читает коды.
writeВсё из read, а также отправка SMS, изменение настроек линии и управление вебхуками.Обычный выбор для интеграции.
adminВсё из write, а также заказ, продление и освобождение номеров и открытие пополнений.Любые операции, расходующие баланс.

Утёкший ключ может потратить ваш баланс. Если утёк ключ с областью admin, сначала отзовите его в панели, затем проверьте свой журнал операций. Платёж в блокчейне нельзя отменить, а адреса электронной почты для предупреждения у нас нет — такова цена учётной записи без привязанной личности.

Соглашения

Запросы

  • Базовый URL: https://api.incognum.com/v1. Только HTTPS; обычный HTTP отклоняется без перенаправления.
  • Тело может быть JSON (Content-Type: application/json) или формой. Ответы всегда JSON в UTF-8.
  • Неизвестные поля тела запроса игнорируются и никогда не вызывают ошибку. Поэтому добавочные изменения безопасны.

Идентификаторы и время

  • ID — непрозрачные строки с префиксом типа: num_, msg_, call_, vm_, whk_, top_. Не разбирайте их.
  • Все временные метки имеют формат RFC 3339 в UTC и оканчиваются на Z. Длительности указаны в секундах, деньги — в USD с двумя десятичными знаками.
  • Коды стран — строчные ISO 3166-1 alpha-2. Номера всегда имеют формат E.164 с начальным +.

Пагинация

Конечные точки списков возвращают объект с object: "list", массивом data и полем has_more. Для страниц используйте limit (1–100, по умолчанию 25) и starting_after, принимающий последний увиденный ID.

GET /v1/messages
curl "https://api.incognum.com/v1/messages?limit=50&starting_after=msg_5b1f7411" \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

Идемпотентность

Передавайте заголовок Idempotency-Key с любым POST. Первый ответ хранится 24 часа и при повторном получении того же ключа воспроизводится побайтно, поэтому тайм-аут или повтор не закажет два номера. Используйте новый UUID для каждой логической операции.

Повторяйте безопасно. Если запрос до нас не дошёл, ключ не сохранён и повтор выполняется обычно. Если запрос дошёл, но истёк по времени у вас, воспроизводится сохранённый ответ. В обоих случаях вы получаете ровно один номер.

Ошибки

Ошибки используют стандартные коды состояния и всегда имеют одну структуру. Поле code стабильно и пригодно для ветвления; message написано для человека и может измениться.

402 Payment Required (требуется оплата)
{
  "error": {
    "type": "balance_error",
    "code": "insufficient_balance",
    "message": "Ваш баланс — 4.10 USD; этот заказ стоит 22.90 USD.",
    "param": null,
    "doc": "https://incognum.com/api/#billing"
  }
}
СтатусКодЧто произошло
400invalid_requestПараметр отсутствует или имеет неверный формат. Его имя указано в param.
401invalid_keyКлюч отсутствует, имеет неверный формат или отозван.
403insufficient_scopeКлюч действителен, но его область не охватывает этот вызов.
403country_unavailableСейчас эта страна закрыта для новых заказов.
404not_foundТакого объекта нет либо он принадлежит другой учётной записи.
409number_releasedЛиния освобождена и больше не может использоваться.
422unsupported_typeВ этой стране нет линии запрошенного типа.
402insufficient_balanceНедостаточно средств. Откройте пополнение и повторите запрос.
429rate_limitedСлишком много запросов. Увеличьте паузу; см. ограничения частоты.
503temporarily_unavailableЗависимый сервис недоступен. Повторите с увеличением паузы и проверьте состояние.

Указатель конечных точек

МетодПутьДействие
GET/v1/countriesНаличие и цена по странам.
GET/v1/numbersСписок ваших линий.
POST/v1/numbersЗаказать линию.
GET/v1/numbers/{id}Получить одну линию.
PATCH/v1/numbers/{id}Метка, автопродление, Caller ID, тихие часы, вебхук и дополнения.
POST/v1/numbers/{id}/renewПродлить сейчас на один период.
DELETE/v1/numbers/{id}Немедленно освободить линию.
GET/v1/numbers/{id}/messagesВходящие одной линии.
GET/v1/messagesСообщения всех линий.
GET/v1/messages/{id}Получить одно сообщение.
POST/v1/messagesОтправить SMS.
GET/v1/callsЖурнал звонков.
GET/v1/voicemails/{id}Голосовое сообщение с расшифровкой и URL аудио.
GET/v1/balanceБаланс и недавние записи журнала.
POST/v1/topupsОткрыть адрес пополнения.
GET/v1/topups/{id}Отслеживать депозит.
GET/v1/webhooksСписок конечных точек.
POST/v1/webhooksЗарегистрировать конечную точку.
DELETE/v1/webhooks/{id}Удалить конечную точку.

Страны

Перед заказом проверьте наличие и цену. Цены совпадают со страницами стран и меняются вместе с ними: эта конечная точка — машиночитаемая версия той таблицы.

GET /v1/countries
curl https://api.incognum.com/v1/countries \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

# 200 OK
{
  "object": "list",
  "data": [
    {
      "code": "fr",
      "name": "France",
      "dial": "+33",
      "region": "europe",
      "types": ["mobile", "landline"],
      "in_stock": true,
      "price": { "mobile": 12.90, "landline": 10.30, "activation": 10.00, "currency": "USD" },
      "premium_surcharge": 4.90
    }
  ]
}

Фильтруйте с помощью ?type=mobile, ?region=europe или ?in_stock=true. Наличие проверяется в реальном времени по пулам операторов, поэтому страна со значением false отклонит заказ с country_unavailable, а не возьмёт деньги и поставит вас в очередь.

Номера

Заказ линии

POST /v1/numbers списывает средства с баланса и подготавливает линию. Вызов возвращается после подтверждения выделения, обычно менее чем за секунду; линия начинает принимать примерно через минуту.

ПолеТипПримечания
countryстрока, обязательноСтрочный код ISO, например fr.
typeстрока, обязательноmobile или landline.
periodцелое число1, 3 или 12 месяцев. По умолчанию 1. Скидка за квартал — 10%, за год — 25%.
premiumлогическое значениеЗапросить запоминающийся шаблон. Доплата $4.90 в месяц.
e164строкаЗарезервировать конкретный номер, возвращённый /v1/numbers/available.
labelстрокаВаше название линии длиной до 40 символов.
auto_renewлогическое значениеПо умолчанию true.
addonsмассив строкЛюбое из: ai-pickup, ai-screen, ai-summary, ai-trans.
webhook_urlстрокаКонечная точка линии. Переопределяет общую для учётной записи.

Активация оплачивается один раз для каждой линии. $10.00 за первый период и больше никогда при продлении. Освобождение линии и получение новой считается новой активацией.

Выбор конкретного номера

Получите список свободных номеров в стране, ничего не удерживая, затем закажите нужный, передав его e164. Кандидаты не резервируются; оформите заказ в течение нескольких минут.

GET /v1/numbers/available
curl "https://api.incognum.com/v1/numbers/available?country=de&type=mobile&premium=true" \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

# 200 OK
{
  "object": "list",
  "data": [
    { "e164": "+4915735550088", "pattern": "repeating", "surcharge": 4.90 },
    { "e164": "+4915735551234", "pattern": "sequential", "surcharge": 4.90 },
    { "e164": "+4915735557000", "pattern": "round", "surcharge": 4.90 }
  ]
}

Изменение, продление и освобождение

PATCH /v1/numbers/{id}
# отключить автопродление, скрыть Caller ID и заглушить линию ночью
curl -X PATCH https://api.incognum.com/v1/numbers/num_8f2c1a94 \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…" \
  -H "Content-Type: application/json" \
  -d '{"auto_renew":false,"mask_caller_id":true,"quiet_from":"23:00","quiet_to":"07:00"}'
  • POST /v1/numbers/{id}/renew немедленно списывает стоимость ещё одного периода и переносит renews_at вперёд.
  • DELETE /v1/numbers/{id} немедленно освобождает линию. Она сразу перестаёт принимать и не подлежит восстановлению: номер возвращается в пул оператора.
  • Линия, продление которой не удалось из-за недостатка средств, остаётся доступной в течение 3 дней, затем освобождается автоматически. Отслеживайте number.grace через вебхук.

Сообщения

Чтение

GET /v1/messages охватывает все линии аккаунта; GET /v1/numbers/{id}/messages возвращает тот же список, ограниченный одной линией. Фильтруйте его с помощью direction, from, since и has_code=true.

GET /v1/messages?has_code=true&since=2026-09-21T00:00:00Z
curl "https://api.incognum.com/v1/messages?has_code=true&since=2026-09-21T00:00:00Z" \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

Отправка

POST /v1/messages отправляет сообщение с одной из ваших линий. Исходящее SMS стоит $0.08 за сегмент, сумма списывается с баланса; длинное сообщение разбивается на сегменты, и каждый сегмент оплачивается отдельно.

POST /v1/messages
curl -X POST https://api.incognum.com/v1/messages \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…" \
  -H "Content-Type: application/json" \
  -d '{"from":"num_8f2c1a94","to":"+447700900123","body":"Я уже еду."}'

# 202 Принято
{
  "id": "msg_9c04ab71",
  "direction": "outbound",
  "status": "queued",
  "segments": 1,
  "charged": 0.08,
  "created_at": "2026-09-21T09:22:10Z"
}

Статус меняется по цепочке queued → sent → delivered либо переходит в failed с полем failure_code. Следите за ним через вебхук message.status, а не с помощью опроса.

Отправка предназначена для разговоров, а не для кампаний. За массовые или нежелательные рассылки линия отключается без возврата денег — см. политику допустимого использования. Операторы блокируют их задолго до того, как мы их заметим, и из-за них диапазон становится непригодным для всех, кто им пользуется.

Звонки и голосовая почта

Каждая линия принимает звонки. Пропущенные звонки поступают в голосовую почту, где они записываются, расшифровываются и — при наличии дополнения для сводок — сокращаются до одной строки.

GET /v1/voicemails/{id}
curl https://api.incognum.com/v1/voicemails/vm_31d9f0a2 \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…"

# 200 OK
{
  "id": "vm_31d9f0a2",
  "number": "num_8f2c1a94",
  "from": "+33612345678",
  "duration": 34,
  "language": "fr",
  "transcript": "Bonjour, c'est le service livraison, votre colis arrive demain entre 9h et 11h.",
  "translation": "Здравствуйте, это служба доставки, ваша посылка прибудет завтра между 9 и 11 часами.",
  "summary": "Доставка завтра, 09:00–11:00.",
  "audio_url": "https://api.incognum.com/v1/voicemails/vm_31d9f0a2/audio",
  "expires_at": "2026-10-21T09:14:02Z",
  "received_at": "2026-09-21T09:31:44Z"
}
  • audio_url требует тот же Bearer-ключ и возвращает audio/ogg. Это не общедоступная ссылка.
  • Записи и расшифровки удаляются через 30 дней после получения или сразу после того, как вы их удалите, — в зависимости от того, что произойдёт раньше.
  • Расшифровка поддерживает 12 языков и выбирается отдельно для каждой линии с помощью voicemail_lang.

Баланс и пополнения

У нас не хранится ваша карта, и вам не нужно оплачивать счета. У вас есть баланс в долларах США, который пополняется криптовалютными депозитами; с него оплачиваются каждый заказ и каждое продление.

POST /v1/topups
# открыть одноразовый адрес для депозита 50 USD в Monero
curl -X POST https://api.incognum.com/v1/topups \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…" \
  -H "Content-Type: application/json" \
  -d '{"amount_usd":50,"coin":"XMR"}'

# 201 Создано
{
  "id": "top_4a91c7e2",
  "coin": "XMR",
  "address": "46BeWrHpwXm…",
  "amount_crypto": "0.2841",
  "amount_usd": 50.00,
  "rate_locked_until": "2026-09-21T10:05:00Z",
  "status": "waiting",
  "confirmations_required": 10
}
  • Курс фиксируется на 30 минут. Если вы заплатите позже, мы зачислим стоимость монет на момент поступления, но никогда не меньше фактически поступившей суммы.
  • При неполной оплате разница остаётся зачисленной как частичная сумма; при переплате излишек тоже зачисляется. Отправителю ничего не возвращается.
  • Каждый адрес используется один раз. Повторное использование старого адреса — самый быстрый способ потерять депозит.
  • Статусы: waiting → seen → confirming → credited либо expired через 3 часа, если ничего не обнаружено.

Вебхуки

Зарегистрируйте конечную точку и прекратите опрос. Мы отправляем методом POST тело в формате JSON и ожидаем ответ 2xx в течение 10 секунд; любой другой результат считается сбоем и приводит к повторной попытке.

POST /v1/webhooks
curl -X POST https://api.incognum.com/v1/webhooks \
  -H "Authorization: Bearer nkp_live_9f2c8a41d0b7e5…" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.org/hooks/nkp","events":["message.received","call.missed"]}'

# 201 Создано
{
  "id": "whk_77c1e0",
  "url": "https://example.org/hooks/nkp",
  "events": ["message.received", "call.missed"],
  "secret": "whsec_2b91f4c7a0d3…",
  "created_at": "2026-09-21T09:40:00Z"
}

События

СобытиеКогда срабатывает
message.receivedНа одну из ваших линий поступает SMS. Содержит извлечённый код.
message.statusИсходящее SMS получает статус «отправлено», «доставлено» или «сбой».
call.missedНа звонок не ответили. Голосовое сообщение поступает отдельно.
voicemail.readyЗапись и расшифровка доступны.
number.activeЗаказанная линия начала работать.
number.graceПродление не удалось из-за недостатка средств; начался обратный отсчёт.
number.releasedЛиния освобождена вами или по истечении срока.
topup.creditedДепозит подтверждён, и баланс изменился.

Полезная нагрузка и подпись

POST на вашу конечную точку
POST /hooks/nkp HTTP/1.1
Content-Type: application/json
X-NKP-Event: message.received
X-NKP-Delivery: evt_6f0b28d4
X-NKP-Timestamp: 1789033541
X-NKP-Signature: v1=6b3a1f8e7c0d94aa5e2b…

{
  "event": "message.received",
  "created_at": "2026-09-21T09:45:41Z",
  "data": {
    "id": "msg_5b1f77c0",
    "number": "num_8f2c1a94",
    "e164": "+33647189022",
    "from": "Telegram",
    "body": "Ваш код для входа: 72194. Никому его не сообщайте.",
    "code": "72194",
    "received_at": "2026-09-21T09:45:41Z"
  }
}

Подпись представляет собой HMAC-SHA256 от timestamp + "." + raw_body, созданный с секретом конечной точки и закодированный в шестнадцатеричном виде. Сравнивайте за постоянное время и отклоняйте всё, что старше пяти минут.

verify.py
import hmac, hashlib, time

def verify(secret, headers, raw_body):
    ts = headers["X-NKP-Timestamp"]
    if abs(time.time() - int(ts)) > 300:
        return False
    sent = headers["X-NKP-Signature"].split("=", 1)[1]
    mine = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(sent, mine)

Повторные попытки

  • Восемь попыток примерно за 24 часа с экспоненциальной задержкой: 10 с, 1 мин, 5 мин, 30 мин, 2 ч, 6 ч, 12 ч, 24 ч.
  • Доставка выполняется как минимум один раз. Удаляйте дубликаты по X-NKP-Delivery; один и тот же идентификатор никогда не относится к двум разным событиям.
  • Порядок не гарантируется. Если последовательность имеет значение, используйте created_at.
  • Конечная точка, для которой все попытки завершаются неудачей в течение трёх дней, отключается, и это отображается в панели.

Сначала ответьте, затем выполняйте работу. Верните 200, как только сохраните тело, а затем обработайте его. Медленный обработчик через 10 секунд выглядит как сбой, и всё событие отправляется повторно.

Ограничения частоты запросов

ГруппаЛимитОбласть действия
Чтение (GET)120 запросов в минутуНа ключ
Запись (POST, PATCH, DELETE)30 запросов в минутуНа ключ
Заказ номеров10 в минуту, 200 в деньНа аккаунт
Отправка SMS60 в минутуНа линию
Одновременно открытые пополнения3На аккаунт

Каждый ответ содержит X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset. Ответ 429 также содержит Retry-After в секундах — соблюдайте его; настойчивые повторные запросы продлевают окно.

Библиотеки

Официального SDK намеренно нет: набор методов API настолько мал, что обёртка устаревала бы быстрее, чем HTTP-вызовы. Ниже приведён весь клиент на каждом языке.

node.mjs
const nkp = (path, init = {}) =>
  fetch("https://api.incognum.com/v1" + path, {
    ...init,
    headers: { Authorization: `Bearer ${process.env.NKP_KEY}`, "Content-Type": "application/json", ...init.headers },
  }).then(async (r) => {
    const body = await r.json();
    if (!r.ok) throw new Error(body.error.code + ": " + body.error.message);
    return body;
  });

const line = await nkp("/numbers", { method: "POST", body: JSON.stringify({ country: "fr", type: "mobile" }) });
console.log(line.e164);
client.py
import os, requests

S = requests.Session()
S.headers["Authorization"] = "Bearer " + os.environ["NKP_KEY"]
BASE = "https://api.incognum.com/v1"

def nkp(method, path, **kw):
    r = S.request(method, BASE + path, timeout=15, **kw)
    if not r.ok:
        e = r.json()["error"]
        raise RuntimeError(f"{e['code']}: {e['message']}")
    return r.json()

line = nkp("POST", "/numbers", json={"country": "fr", "type": "mobile"})
print(line["e164"])

Журнал изменений

В v1 только добавляются поля и конечные точки. Всё, что может нарушить работу действующей интеграции, выпускается как v2, а v1 продолжает работать не менее двенадцати месяцев после этого.

ДатаИзменение
2026-07-14Добавлены premium и /v1/numbers/available: выбирайте запоминающийся номер до заказа.
2026-05-02Добавлено поле addons, а voicemail.ready теперь содержит summary.
2026-02-19Добавлен фильтр has_code для сообщений. Извлечение переписано; теперь code задаётся примерно на 30% чаще.
2025-11-06Подписи вебхуков переведены на HMAC с префиксом v1= и меткой времени. Старый заголовок без префикса принимался до 2026-02.
2025-06-23Добавлена пагинация starting_after. Пагинация по смещению удалена после шестимесячного периода устаревания.
2024-09-16v1 запущена вместе с сервисом.

Создавайте на основе номера,
который заработает через минуту.

Создайте аккаунт, пополните баланс и закажите первую линию через API. Документы ни на одном этапе не передаются.