NOKYCNUMBER

HTTP API v1

Программный доступ к телефонным номерам, звонкам, SMS, голосовой почте и AI-функциям. JSON по HTTPS. Идемпотентность там, где это важно. SDK не обязателен, но мы предоставляем 5.

Введение

API NoKYCNumber построен по принципам REST. Мы используем предсказуемые URL, ориентированные на ресурсы, принимаем и возвращаем JSON-тела и используем стандартные HTTP-коды ответа, аутентификацию и методы.

Базовый URL

http
https://api.nokycnumber.com/v1/

Все запросы должны выполняться по HTTPS. Запросы по HTTP завершатся ошибкой 301 Moved Permanently. Запросы без аутентификации завершатся ошибкой 401 Unauthenticated.

Соглашение JSON

  • Все запросы с телом используют Content-Type: application/json. Запросы с form-encoded телом отклоняются с кодом 415.
  • Временные метки возвращаются в виде строк ISO-8601 UTC (2026-04-26T14:23:00Z) и принимаются в том же формате.
  • Телефонные номера возвращаются в формате E.164 с ведущим + (+33647189022) и в отформатированном виде в поле display где применимо.
  • ID объектов имеют префикс ресурса: num_, call_, sms_, vm_, whk_, evt_.

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

Аутентифицируйтесь с помощью bearer-ключа из вашей панели в разделе Настройки → API-ключи. Существует два типа ключей:

  • sk_live_… — серверный секрет. Полный доступ на чтение/запись. Никогда не раскрывайте в клиентском коде.
  • pk_live_… — публичный ключ. Зарезервирован; пока не используется ни одним эндпоинтом.

Формат заголовка

http
Authorization: Bearer sk_live_5f3a8b2c4d1e9f6a7b8c2d1e9f6a7b8c
Content-Type: application/json
NoKYC-Version: 2026-04-01

Используйте заголовок NoKYC-Version для привязки к конкретной версии API (см. Версионирование). При отсутствии используется закреплённая версия по умолчанию вашего аккаунта.

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

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

Область доступаРазрешённые методыСценарий использования
readGETОтчётность, мониторинговые дашборды.
read_writeGET · POST · PATCHБольшинство серверных интеграций.
adminВсе, включая DELETEАвтоматизация выделения, управление аккаунтом.

Ключи можно ротировать в любое время. Старые ключи остаются действительными 5 минут после ротации для деплоя без простоя.

Ошибки

API использует стандартные HTTP-коды статуса. 2xx означает успех, 4xx — проблема с вашим запросом, 5xx — наша ошибка, и мы хотим об этом узнать.

Конверт ошибки

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Required parameter `country` is missing.",
    "param": "country",
    "request_id": "req_8a4c2f1e9b3d4a7c"
  }
}

Коды статусов

КодЗначение
200OK · запрос выполнен успешно
201Created · ресурс создан
204No Content · ресурс удалён, тело ответа отсутствует
400Bad Request · некорректный JSON или отсутствует обязательный параметр
401Unauthenticated · недействительный, отсутствующий или отозванный API-ключ
402Payment Required · недостаточно средств на балансе аккаунта
403Forbidden · ключ не имеет необходимых прав для этой операции
404Not Found · ресурс не существует или принадлежит другому аккаунту
409Conflict · ключ идемпотентности повторно использован с другими параметрами
422Unprocessable · семантическая ошибка (например, неподдерживаемая страна)
429Too Many Requests · см. Лимиты запросов
500503Проблема сервера / сервиса · безопасно повторить с паузой

Типы ошибок

  • invalid_request_error — некорректный запрос, отсутствующие поля, неверный формат.
  • authentication_error — проблема с ключом.
  • authorization_error — проблема с правами доступа.
  • rate_limit_error — слишком много запросов.
  • api_error — наша ошибка. Можно повторить запрос.
  • resource_error — состояние ресурса не позволяет выполнить операцию (например, попытка совершить звонок с приостановленного номера).
  • upstream_error — тайм-аут оператора или партнёра.

Каждый ответ с ошибкой содержит request_id. Всегда записывайте его — это единственный способ для нашей поддержки сопоставить ваш запрос с нашей внутренней трассировкой.

Пагинация

Эндпоинты списков используют однонаправленную курсорную пагинацию. Они возвращают до limit объектов (по умолчанию 25, максимум 100) и булево значение has_more. Для получения следующей страницы передайте ID последнего объекта как starting_after.

