REST API чекера MAX: как получить доступ, лимиты и примеры запросов (2026)
REST API чекера MAX: как запросить ключ через /support за 1-2 дня, лимиты по умолчанию, HMAC-подпись webhook, idempotency-key, примеры на cURL, Python и Node.js.
REST API чекера MAX доступен по индивидуальной выдаче через /support
в Telegram-боте. Это намеренная архитектурная схема: каждому
клиенту команда подбирает rate-limit, тариф и условия SLA под реальный
объём и сценарий — это позволяет крупным клиентам экономить 20-40%
по сравнению со «средним» self-serve тарифом, а мелким — не платить
за неиспользуемые лимиты.
Эта статья — практическая документация: как запросить доступ, какие лимиты по умолчанию, как считать HMAC-подпись webhook'а, какие коды ошибок ловить, и три полных рабочих сниппета на cURL, Python и Node.js.
TL;DR
- Доступ — через
/supportв боте, 1-2 рабочих дня, без формы self-serve - Endpoint:
POST https://api.checkmaxapp.com/v1/check-account(одиночный),POST /v1/check-account/batch(до 10 000 номеров) - Авторизация:
Authorization: Bearer sk_live_...+ опциональныйIdempotency-Key: <UUID>(RFC 9110) - Webhook callback с подписью
X-MaxChecker-Signature(HMAC-SHA256, RFC 2104) - Лимиты по умолчанию: 100 req/min одиночных, 10 batch/час, batch ≤ 10k
- Тариф от $0.005 за положительный hit, отрицательные бесплатно
- SLA опционально: 99.9% / p95 ≤ 500 мс
Как мы выдаём ключ
Путь от первого сообщения в /support до production-ключа — обычно
1-2 рабочих дня. Этапы:
Шаг 1 — заявка (5 минут вашего времени). В Telegram-боте на
checkmaxapp.com пишете /support и
описываете кейс по форме (см. раздел ниже). Бот форвардит заявку в
очередь команды интеграций.
Шаг 2 — уточнение (день 0-1). Поддержка возвращается с уточняющими вопросами: пиковая нагрузка, желаемая модель оплаты (commit / pay-as-you-go), нужен ли формальный SLA-договор, на какой стороне будет жить webhook.
Шаг 3 — выдача ключа (день 1-2). Получаете в защищённом канале:
MAXCHECKER_TOKENформатаsk_live_<32 base62 символа>— дляAuthorization: BearerзаголовкаMAXCHECKER_WEBHOOK_SECRET— для проверки HMAC-подписи входящих callback'ов- URL endpoint'ов (production + staging)
- Согласованные лимиты (
X-RateLimit-Limitваш персональный) - OpenAPI 3.1 спецификацию под ваш профиль
Шаг 4 — интеграция (1-3 дня на стороне клиента). Делаете тестовый вызов на staging (5 проверок в подарок к ключу), подключаете webhook, проверяете HMAC, выводите в production. Команда на связи в выделенном канале.
Шаг 5 — production. После первой недели работы созваниваемся на 15 минут — смотрим метрики, корректируем лимиты, если профиль оказался другим.
Что мы спросим в /support
Чтобы команда сразу подобрала тариф и rate-limit без лишних итераций, пришлите при запросе следующее:
- Ожидаемый объём проверок в месяц — диапазон вида «20 000-40 000» достаточен; нужен ли burst-режим (например, 100 000 раз в месяц, но 80% за один день перед рассылкой).
- Кейс: антифрод на регистрации, обогащение CRM, чистка базы перед рассылкой, white-label, OSINT-инструмент, другое.
- Платформа интеграции: amoCRM, Bitrix24, HubSpot, Make, Zapier, n8n, кастомный бэкенд (с указанием стека — Python/Node/Go/Java/PHP).
- Латентность: критична ли низкая задержка отклика (антифрод — да, чистка базы — нет, batch с webhook — нет).
- SLA: нужен ли формальный договор с гарантиями 99.9% / p95 латентности / кредитами за нарушение.
- Где будет жить webhook-приёмник: публичный URL с HTTPS, есть
ли возможность поднять (если нет — расскажем про polling-режим
через
GET /v1/jobs/{id}).
Чем подробнее заявка — тем меньше итераций, тем быстрее ключ.
Endpoint: одиночная проверка
Базовый URL: https://api.checkmaxapp.com. Все запросы — HTTPS, TLS 1.2+.
Формат запроса
POST /v1/check-account HTTP/1.1
Host: api.checkmaxapp.com
Authorization: Bearer sk_live_<your_token>
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{
"phone": "+79161234567"
}Idempotency-Key — опциональный UUID v4. Если задан, сервер хранит
результат 24 часа: повторный вызов с тем же ключом вернёт кэшированный
ответ без повторного списания (поведение по RFC 9110 §9.2.2).
Используйте уникальный UUID на каждый бизнес-вызов — это даёт безопасный
ретрай при сетевых таймаутах.
Ответ 200 OK
{
"phone": "+79161234567",
"registered": true,
"firstName": "Анна",
"lastName": "Иванова",
"server_id": 847291,
"last_seen": "2026-05-21T09:42:15Z",
"bio": "Маркетолог, Москва",
"checked_at": "2026-05-22T12:33:21Z",
"request_id": "req_x9k2hf4n8p"
}При registered=false остальные поля отсутствуют. Тарифицируются
только положительные hits — registered=false всегда бесплатно.
request_id сохраняйте в логах: пригодится при инцидент-разборе с
поддержкой.
Пример: cURL
#!/usr/bin/env bash
set -euo pipefail
TOKEN="${MAXCHECKER_TOKEN:?set MAXCHECKER_TOKEN env var}"
IDEMPOTENCY_KEY="$(uuidgen)"
curl -fsSL -X POST https://api.checkmaxapp.com/v1/check-account \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-d '{"phone": "+79161234567"}' \
--retry 3 --retry-delay 2 --retry-connrefused \
-w '\nHTTP %{http_code} in %{time_total}s\n'--retry 3 справится с временными 5xx; для 429 нужен respect к
заголовку Retry-After — здесь cURL его не учитывает, поэтому в
production-скриптах используйте Python/Node-клиенты с правильной
retry-логикой (см. ниже).
Пример: Python (requests)
Полный production-ready клиент с retry и idempotency:
"""MaxChecker REST API client.
Зависимости: requests >= 2.31
"""
from __future__ import annotations
import os
import time
import uuid
import logging
from typing import Any
import requests
log = logging.getLogger(__name__)
API_BASE = "https://api.checkmaxapp.com"
TOKEN = os.environ["MAXCHECKER_TOKEN"]
class MaxCheckerError(Exception):
"""Базовая ошибка API."""
class RateLimitError(MaxCheckerError):
def __init__(self, retry_after: int) -> None:
super().__init__(f"rate limit; retry after {retry_after}s")
self.retry_after = retry_after
def check_phone(
phone: str,
*,
idempotency_key: str | None = None,
timeout: float = 10.0,
max_retries: int = 5,
) -> dict[str, Any]:
"""Проверить один номер. Делает экспоненциальный retry на 429 и 5xx."""
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
"Idempotency-Key": idempotency_key or str(uuid.uuid4()),
}
payload = {"phone": phone}
for attempt in range(max_retries):
try:
r = requests.post(
f"{API_BASE}/v1/check-account",
headers=headers,
json=payload,
timeout=timeout,
)
except requests.RequestException as exc:
log.warning("network error attempt=%d: %s", attempt, exc)
time.sleep(min(2 ** attempt, 30))
continue
if r.status_code == 200:
return r.json()
if r.status_code == 429:
retry_after = int(r.headers.get("Retry-After", 2 ** attempt))
log.warning("429; sleeping %ds", retry_after)
time.sleep(retry_after)
continue
if 500 <= r.status_code < 600:
time.sleep(min(2 ** attempt, 30))
continue
# 4xx (кроме 429) — не ретраим, ошибка клиента
body = r.json() if r.headers.get("Content-Type", "").startswith("application/json") else {}
raise MaxCheckerError(
f"HTTP {r.status_code} error={body.get('error')} message={body.get('message')}"
)
raise MaxCheckerError("exceeded max_retries")
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
result = check_phone("+79161234567")
if result["registered"]:
print(f"{result.get('firstName')} {result.get('lastName')} — {result.get('last_seen')}")
else:
print("not registered in MAX")Запуск:
export MAXCHECKER_TOKEN="sk_live_..."
python check.pyДля async-нагрузок 100+ rps замените requests на httpx.AsyncClient
с http2=True — даст 2-3× прирост по сравнению с sync-pool'ом.
Готовый async-клиент есть в нашем
бойлерплейте.
Пример: Node.js (axios)
Аналогичный клиент на Node.js 20+ с axios и axios-retry:
// maxchecker-client.mjs
// Зависимости: axios@^1.6, axios-retry@^4
import axios from 'axios';
import axiosRetry from 'axios-retry';
import { randomUUID } from 'node:crypto';
const TOKEN = process.env.MAXCHECKER_TOKEN;
if (!TOKEN) throw new Error('MAXCHECKER_TOKEN env var is required');
const client = axios.create({
baseURL: 'https://api.checkmaxapp.com',
timeout: 10_000,
headers: {
Authorization: `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
});
axiosRetry(client, {
retries: 5,
retryDelay: (retryCount, error) => {
// Если сервер прислал Retry-After — слушаем его
const retryAfter = error?.response?.headers?.['retry-after'];
if (retryAfter) return Number(retryAfter) * 1000;
return Math.min(2 ** retryCount * 1000, 30_000);
},
retryCondition: (error) => {
const status = error?.response?.status;
return status === 429 || (status >= 500 && status < 600) || !status;
},
});
export async function checkPhone(phone, { idempotencyKey } = {}) {
const { data } = await client.post(
'/v1/check-account',
{ phone },
{ headers: { 'Idempotency-Key': idempotencyKey ?? randomUUID() } },
);
return data;
}
// Demo
const result = await checkPhone('+79161234567');
console.log(result.registered ? `${result.firstName} ${result.lastName}` : 'not registered');В TypeScript-проектах добавьте типизацию ответа:
type CheckAccountResponse =
| {
phone: string;
registered: true;
firstName?: string;
lastName?: string;
server_id: number;
last_seen?: string;
bio?: string;
checked_at: string;
request_id: string;
}
| {
phone: string;
registered: false;
checked_at: string;
request_id: string;
};Batch endpoint
Для объёмов от 100 номеров — async batch. До 10 000 номеров за один вызов, пропускная способность сервера — до 1 млн номеров в час.
Запрос
POST /v1/check-account/batch HTTP/1.1
Authorization: Bearer sk_live_...
Content-Type: application/json
Idempotency-Key: 6f9619ff-8b86-d011-b42d-00cf4fc964ff
{
"phones": [
"+79161234567",
"+79162345678",
"+79163456789"
],
"callback_url": "https://your-app.example.com/maxcheck/webhook",
"metadata": {
"campaign_id": "spring_cleanup_2026",
"internal_batch_id": "batch_42"
}
}Поле metadata — произвольный JSON-объект, возвращается обратно в
webhook без изменений. Удобно для трассировки на стороне клиента.
Ответ 202 Accepted
{
"job_id": "job_8x4kpqz2nm",
"status": "queued",
"phones_count": 3,
"estimated_completion": "2026-05-22T13:42:00Z",
"request_id": "req_a7b9c2..."
}Webhook callback
Когда batch готов, сервер делает POST на ваш callback_url:
POST /maxcheck/webhook HTTP/1.1
Host: your-app.example.com
Content-Type: application/json
X-MaxChecker-Signature: sha256=<HEX>
X-MaxChecker-Timestamp: 1716381140
User-Agent: MaxChecker-Webhook/1.0
{
"job_id": "job_8x4kpqz2nm",
"status": "completed",
"results_url": "https://api.checkmaxapp.com/v1/jobs/job_8x4kpqz2nm/results.csv",
"results_expires_at": "2026-05-29T12:33:21Z",
"stats": {
"total": 10000,
"registered": 7240,
"not_found": 2760,
"errors": 0
},
"metadata": {
"campaign_id": "spring_cleanup_2026",
"internal_batch_id": "batch_42"
}
}results_url живёт 7 дней. Скачивайте файл и кладите в своё хранилище
сразу — мы не считаем себя долгосрочным архивом.
Ретраи доставки webhook: 5 попыток за 24 часа по схеме 1m, 5m, 30m, 2h, 6h. Если ваш приёмник возвращает 2xx — доставка считается успешной. Любой не-2xx ответ — ретрай.
Если webhook поднять негде — polling
curl -H "Authorization: Bearer ${TOKEN}" \
https://api.checkmaxapp.com/v1/jobs/job_8x4kpqz2nmРекомендованный интервал — 30 секунд. Чаще — 429.
Webhook и HMAC-подпись
Подпись X-MaxChecker-Signature — HMAC-SHA256 от сырого тела
запроса с вашим webhook-секретом, согласно RFC 2104.
Формат: sha256=<hex>.
Дополнительно сервер шлёт X-MaxChecker-Timestamp (Unix epoch
секунды) — храните окно ±5 минут для защиты от replay-атак.
Проверка на Python
import hmac
import hashlib
import time
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = os.environ["MAXCHECKER_WEBHOOK_SECRET"].encode()
TIMESTAMP_TOLERANCE_SECONDS = 300 # ±5 min
def verify_signature(raw_body: bytes, signature_header: str, timestamp_header: str) -> bool:
# 1) Защита от replay: timestamp должен быть в окне ±5 минут
try:
ts = int(timestamp_header)
except (TypeError, ValueError):
return False
if abs(time.time() - ts) > TIMESTAMP_TOLERANCE_SECONDS:
return False
# 2) Считаем ожидаемую подпись от <timestamp>.<body>
signed_payload = f"{ts}.".encode() + raw_body
expected = hmac.new(WEBHOOK_SECRET, signed_payload, hashlib.sha256).hexdigest()
received = signature_header.removeprefix("sha256=")
# 3) Constant-time сравнение
return hmac.compare_digest(expected, received)
@app.post("/maxcheck/webhook")
def webhook():
raw_body = request.get_data()
if not verify_signature(
raw_body,
request.headers.get("X-MaxChecker-Signature", ""),
request.headers.get("X-MaxChecker-Timestamp", ""),
):
abort(401)
payload = request.get_json()
# Обработка: скачать results_url, обновить вашу БД
process_batch_result(payload)
# 2xx обязателен — иначе мы будем ретраить
return "", 204Критически важно использовать hmac.compare_digest, а не ==:
обычное сравнение строк уязвимо к timing-атакам, через которые
атакующий может подобрать подпись по байтам.
Проверка на Node.js
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const WEBHOOK_SECRET = process.env.MAXCHECKER_WEBHOOK_SECRET;
const TIMESTAMP_TOLERANCE_SECONDS = 300;
// КРИТИЧНО: нужен raw body, не parsed JSON
app.use('/maxcheck/webhook', express.raw({ type: 'application/json' }));
function verifySignature(rawBody, signatureHeader, timestampHeader) {
const ts = Number(timestampHeader);
if (!Number.isFinite(ts)) return false;
if (Math.abs(Date.now() / 1000 - ts) > TIMESTAMP_TOLERANCE_SECONDS) return false;
const signedPayload = Buffer.concat([
Buffer.from(`${ts}.`),
rawBody,
]);
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(signedPayload)
.digest('hex');
const received = (signatureHeader || '').replace(/^sha256=/, '');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(received, 'hex');
if (a.length !== b.length) return false;
return crypto.timingSafeEqual(a, b);
}
app.post('/maxcheck/webhook', (req, res) => {
const ok = verifySignature(
req.body,
req.get('X-MaxChecker-Signature'),
req.get('X-MaxChecker-Timestamp'),
);
if (!ok) return res.status(401).end();
const payload = JSON.parse(req.body.toString('utf-8'));
// ...handle payload
res.status(204).end();
});
app.listen(3000);В Express важно использовать express.raw(), а не express.json() —
HMAC считается от сырых байт, а парсер JSON может изменить
представление (пробелы, порядок ключей), что сломает проверку.
Idempotency-Key и безопасные ретраи
RFC 9110 §9.2.2
определяет идемпотентность как «эффект на сервере от N идентичных
вызовов идентичен одному вызову». Из коробки POST идемпотентным
не является — Idempotency-Key это поведение добавляет.
Когда использовать. Везде, где сетевая ошибка после отправки запроса не позволяет понять, дошёл ли запрос до сервера. Особенно критично для batch'ей на тысячи номеров — там стоимость двойного списания заметная.
Как формировать ключ. UUID v4 на каждый бизнес-вызов, не переиспользовать для семантически разных запросов. Пример:
import uuid
idem_key = str(uuid.uuid4())
# Первая попытка
try:
result = check_phone("+79161234567", idempotency_key=idem_key)
except TimeoutError:
# Сеть упала — не знаем, дошёл ли запрос
# Безопасный ретрай: тот же ключ → или новый ответ, или кэш
result = check_phone("+79161234567", idempotency_key=idem_key)Кэш живёт 24 часа от первого успешного 2xx. После — следующий вызов с тем же ключом считается новым.
Лимиты по умолчанию
| Endpoint | Лимит | Заголовки в ответе |
|---|---|---|
POST /v1/check-account | 100 req/min | X-RateLimit-Remaining, X-RateLimit-Reset |
POST /v1/check-account/batch | 10 batch/hour | те же |
| Batch size | ≤ 10 000 номеров | — |
GET /v1/jobs/{id} | 60 req/min | те же |
| Webhook delivery retries | 5 за 24 часа | — |
| Idempotency-Key cache TTL | 24 часа | — |
| Max request body | 5 MB | — |
| Max concurrent batch jobs per account | 20 | — |
Это базовый профиль. При выдаче ключа лимиты корректируются под
ожидаемый объём — нет смысла держать 100 req/min, если клиент делает
2 000 в минуту регулярно, или, наоборот, держать высокий потолок при
эпизодической нагрузке. Запросить пересмотр можно в любой момент
через /support — обычно меняем в течение часа.
Коды ошибок
Все ошибки возвращаются с JSON-телом:
{
"error": "rate_limit_exceeded",
"message": "100 req/min exceeded; retry after 23 seconds",
"retry_after_seconds": 23,
"request_id": "req_x9k2hf4n8p"
}| HTTP | error | Что значит | Стратегия |
|---|---|---|---|
| 400 | invalid_phone_format | Номер не в E.164 (нет +, есть пробелы) | Нормализовать и переотправить |
| 400 | malformed_json | Тело не JSON | Починить формат |
| 401 | invalid_token | Bearer токен не распознан | Проверить env var, ротировать |
| 402 | insufficient_balance | Не хватает средств для следующего hit'а | Пополнить через /pricing |
| 422 | unknown_number | Невалидный номер (служебный диапазон, неактивный код) | Не ретраить, фильтровать на входе |
| 422 | country_not_supported | Только RU поддерживается | Не ретраить |
| 429 | rate_limit_exceeded | Превышен rate-limit | Ждать retry_after_seconds |
| 500 | internal_error | Серверная ошибка | Retry с exp backoff (1, 2, 4, 8 с) |
| 502 | upstream_unavailable | Временная недоступность бэкенда | Retry через 10-30 с |
| 503 | maintenance | Запланированная профилактика | Retry через Retry-After |
| 401 | invalid_signature | На webhook: HMAC не сошёлся | Проверить секрет, raw body |
Главное правило: ретраить только 429 и 5xx. На 4xx (кроме 429) ретрай не поможет — это ошибка клиента, нужно чинить запрос.
Тарифные тиры в API
Тариф тот же, что и в боте — pay-per-hit от $0.005 за положительный
ответ. Отрицательные (registered=false) бесплатно. Скидочные тиры
применяются по сумме депозита:
| Депозит | Скидка | Эффективная цена/hit |
|---|---|---|
| $10-$199 | 0% | $0.005 |
| $200-$499 | 10% | $0.0045 |
| $500-$999 | 20% | $0.004 |
| $1 000-$1 999 | 30% | $0.0035 |
| $2 000+ | 40% | $0.003 |
Минимальный депозит — $10. Для commit-моделей с ежемесячным предоплатным объёмом обсуждаются индивидуальные условия — это типично для команд антифрода с предсказуемой нагрузкой 200k+ hits/мес. Полная сетка — на странице тарифов.
Типичные интеграционные сценарии
По нашей статистике, 80% индивидуальных API-доступов используются под одну из четырёх задач — даём готовые сниппеты и webhook-шаблоны под каждый сценарий при выдаче ключа.
1. Антифрод на регистрации. Синхронный вызов /v1/check-account
из формы регистрации, p95 ≤ 500 мс. Решение «пускать/в ручную
верификацию/отказать» на основе registered, last_seen, наличия
firstName. Подробнее — Антифрод по номеру.
2. Обогащение CRM в реальном времени. Webhook от CRM → один API-вызов → запись в карточку лида. Стандартно настраивается на amoCRM/Bitrix24 за час через webhook-конструктор. См. use-case по маркетингу.
3. Чистка маркетинговой базы. Batch на 10-100k номеров раз в неделю перед рассылкой. Webhook-приёмник кладёт CSV в S3/Yandex Object Storage, ETL обновляет основную базу.
4. White-label-зеркала. Реселлеры выставляют наш API под своим брендом и тарифицируют по своему прайс-листу. См. white-label.
Кросс-ссылка на сиблинг-материал с расширенными примерами на async Python и сравнением с green-api: CheckAccount REST API для MAX.
Что не даёт API
Чтобы не перегружать ожидания:
- Не возвращаем переписку, аватарки и приватные настройки — только публичные поля профиля MAX.
- Не поддерживаем поиск по странам кроме RU — это сознательная специализация, не отсутствие технической возможности.
- Не поддерживаем другие мессенджеры — для WhatsApp есть green-api, для Telegram — отдельные решения; мы не конкурируем за «универсальный чекер».
- Не предоставляем готовые базы номеров — мы инструмент проверки, а не источник данных.
- Self-serve панели регистрации намеренно нет: см. раздел «Как мы выдаём ключ» выше.
E-E-A-T: кто стоит за API
Команда max-checker-team поддерживает REST API для интеграций
B2B-клиентов с 2024 года. За это время через API прошло более
14 млн проверок в основном четырёх вертикалях: МФО и онлайн-кредитование,
e-commerce антифрод, маркетинговые рассылки, B2B-обогащение CRM.
Базовая инфраструктура — Python (FastAPI) + PostgreSQL + Redis
- Cloudflare Workers на edge, p95 латентность одиночного запроса держится в районе 280 мс.
Контакт для интеграционных вопросов — /support в боте,
ответ в рабочее время в течение нескольких часов.
Полезные материалы
- REST API personal cabinet — продуктовая страница API
- CheckAccount REST API для MAX — расширенные примеры, сравнение с green-api
- Антифрод по номеру в B2B — типовой синхронный кейс API
- Use-case: маркетинг — чистка базы перед рассылкой
- White-label-зеркала — отдельная модель для реселлеров
- Тарифы и скидочные тиры — те же цены, что и в API
- Как это работает — техника проверки номера
Внешние спецификации, на которые ссылается API:
- RFC 9110 §9.2.2 — Idempotency
- RFC 2104 — HMAC
- OpenAPI Specification 3.1 — формат, в котором мы отдаём документацию
Частые вопросы
01.Как получить API-ключ к чекеру MAX?
Доступ выдаётся индивидуально через /support в Telegram-боте. Опишите кейс (объём, платформа, латентность, нужен ли SLA) — команда вернётся за 1-2 рабочих дня с ключом, секретом для HMAC-подписи webhook'а, выделенным rate-limit и индивидуальными условиями по объёмам. Self-serve панели регистрации намеренно нет: индивидуальный подбор тарифа экономит клиентам 20-40% на больших объёмах.
02.Какие лимиты по умолчанию у REST API?
Базовый профиль: 100 одиночных запросов в минуту, batch до 10 000 номеров за один вызов, до 10 batch-запросов в час. Webhook доставки с экспоненциальными ретраями (5 попыток за 24 часа). Лимиты подбираются под объём клиента — для нагрузок от 1 млн проверок в месяц повышаются индивидуально.
03.Как проверить подпись X-MaxChecker-Signature на webhook?
Подпись — HMAC-SHA256 от сырого тела запроса (request body) с вашим webhook-секретом. Сравнивайте через constant-time функцию (hmac.compare_digest в Python, crypto.timingSafeEqual в Node.js), чтобы избежать timing-атак. Подробный пример с защитой от replay-атак через timestamp window — в разделе «Webhook и HMAC-подпись» ниже.
04.Что такое Idempotency-Key и зачем он нужен?
Idempotency-Key — UUID-заголовок, который позволяет безопасно повторить запрос после сетевой ошибки или таймаута без риска двойного списания. Сервер хранит результат первого вызова с этим ключом 24 часа и при повторе возвращает кэшированный ответ. Поведение соответствует RFC 9110 §9.2.2. Особенно критично для batch-запросов на тысячи номеров.
05.Какие коды ошибок возвращает API?
Стандартные HTTP-коды (400, 401, 402, 422, 429, 500, 503) + machine-readable error code в JSON-теле: rate_limit_exceeded (с retry_after_seconds), unknown_number (номер не валиден), country_not_supported (не RU), insufficient_balance, invalid_signature (на webhook), internal_error. Полная таблица с рекомендованными retry-стратегиями — в разделе «Коды ошибок».
06.Сколько стоит проверка через API?
Базовый тариф — от $0.005 за положительный hit (registered=true). Отрицательные ответы (registered=false) не тарифицируются. Скидочные тиры: 10% от $200, 20% от $500, 30% от $1 000, 40% от $2 000 — те же, что и в боте. Минимальный депозит — $10. Конкретный коммит обсуждается с поддержкой при выдаче доступа.
07.Какие платформы интеграции вы поддерживаете из коробки?
amoCRM, Bitrix24, HubSpot, Make, Zapier, n8n — есть готовые примеры запросов и webhook-получателей. Для кастомных бэкендов даём cURL/Python/Node.js-сниппеты под конкретный сценарий: антифрод на регистрации, обогащение CRM в реальном времени, чистка маркетинговой базы перед рассылкой, white-label-зеркала.
08.Какое SLA на API?
Базовый профиль — best effort: историческая аптайм 99.6%, p95 латентность одиночного запроса 280 мс. Для команд с критичной зависимостью оформляется отдельный SLA-договор: 99.9% месячная доступность, p95 ≤ 500 мс, кредиты за нарушение. SLA включается опционально при выдаче доступа и обсуждается под конкретный кейс.
Читать дальше