uCheckeruChecker
Blog/API Guide
⚡ For developersFebruary 21, 202610 min read

uChecker API developer guide

From getting your API key to processing bulk validation results. Working examples in curl, Python, and Node.js.

$ 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"}'

A dirty email list means a bounce rate above 5%, an ESP suspension, and money wasted on addresses that never deliver. Manual checking does not scale. You need validation built into your pipeline.

This guide covers the full uChecker API integration flow: authentication, single and bulk validation, task polling, and result retrieval. All examples are tested and ready to run.

🌐

Base URL

https://api.uchecker.net

All endpoints below are relative to this URL. Requests and responses use JSON.

Authentication

The API supports two authentication methods:

🔑

API Key recommended

Pass the key in the x-api-key header. Simple and safe for server-side integrations.

🎫

Bearer JWT

JWT token from /auth/login. Access tokens expire after 1 hour; refresh tokens last 7 days.

Getting an API key: POST /auth/login

Register at app.uchecker.net, then retrieve your key via the login endpoint:

curl
curl -X POST https://api.uchecker.net/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "your_password"
  }'
Response 200
{
  "user": {
    "id": 1,
    "email": "you@example.com",
    "telegram_code": 123456
  },
  "api_key": "uk_xxxxxxxxxxxxx",
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}

Store the api_key. It stays the same until you explicitly rotate it via POST /auth/reset-api-key.

⚠️

Never hardcode your API key in source code. Store it in an environment variable: UCHECKER_API_KEY.

🔐
Two auth methods: API Key (simple) and JWT (flexible)

Single email validation

The POST /api/v1/validate/single endpoint checks one address in real time. Use it for registration form validation.

Request body

{
  "email": "user@example.com"
}

Optional: webhook_url to receive a notification when the job finishes.

curl
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"}'
Python
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"])
Node.js
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"
}

The request queues the email and returns a task_id. Use it to poll status and fetch the result.

Bulk validation

POST /api/v1/validate/bulk accepts an array of addresses. Any address with invalid syntax is filtered out automatically and not billed. You can also pass a webhook_url for completion notification.

curl
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"
    ]
  }'
Python
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"
}

The invalid_details field shows which addresses were filtered and why. Credits are charged only for addresses that passed syntax validation.

Try the uChecker API

Free credits on signup. Get your API key in 30 seconds and send your first request.

Get API key

Task status polling

Validation is asynchronous. After submitting a request, poll GET /api/v1/tasks/{taskId} until the status reaches completed or failed.

StatusCodeDescription
pending0Task created, waiting in queue
processing1Addresses are being checked
completed2Done, results are ready
failed-2Processing error
curl
curl https://api.uchecker.net/api/v1/tasks/124 \
  -H "x-api-key: YOUR_API_KEY"
Response 200
{
  "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 loop in Python

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 loop in Node.js

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);
🔄
Async flow: submit request, poll status, retrieve results

Retrieving and processing results

Once a task reaches completed status, you can fetch results in two ways.

JSON results: GET /api/v1/tasks/{taskId}/results

curl
curl "https://api.uchecker.net/api/v1/tasks/124/results?format=json" \
  -H "x-api-key: YOUR_API_KEY"
Response 200
{
  "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"
    }
  ]
}

The format parameter accepts json or csv. Use JSON for programmatic processing, CSV for spreadsheet imports.

Python - processing results
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 archive: GET /api/v1/tasks/{taskId}/download

Returns a ZIP with two files: good.txt and bad.txt, one email per line.

curl
curl "https://api.uchecker.net/api/v1/tasks/124/download" \
  -H "x-api-key: YOUR_API_KEY" \
  -o results.zip
Python - download and unzip
import 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)}")

Tasks and balance

Check balance: GET /api/v1/account/balance

Always check your balance before a bulk request to avoid a 403 (Insufficient credits) error mid-job.

curl
curl https://api.uchecker.net/api/v1/account/balance \
  -H "x-api-key: YOUR_API_KEY"
Response 200
{
  "success": true,
  "account_id": 123456,
  "credits_remaining": 1000,
  "api_key": "uk_xxxxx..."
}

List tasks: GET /api/v1/tasks

Paginated list of all your tasks, sorted by creation date (newest first).

curl
curl "https://api.uchecker.net/api/v1/tasks?page=1&limit=10" \
  -H "x-api-key: YOUR_API_KEY"
Response 200
{
  "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
}

Payment history: GET /api/v1/billing/history

Paginated list of all payments, useful for reconciliation and reporting.

curl
curl "https://api.uchecker.net/api/v1/billing/history?page=1&limit=10" \
  -H "x-api-key: YOUR_API_KEY"
Response 200
{
  "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
  }
}
📊
Monitor balance, tasks, and payments through the API

Error handling and best practices

HTTP error codes

CodeCauseFix
401Missing or invalid API keyCheck the x-api-key header
403Insufficient creditsTop up your balance or reduce the batch size
404Task not foundVerify the task_id and ownership

Recommendations

Check balance before bulk requests

GET /api/v1/account/balance and compare credits_remaining against your batch size before submitting.

Use environment variables for keys

Never commit API keys to a repository. Store them in .env files, Vault, or CI/CD secrets.

Implement retry with backoff for failed tasks

If a task fails, wait and create a new one. Exponential backoff works well: 5s, 10s, 20s.

Split large lists into batches

For 100K+ addresses, send several bulk requests. Smaller batches are easier to track and recover if one fails.

Cache validation results

Store results locally. Re-checking the same address a day later wastes credits with no new information.

Summary

The full uChecker API integration flow in five steps:

Sign upAPI keySingle / BulkPollingResults

Plain REST with standard JSON. No SDKs or extra dependencies — any HTTP client on any language works.

Register at app.uchecker.net, get your API key, and send your first request in under five minutes.

Start for free
email validation apibulk email validationrest apiuchecker apideveloper guideemail verificationapi integration