curl
curl https://api.nokycnumber.com/v1/numbers?limit=10 \
  -H "Authorization: Bearer sk_live_…"
json
{
  "object": "list",
  "url": "/v1/numbers",
  "data": [
    { "id": "num_8a4c2f1e9b3d", "object": "number", "number": "+33647189022", … },
    { "id": "num_2k7m9p3w8x4t", "object": "number", "number": "+12025550143", … }
  ],
  "has_more": true,
  "next_cursor": "num_2k7m9p3w8x4t"
}

Списки упорядочены по дате создания (новые первыми). Обратная пагинация через ending_before не поддерживается — используйте курсор.

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

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

http
POST /v1/sms HTTP/1.1
Authorization: Bearer sk_live_…
Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e
Content-Type: application/json

{ "from": "num_8a4c2f1e9b3d", "to": "+33612345678", "body": "Hello" }

Повторное использование того же ключа с другим содержимым тела возвращает 409 Conflict с idempotency_key_mismatch.

Ключи идемпотентности не обязательны, но настоятельно рекомендуются для любых платных операций (звонки, SMS, покупка номеров). Без них повторная попытка сети может привести к двойному списанию.

Лимиты запросов

По умолчанию каждый API-ключ ограничен 100 запросами в минуту. Крупные клиенты могут запросить увеличение лимита через поддержку. Лимиты применяются к ключу, а не к IP.

Заголовки ответа

http
X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 73
X-Rate-Limit-Reset: 1745672460
Retry-After: 8

При превышении лимита вы получаете 429 Too Many Requests с заголовком Retry-After в секундах. Рекомендуется линейная задержка до 4 повторных попыток; если ситуация не улучшается, запросите более высокий лимит.

Допустимый всплеск запросов

Ограничитель работает по принципу маркерного ведра — короткие всплески выше 100 запросов в минуту допустимы, пока скользящее среднее за 60 секунд остаётся ниже лимита.

Версионирование

Версии API датированы (2026-04-01). Несовместимые изменения выпускаются как новая датированная версия; обратно совместимые дополнения включаются в текущую. Закрепите версию с помощью заголовка NoKYC-Version.

Совместимость

  • Мы поддерживаем каждую версию не менее 24 месяцев после выхода следующей.
  • Уведомления об устаревании отправляются владельцам аккаунтов по email за 90 дней.
  • Заголовок ответа NoKYC-Deprecation предупреждает об использовании устаревшей версии.

Текущая версия: 2026-04-01.

Номера

Номер — это виртуальная телефонная линия под вашим управлением. Номера привязаны к стране и типу (mobile или landline) и имеют период оплаты.

GET /v1/numbers

Список всех номеров вашего аккаунта. Возвращает постраничный список объектов number.

FieldТипDescription
limit необязательныйinteger1–100, по умолчанию 25.
starting_after необязательныйstringКурсор для пагинации.
country необязательныйstringФильтр по коду страны ISO-2 (например, fr).
type необязательныйstringФильтр по mobile или landline.
status необязательныйstringФильтр по active, paused или released.
curl
curl https://api.nokycnumber.com/v1/numbers?country=fr&type=mobile \
  -H "Authorization: Bearer sk_live_…"
