CheckAccount REST API для MAX: пример Python, Node и cURL
Документация REST API для проверки номеров в MAX: endpoints, headers, body, JSON-ответ, примеры на curl/Python/Node, batch и webhook, rate-limits, обработка ошибок.
REST API — обязательный инструмент для команд, которые встраивают проверку номеров в продакшен-pipeline: антифрод на регистрации, обогащение CRM в реальном времени, sales-инструменты, ML-модели скоринга. Веб-форма с CSV — для разовых задач, API — для систем.
Эта статья — полная документация REST API нашего сервиса checkmaxapp.com: endpoints, форматы, примеры на трёх языках, batch-режим, webhooks, rate-limits, обработка ошибок.
TL;DR
- POST
/v1/check-account— одиночная проверка, ответ 200–500 мс - POST
/v1/check-account/batch— массовая проверка до 10 000 за запрос - Возвращает registered, firstName, lastName, server_id, last_seen, bio
- Авторизация:
Authorization: Bearer YOUR_TOKEN - Rate-limits: 100/мин одиночных, 10/час batch
- Webhook для асинхронных batch-результатов
- Цена та же, что и через бот: $0.005 за hit, со скидками до 40%
Получение токена
API-токен выдаётся в личном кабинете на checkmaxapp.com после регистрации. Бесплатные 5 проверок доступны без депозита — протестировать API можно сразу. Дальше пополнение от $10 (тарифы и скидки).
Храните токен в переменных окружения, не коммитьте в репозиторий. Минимально:
export MAXCHECK_TOKEN="sk_live_..."Endpoint: одиночная проверка
Запрос
POST https://api.checkmaxapp.com/v1/check-account
Headers:
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
Body:
{ "phone": "+79161234567" }Номер строго в формате E.164: знак +, код страны, без пробелов и
дефисов. Подробнее про нормализацию —
Как очистить базу 100k.
Ответ при registered=true
{
"phone": "+79161234567",
"registered": true,
"firstName": "Анна",
"lastName": "Иванова",
"server_id": 847291,
"last_seen": "2026-05-11 09:42:15",
"bio": "Маркетолог, Москва",
"checked_at": "2026-05-11T12:33:21Z"
}Ответ при registered=false
{
"phone": "+79161234567",
"registered": false,
"checked_at": "2026-05-11T12:33:21Z"
}Когда registered=false — пользователя в MAX нет, остальные поля
не возвращаются. Деньги списываются только за положительные hits
(registered=true), отрицательные ответы бесплатные.
Пример: cURL
curl -X POST https://api.checkmaxapp.com/v1/check-account \
-H "Authorization: Bearer $MAXCHECK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"phone": "+79161234567"}'Полезно для быстрых проверок и интеграционных скриптов.
Пример: Python (requests)
Синхронный клиент для простых сценариев:
import os
import requests
TOKEN = os.environ["MAXCHECK_TOKEN"]
URL = "https://api.checkmaxapp.com/v1/check-account"
def check_phone(phone: str) -> dict:
response = requests.post(
URL,
headers={
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
},
json={"phone": phone},
timeout=10,
)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
result = check_phone("+79161234567")
if result["registered"]:
print(f"Найден: {result.get('firstName')} {result.get('lastName')}")
else:
print("Не зарегистрирован в MAX")Пример: Python async (httpx)
Для высокой пропускной способности — асинхронный клиент:
import asyncio
import os
import httpx
TOKEN = os.environ["MAXCHECK_TOKEN"]
URL = "https://api.checkmaxapp.com/v1/check-account"
async def check_phone(client: httpx.AsyncClient, phone: str) -> dict:
r = await client.post(
URL,
headers={"Authorization": f"Bearer {TOKEN}"},
json={"phone": phone},
timeout=10.0,
)
r.raise_for_status()
return r.json()
async def main(phones: list[str]):
async with httpx.AsyncClient(http2=True) as client:
tasks = [check_phone(client, p) for p in phones]
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
if __name__ == "__main__":
phones = ["+79161234567", "+79162345678", "+79163456789"]
print(asyncio.run(main(phones)))При больших объёмах вместо много параллельных одиночных запросов лучше использовать batch endpoint (см. ниже) — это дешевле по rate-limits.
Пример: Node.js (fetch)
Современный нативный fetch (Node.js 18+):
const TOKEN = process.env.MAXCHECK_TOKEN;
const URL = 'https://api.checkmaxapp.com/v1/check-account';
async function checkPhone(phone) {
const response = await fetch(URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ phone }),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
(async () => {
const result = await checkPhone('+79161234567');
console.log(result);
})();Пример: Node.js (axios)
import axios from 'axios';
const client = axios.create({
baseURL: 'https://api.checkmaxapp.com',
headers: { Authorization: `Bearer ${process.env.MAXCHECK_TOKEN}` },
timeout: 10000,
});
async function checkPhone(phone) {
const { data } = await client.post('/v1/check-account', { phone });
return data;
}
checkPhone('+79161234567').then(console.log);Batch endpoint
Для проверки от 100 номеров за раз — asynchronous batch:
Запрос
POST https://api.checkmaxapp.com/v1/check-account/batch
Headers:
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
Body:
{
"phones": ["+79161234567", "+79162345678", ...],
"callback_url": "https://your-app.com/maxcheck-webhook"
}Лимит: 10 000 номеров за один запрос. Для больших объёмов разбивайте на батчи. Пропускная способность сервера — до 1 млн номеров в час.
Ответ
Сервер сразу возвращает job_id:
{
"job_id": "job_8x4kpqz2nm",
"status": "queued",
"phones_count": 10000,
"estimated_completion": "2026-05-11T13:42:00Z"
}Webhook callback
Когда batch готов, сервер вызывает ваш callback_url:
POST https://your-app.com/maxcheck-webhook
Headers:
X-MaxCheck-Signature: <HMAC-SHA256>
Body:
{
"job_id": "job_8x4kpqz2nm",
"status": "completed",
"results_url": "https://api.checkmaxapp.com/v1/jobs/job_8x4kpqz2nm/results.csv",
"stats": {
"total": 10000,
"registered": 7240,
"not_found": 2760,
"errors": 0
}
}Подпись X-MaxCheck-Signature — HMAC-SHA256 от тела запроса с
вашим секретом webhook. Обязательно проверяйте подпись, чтобы
исключить подделку callback'а.
Без webhook (поллинг)
Если webhook поднять негде — поллинг статуса:
GET https://api.checkmaxapp.com/v1/jobs/job_8x4kpqz2nmВозвращает текущий статус. Рекомендованный интервал поллинга — 30 секунд, чаще — 429.
Rate-limits
| Endpoint | Лимит | Заголовок |
|---|---|---|
POST /v1/check-account | 100/мин | X-RateLimit-Remaining |
POST /v1/check-account/batch | 10/час | X-RateLimit-Remaining |
GET /v1/jobs/{id} | 60/мин | X-RateLimit-Remaining |
При превышении — 429 Too Many Requests + заголовок Retry-After
в секундах. Простейшая реализация retry:
import time
def with_retry(fn, max_retries=5):
for attempt in range(max_retries):
try:
return fn()
except requests.HTTPError as e:
if e.response.status_code == 429:
wait = int(e.response.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
raise
raise RuntimeError("Exceeded retries")Для production-нагрузок свяжитесь с поддержкой — лимиты повышаются индивидуально для проверенных клиентов.
Обработка ошибок
| HTTP код | Значение | Что делать |
|---|---|---|
| 200 | OK | Парсить ответ |
| 400 | Bad Request | Проверить формат phone (E.164) |
| 401 | Unauthorized | Проверить токен |
| 402 | Payment Required | Пополнить баланс |
| 422 | Unprocessable Entity | Невалидный номер (служебный диапазон) |
| 429 | Too Many Requests | Retry с Retry-After |
| 500 | Internal Server Error | Retry через 5–10 секунд |
| 503 | Service Unavailable | Сервер на профилактике, retry |
Все ошибки возвращаются с JSON-телом:
{
"error": "invalid_phone_format",
"message": "Phone must be in E.164 format",
"request_id": "req_x9k2..."
}request_id пригодится поддержке для разбора инцидентов — сохраняйте
в логах.
Сравнение с green-api CheckAccount
Многие команды приходят с опытом green-api (WhatsApp CheckAccount). Принципиальные отличия:
| Параметр | green-api CheckAccount | MaxCheck API |
|---|---|---|
| Мессенджер | MAX | |
| Поля ответа | существование | имя, фамилия, last_seen, BIO, server_id |
| Модель оплаты | подписка $39–290/мес | pay-per-hit от $0.005 |
| Минимум | $39/мес | $10 одноразово |
| Batch endpoint | Нет (только одиночные) | Есть, до 10k за раз |
| Webhook | Нет | Есть |
| Trial | 7 дней | 5 проверок бесплатно |
Для российской аудитории и B2C-сегмента MaxCheck даёт больше полей для персонализации и работает без подписочной модели — выгоднее при нерегулярных нагрузках.
Best practices
- Нормализуйте номера на своей стороне — отдавайте в API уже E.164, иначе 422
- Используйте batch для >100 номеров — экономит rate-limits
- Реализуйте webhook вместо поллинга — снижает нагрузку
- Логируйте
request_id— пригодится при разборе - Храните результаты в своей CRM — не делайте повторных проверок тех же номеров
- Соблюдайте 152-ФЗ — см. юридический материал
Что дальше
Получить токен и протестировать API на 5 бесплатных проверках — прямо сейчас на checkmaxapp.com.
Частые вопросы
01.Чем REST API лучше веб-формы для проверки номеров?
REST API даёт интеграцию с любыми внутренними системами: CRM, антифрод-pipeline, sales-инструменты, ML-модели скоринга. Веб-форма требует ручного экспорта/импорта CSV и не подходит для real-time сценариев. API позволяет проверять номер в момент регистрации пользователя на сайте за 200–500 мс и принимать решение «пускать/нет» прямо в воронке.
02.Какой формат запроса принимает /v1/check-account?
POST с заголовками Authorization Bearer YOUR_TOKEN и Content-Type application/json, тело — JSON { phone: '+79161234567' }. Номер должен быть в формате E.164 с плюсом и международным кодом. Сервер возвращает 200 OK с полным JSON-ответом или 4xx/5xx с описанием ошибки. Подробные примеры на curl, Python и Node.js — ниже в статье.
03.Что в batch-режиме и сколько номеров можно отправить за раз?
POST /v1/check-account/batch принимает массив до 10 000 номеров за один запрос. Сервер сразу возвращает job_id, и через 1–10 минут (зависит от объёма) присылает webhook с готовым CSV или JSON-ответом. Пропускная способность — до 1 млн номеров в час. Без webhook можно поллить статус через GET /v1/jobs/{job_id}, но webhook эффективнее.
04.Какие rate-limits и что делать при 429?
По умолчанию 100 одиночных запросов в минуту и 10 batch-запросов в час. Для бóльших объёмов — связаться с поддержкой для повышения лимитов. При получении 429 Too Many Requests сервер возвращает заголовок Retry-After в секундах — нужно подождать указанное время и повторить запрос. Рекомендуется реализовать exponential backoff: 1 → 2 → 4 → 8 секунд.
Читать дальше