Грязная email-база - это bounce rate выше 5%, бан от ESP и деньги на ветер. Ручная проверка не масштабируется. Нужен API, встроенный в ваш pipeline.
В этом руководстве - полный flow интеграции uChecker API: аутентификация, single и bulk валидация, polling задач, получение результатов. С рабочими примерами на curl, Python и Node.js.
Base URL
https://api.uchecker.netВсе эндпоинты ниже - относительно этого URL. Формат запросов и ответов - JSON.
Аутентификация
API поддерживает два метода аутентификации:
API Key рекомендуемый
Передавайте ключ в заголовке x-api-key. Просто и безопасно для серверных интеграций.
Bearer JWT
JWT-токен из /auth/login. Access token живёт 1 час, refresh - 7 дней.
Получение API-ключа: POST /auth/login
Зарегистрируйтесь на app.uchecker.net, затем получите ключ через login-эндпоинт:
curl -X POST https://api.uchecker.net/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "you@example.com",
"password": "your_password"
}'{
"user": {
"id": 1,
"email": "you@example.com",
"telegram_code": 123456
},
"api_key": "uk_xxxxxxxxxxxxx",
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}Сохраните api_key - он не меняется, пока вы не сбросите его вручную через POST /auth/reset-api-key.
Никогда не хардкодьте API-ключ в исходном коде. Храните его в переменных окружения: UCHECKER_API_KEY.
Валидация одного email
Эндпоинт POST /api/v1/validate/single - для проверки одного адреса в реальном времени. Идеально для валидации на форме регистрации.
Request body
{
"email": "user@example.com"
}Опционально: webhook_url - URL для уведомления о завершении.
curl -X POST https://api.uchecker.net/api/v1/validate/single \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'import requests
import os
API_KEY = os.environ["UCHECKER_API_KEY"]
BASE = "https://api.uchecker.net"
resp = requests.post(
f"{BASE}/api/v1/validate/single",
headers={"x-api-key": API_KEY},
json={"email": "user@example.com"},
)
data = resp.json()
print(data["task_id"], data["credits_remaining"])const API_KEY = process.env.UCHECKER_API_KEY;
const BASE = "https://api.uchecker.net";
const res = await fetch(`${BASE}/api/v1/validate/single`, {
method: "POST",
headers: {
"x-api-key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ email: "user@example.com" }),
});
const data = await res.json();
console.log(data.task_id, data.credits_remaining);Response 200
{
"success": true,
"task_id": 123,
"email": "user@example.com",
"status": "queued",
"credits_used": 1,
"credits_remaining": 999,
"estimated_completion": "2024-01-01T12:00:30.000Z"
}Запрос ставит email в очередь и возвращает task_id. Используйте его для polling статуса и получения результата.
Массовая валидация (Bulk)
POST /api/v1/validate/bulk принимает массив email-адресов. Адреса с невалидным синтаксисом отсеиваются автоматически и не тарифицируются. Опционально можно передать webhook_url для уведомления о завершении.
curl -X POST https://api.uchecker.net/api/v1/validate/bulk \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"alice@company.com",
"bob@example.org",
"invalid-email",
"carol@domain.net"
]
}'emails = ["alice@company.com", "bob@example.org", "carol@domain.net"]
resp = requests.post(
f"{BASE}/api/v1/validate/bulk",
headers={"x-api-key": API_KEY},
json={"emails": emails},
)
data = resp.json()
print(f"Task {data['task_id']}: {data['valid_emails']} queued, "
f"{data['invalid_emails']} skipped")Response 200
{
"success": true,
"task_id": 124,
"status": "queued",
"total_emails": 4,
"valid_emails": 3,
"invalid_emails": 1,
"invalid_details": [
{ "email": "invalid-email", "reason": "Invalid email syntax" }
],
"credits_used": 3,
"credits_remaining": 996,
"estimated_completion": "2024-01-01T12:01:35.000Z",
"note": "1 invalid addresses were skipped"
}Обратите внимание: invalid_details показывает, какие адреса были отсеяны и почему. Кредиты списываются только за валидные адреса.
Попробуйте uChecker API
Бесплатные кредиты при регистрации. Получите API-ключ за 30 секунд и отправьте первый запрос.
Получить API-ключPolling статуса задачи
Валидация - асинхронный процесс. После отправки запроса опрашивайте GET /api/v1/tasks/{taskId}, пока статус не станет completed или failed.
| Статус | Код | Описание |
|---|---|---|
| pending | 0 | Задача создана, ожидает обработки |
| processing | 1 | Идёт проверка адресов |
| completed | 2 | Готово, можно забирать результаты |
| failed | -2 | Ошибка при обработке |
curl https://api.uchecker.net/api/v1/tasks/124 \
-H "x-api-key: YOUR_API_KEY"{
"success": true,
"task_id": 124,
"status": "processing",
"total_emails": 3,
"processed_emails": 1,
"progress_percent": 33,
"created_at": "2024-01-01T12:00:00.000Z",
"finished_at": null
}Polling-цикл на Python
import time
def wait_for_task(task_id, timeout=300, interval=5):
"""Poll task until completed or failed."""
elapsed = 0
while elapsed < timeout:
resp = requests.get(
f"{BASE}/api/v1/tasks/{task_id}",
headers={"x-api-key": API_KEY},
)
status = resp.json()["status"]
progress = resp.json()["progress_percent"]
print(f"Status: {status} ({progress}%)")
if status == "completed":
return True
if status == "failed":
raise Exception(f"Task {task_id} failed")
time.sleep(interval)
elapsed += interval
raise TimeoutError(f"Task {task_id} timed out")
wait_for_task(124)Polling-цикл на Node.js
async function waitForTask(taskId, timeout = 300_000, interval = 5_000) {
const start = Date.now();
while (Date.now() - start < timeout) {
const res = await fetch(`${BASE}/api/v1/tasks/${taskId}`, {
headers: { "x-api-key": API_KEY },
});
const { status, progress_percent } = await res.json();
console.log(`Status: ${status} (${progress_percent}%)`);
if (status === "completed") return true;
if (status === "failed") throw new Error(`Task ${taskId} failed`);
await new Promise((r) => setTimeout(r, interval));
}
throw new Error(`Task ${taskId} timed out`);
}
await waitForTask(124);Получение и обработка результатов
Когда задача в статусе completed, забирайте результаты двумя способами.
JSON-результаты: GET /api/v1/tasks/{taskId}/results
curl "https://api.uchecker.net/api/v1/tasks/124/results?format=json" \
-H "x-api-key: YOUR_API_KEY"{
"success": true,
"format": "json",
"data": [
{
"email": "alice@company.com",
"validation_result": "good"
},
{
"email": "bob@example.org",
"validation_result": "bad",
"result": "mailbox_not_found"
},
{
"email": "carol@domain.net",
"validation_result": "good"
}
]
}Параметр format принимает значения json или csv. Для программной обработки используйте JSON, для импорта в таблицы - CSV.
resp = requests.get(
f"{BASE}/api/v1/tasks/124/results",
headers={"x-api-key": API_KEY},
params={"format": "json"},
)
results = resp.json()["data"]
good = [r["email"] for r in results if r["validation_result"] == "good"]
bad = [r["email"] for r in results if r["validation_result"] == "bad"]
print(f"Valid: {len(good)}, Invalid: {len(bad)}")ZIP-архив: GET /api/v1/tasks/{taskId}/download
Возвращает ZIP с двумя файлами: good.txt и bad.txt - по одному email на строку.
curl "https://api.uchecker.net/api/v1/tasks/124/download" \
-H "x-api-key: YOUR_API_KEY" \
-o results.zipimport zipfile, io
resp = requests.get(
f"{BASE}/api/v1/tasks/124/download",
headers={"x-api-key": API_KEY},
)
with zipfile.ZipFile(io.BytesIO(resp.content)) as zf:
good = zf.read("good.txt").decode().splitlines()
bad = zf.read("bad.txt").decode().splitlines()
print(f"Good: {len(good)}, Bad: {len(bad)}")Управление задачами и балансом
Проверка баланса: GET /api/v1/account/balance
Всегда проверяйте баланс перед bulk-запросом, чтобы избежать ошибки 403 (Insufficient credits).
curl https://api.uchecker.net/api/v1/account/balance \
-H "x-api-key: YOUR_API_KEY"{
"success": true,
"account_id": 123456,
"credits_remaining": 1000,
"api_key": "uk_xxxxx..."
}Список задач: GET /api/v1/tasks
Пагинированный список всех задач. Сортировка - по дате создания (новые первые).
curl "https://api.uchecker.net/api/v1/tasks?page=1&limit=10" \
-H "x-api-key: YOUR_API_KEY"{
"success": true,
"tasks": [
{
"task_id": 124,
"fileName": "bulk_100_emails",
"status": "completed",
"created_at": "2024-01-01T12:00:00.000Z",
"finished_at": "2024-01-01T12:01:35.000Z"
}
],
"total": 50,
"page": 1,
"limit": 10
}История платежей: GET /api/v1/billing/history
Пагинированный список всех платежей - для сверки и отчётности.
curl "https://api.uchecker.net/api/v1/billing/history?page=1&limit=10" \
-H "x-api-key: YOUR_API_KEY"{
"data": [
{
"id": 1,
"amount": 1000,
"status": "completed",
"product_details": "5000 addresses (5k) via freekassa from web",
"creation_date": "2024-01-01T12:00:00.000Z",
"payment_id": "uuid-xxx"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 5,
"totalPages": 1
}
}Обработка ошибок и best practices
HTTP-коды ошибок
| Код | Причина | Что делать |
|---|---|---|
| 401 | Невалидный или отсутствующий API-ключ | Проверьте заголовок x-api-key |
| 403 | Недостаточно кредитов | Пополните баланс или уменьшите batch |
| 404 | Задача не найдена | Проверьте task_id и принадлежность |
Рекомендации
Проверяйте баланс перед bulk-запросом
GET /api/v1/account/balance → сравните credits_remaining с размером батча.
Используйте env-переменные для ключей
Никогда не коммитьте API-ключи в репозиторий. Используйте .env, Vault или секреты CI/CD.
Реализуйте retry с backoff для failed задач
Если задача упала - подождите и создайте новую. Экспоненциальный backoff: 5s → 10s → 20s.
Разбивайте большие базы на батчи
Для 100K+ адресов отправляйте несколько bulk-запросов. Так проще отслеживать прогресс и обрабатывать ошибки.
Сохраняйте результаты
Кешируйте результаты валидации. Повторная проверка того же email через день - пустая трата кредитов.
Итого
Полный flow интеграции uChecker API:
Всё через REST API, стандартный JSON. Никаких SDK или зависимостей - работает с любым HTTP-клиентом на любом языке.
Зарегистрируйтесь на app.uchecker.net, получите API-ключ и запустите первый запрос за 5 минут.
Начать бесплатно