json
{
  "object": "list",
  "data": [
    {
      "id": "num_8a4c2f1e9b3d",
      "object": "number",
      "number": "+33647189022",
      "display": "+33 6 47 18 90 22",
      "country": "fr",
      "type": "mobile",
      "tier": "standard",
      "status": "active",
      "billing_period": "yearly",
      "renews_at": "2027-04-26T11:23:00Z",
      "ai_enabled": true,
      "created_at": "2026-04-26T11:23:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
POST /v1/numbers

Активировать новый номер по ID резервирования. Списывает настроенный период с баланса аккаунта.

FieldТипDescription
available_id обязательныйstringИдентификатор navail_… из /v1/numbers/available.
billing_period обязательныйstringmonthly, quarterly или yearly.
addons необязательныйarrayAI-дополнения для включения, например ["ai-pickup","ai-trans"].
webhook_url необязательныйstringЭндпоинт, который будет получать события, связанные с номером.
curl
curl https://api.nokycnumber.com/v1/numbers \
  -H "Authorization: Bearer sk_live_…" \
  -H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
  -d '{
    "available_id":   "navail_2k7m9p3w8x4t",
    "billing_period": "yearly",
    "addons":         ["ai-pickup"]
  }'
json
{
  "id": "num_8a4c2f1e9b3d",
  "object": "number",
  "number": "+33611112222",
  "display": "+33 6 11 11 22 22",
  "country": "fr",
  "type": "mobile",
  "tier": "premium",
  "status": "active",
  "billing_period": "yearly",
  "renews_at": "2027-04-26T11:23:00Z",
  "ai_enabled": true,
  "created_at": "2026-04-26T11:23:00Z"
}
GET /v1/numbers/{id}

Получить один номер по ID.

curl
curl https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
  -H "Authorization: Bearer sk_live_…"
PATCH /v1/numbers/{id}

Обновить изменяемые поля номера. Используйте POST /v1/numbers/{id}/renew для продления периода.

FieldТипDescription
auto_renew необязательныйbooleanВключить/выключить автопродление по окончании периода.
webhook_url необязательныйstringЗаменить webhook-цель для номера.
addons необязательныйarrayЗаменить активный набор AI-дополнений.
on_off необязательныйobjectУстановить тихие часы / окна отключения. См. настройку AI.
DELETE /v1/numbers/{id}

Освободить номер. Номер возвращается в пул по окончании периода и может быть переназначен другому клиенту. Возвращает 204 No Content.

curl
curl -X DELETE https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
  -H "Authorization: Bearer sk_live_…"

Освобождённые номера нельзя вернуть. Рекомендуем сначала приостановить через PATCH с { "status": "paused" }, если вы захотите его вернуть.

Звонки

Звонок — это одна голосовая сессия, инициированная с одного из ваших номеров. Исходящие звонки совершаются через POST /v1/calls; входящие звонки зеркалируются на ваш webhook и также доступны через API.

POST/v1/calls

Совершить исходящий звонок с одного из ваших номеров.

FieldТипDescription
from обязательныйstringИдентификатор num_, которым вы владеете.
to обязательныйstringНомер назначения в формате E.164, например +33612345678.
recording_enabled необязательныйbooleanПо умолчанию false. Записи хранятся 30 дней.
callerid_mask необязательныйstring"hide", "rotate" или любой номер в формате E.164, которым вы владеете.
metadata необязательныйobjectПроизвольный JSON, возвращаемый в webhook для звонка.
curl
curl https://api.nokycnumber.com/v1/calls \
  -H "Authorization: Bearer sk_live_…" \
  -d '{
    "from": "num_8a4c2f1e9b3d",
    "to":   "+33612345678",
    "callerid_mask": "rotate"
  }'
json
{
  "id": "call_2k7m9p3w8x4t",
  "object": "call",
  "from": "num_8a4c2f1e9b3d",
  "from_e164": "+33647189022",
  "to": "+33612345678",
  "status": "ringing",
  "direction": "outbound",
  "started_at": "2026-04-26T11:24:01Z",
  "answered_at": null,
  "ended_at": null,
  "duration_sec": 0,
  "recording_url": null,
  "cost_usd": null
}
GET/v1/calls

Список звонков. Фильтр по number, direction, status или created_after / created_before.

GET/v1/calls/{id}

Получить один звонок.

POST/v1/calls/{id}/hangup

Принудительно завершить активный звонок. Идемпотентно.

SMS-сообщения

Отправка и получение SMS. Длинные сообщения автоматически сегментируются по правилам GSM-03.38 / UCS-2; ответ показывает фактическое количество сегментов для расчёта оплаты.

POST/v1/sms

Отправить SMS с одного из ваших номеров.

FieldТипDescription
from обязательныйstringИдентификатор num_, которым вы владеете.
to обязательныйstringНомер назначения в формате E.164.
body обязательныйstringТело сообщения. Максимум 1 600 символов (10 сегментов).
send_at необязательныйstringВременная метка ISO-8601 в будущем для планирования доставки.
media_urls необязательныйarrayДо 5 URL изображений/видео. Только MMS — работает в поддерживающих странах.
curl
curl https://api.nokycnumber.com/v1/sms \
  -H "Authorization: Bearer sk_live_…" \
  -H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
  -d '{
    "from": "num_8a4c2f1e9b3d",
    "to":   "+33612345678",
    "body": "Bonjour. Your code is 482917."
  }'
json
{
  "id": "sms_4n2v8j1q6h7y",
  "object": "sms",
  "from_e164": "+33647189022",
  "to": "+33612345678",
  "body": "Bonjour. Your code is 482917.",
  "direction": "outbound",
  "segments": 1,
  "status": "queued",
  "created_at": "2026-04-26T11:24:50Z",
  "delivered_at": null,
  "cost_usd": 0.012
}
GET/v1/sms

Список сообщений. Фильтр по number, direction, status.

GET/v1/sms/{id}

Получить одно сообщение, включая статус доставки на уровне сегментов.

Голосовые сообщения

Голосовые сообщения хранятся, транскрибируются и переводятся автоматически. URL аудио предварительно подписаны и истекают через 1 час после выдачи.

GET/v1/voicemails

Список голосовых сообщений. Пагинация аналогична другим эндпоинтам списков.

GET/v1/voicemails/{id}

Получить одно голосовое сообщение с транскрипцией и URL аудио.

json
{
  "id": "vm_5p3w8x4t9k2m",
  "object": "voicemail",
  "number_id": "num_8a4c2f1e9b3d",
  "from_e164": "+33612345678",
  "received_at": "2026-04-26T11:25:42Z",
  "duration_sec": 27,
  "audio_url": "https://files.nokycnumber.com/vm/5p3w8x4t9k2m.mp3?expires=1745676342&sig=…",
  "transcript": {
    "text": "Bonjour, c'est Marc. Rappelez-moi quand vous pouvez.",
    "language": "fr",
    "translation_en": "Hello, this is Marc. Call me back when you can.",
    "summary": "Marc asks for a callback.",
    "sentiment": "neutral"
  }
}

И translation_en, и summary требуют дополнения ai-summary.

DELETE/v1/voicemails/{id}

Безвозвратно удалить голосовое сообщение и его аудиофайл. Возвращает 204 No Content.

Настройка AI

На каждом номере можно запустить AI-агента, который принимает звонки вместо вас, фильтрует неизвестных звонящих, составляет резюме голосовой почты или переводит разговоры в реальном времени. Настраивается для каждого номера через AI-подресурс.

GET/v1/numbers/{id}/ai

Получить текущую конфигурацию AI для номера.

json
{
  "object": "ai_config",
  "number_id": "num_8a4c2f1e9b3d",
  "addons": ["ai-pickup", "ai-summary"],
  "auto_pickup": {
    "enabled": true,
    "after_rings": 4,
    "script": "I'm unavailable right now. Leave your name, the reason for the call, and a callback number.",
    "language": "auto",
    "voice": "neutral_fr"
  },
  "screening": { "enabled": false },
  "translator": { "enabled": false, "target_language": "en" },
  "voicemail_summary": { "enabled": true, "include_sentiment": true }
}
PATCH/v1/numbers/{id}/ai

Обновить одну или несколько AI-функций. Каждый блок необязателен; обновляются только присутствующие поля.

Голоса

Доступные голоса: neutral_en, neutral_fr, neutral_es, neutral_de, neutral_jp, warm_en, warm_fr. Клонированные голоса для корпоративных клиентов — по запросу.

Аккаунт

Чтение данных уровня аккаунта: баланс, статистика использования, настроенные webhook.

GET/v1/account

Получить данные вашего аккаунта.

json
{
  "object": "account",
  "email_hash": "9b3d4a7c8a4c2f1e",
  "balance_usd": 47.32,
  "default_country": "fr",
  "active_numbers": 3,
  "monthly_call_minutes": 412,
  "monthly_sms_segments": 1820,
  "created_at": "2026-04-12T09:15:00Z"
}
GET/v1/account/usage

Детальная разбивка использования за текущий период. Передайте period=last_30d или period=last_90d.

Webhook

Подпишитесь на события вашего аккаунта или отдельных номеров. Мы отправляем JSON-событие методом POST на ваш эндпоинт и повторяем попытку до 5 раз с экспоненциальной задержкой в течение 24 часов.

Конверт события

json
{
  "id": "evt_3d4a7c8a4c2f",
  "object": "event",
  "type": "sms.received",
  "created": "2026-04-26T11:25:42Z",
  "livemode": true,
  "data": { "object": { "id": "sms_…", … } },
  "request_id": "req_8a4c2f1e9b3d4a7c"
}

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

Каждый запрос содержит заголовок X-NoKYC-Signature в формате t=<ts>,v1=<hex>. Подпись — это HMAC-SHA256 от <ts>.<raw_body> с использованием секрета подписи эндпоинта. Отклоняйте любые запросы старше 5 минут.

shell
# Pseudocode
ts, v1 = parse(header)
if abs(now - ts) > 300: reject
expected = hmac_sha256(secret, f"{ts}.{body}")
if not constant_time_eq(expected, v1): reject

Эндпоинты

POST/v1/webhook_endpoints

Зарегистрировать новый webhook-эндпоинт. Возвращает секрет подписи один раз; сохраните его.

FieldТипDescription
url обязательныйstringHTTPS URL, на который мы будем отправлять события методом POST.
enabled_events обязательныйarrayСписок подписки, например ["sms.received","call.completed"]. Используйте ["*"] для всех.
description необязательныйstringПроизвольная заметка для вашей собственной бухгалтерии.
GET/v1/webhook_endpoints

Список ваших эндпоинтов.

DELETE/v1/webhook_endpoints/{id}

Удалить эндпоинт. Возвращает 204.

Типы событий

СобытиеСрабатывает когда
number.activatedНовый номер выделен и готов к использованию.
number.renewedПериод успешно продлён.
number.pausedНомер перешёл в состояние паузы в период on/off-окна.
number.releasedНомер безвозвратно возвращён в пул.
call.initiatedИсходящий звонок совершён.
call.answeredУдалённая сторона ответила.
call.completedЗвонок завершён (по любой причине).
call.recordedЗапись завершена и доступна.
sms.receivedВходящее SMS поступило на ваш номер.
sms.sentИсходящее SMS принято оператором.
sms.deliveredКвитанция о доставке от оператора подтверждена.
sms.failedОтклонено оператором — проверьте failure_code.
voicemail.createdНовое голосовое сообщение записано и транскрибировано.
ai.pickupAI-автоответ принял звонок.
account.balance_lowБаланс опустился ниже установленного порога.

Схемы объектов

number

json
{
  "id":             "string · num_…",
  "object":         "string · constant \"number\"",
  "number":         "string · E.164",
  "display":        "string · pretty-printed",
  "country":        "string · ISO-2",
  "type":           "enum · mobile | landline",
  "tier":           "enum · standard | premium",
  "tier_pattern":   "string | null · double-repeat | sequential | mirror | round | …",
  "status":         "enum · active | paused | released",
  "billing_period": "enum · monthly | quarterly | yearly",
  "renews_at":      "string · ISO-8601 UTC",
  "auto_renew":     "boolean",
  "addons":         "array · ai-pickup | ai-screen | ai-summary | ai-trans",
  "ai_enabled":     "boolean",
  "metadata":       "object | null",
  "created_at":     "string · ISO-8601 UTC"
}

call

json
{
  "id":             "string · call_…",
  "object":         "string · constant \"call\"",
  "from":           "string · num_…",
  "from_e164":      "string · E.164",
  "to":             "string · E.164",
  "direction":      "enum · inbound | outbound",
  "status":         "enum · queued | ringing | in_progress | completed | failed | no_answer | busy",
  "started_at":     "string · ISO-8601 UTC",
  "answered_at":    "string | null",
  "ended_at":       "string | null",
  "duration_sec":   "integer",
  "recording_url":  "string | null · pre-signed, expires in 1h",
  "cost_usd":       "number | null"
}

sms

json
{
  "id":             "string · sms_…",
  "object":         "string · constant \"sms\"",
  "from":           "string · num_…",
  "from_e164":      "string · E.164",
  "to":             "string · E.164",
  "body":           "string",
  "media_urls":     "array · up to 5",
  "direction":      "enum · inbound | outbound",
  "segments":       "integer · 1–10",
  "status":         "enum · queued | sent | delivered | failed | undelivered",
  "failure_code":   "string | null",
  "created_at":     "string · ISO-8601 UTC",
  "delivered_at":   "string | null",
  "cost_usd":       "number | null"
}

Официальные SDK

HTTP API является источником истины, но эти SDK предоставляют типизированные привязки, повторные попытки, идемпотентность и проверку webhook из коробки.

  • node npm install @nokycnumber/sdk
  • python pip install nokycnumber
  • go go get github.com/nokycnumber/sdk-go
  • php composer require nokycnumber/sdk
  • ruby gem install nokycnumber