Overview
The API exposes one verification endpoint today. It accepts a single email address and returns a classification decided by the same validator the dashboard uses — no separate ruleset, no silent downgrade. All responses carry Cache-Control: no-store and a X-RateLimit-Remaining header.
POST /api/v1/validate— verify a single address. Bulk submission and webhook notifications are on the roadmap.Authentication
Every API call must carry a bearer token in the Authorizationheader. Tokens are issued from the dashboard and are shown once on creation — only the SHA-256 digest is stored server-side, so a lost key cannot be recovered, only revoked and replaced.
Authorization: Bearer pl_live_a1b2c3d4e5f6…
Creating a key
- Sign in to your dashboard.
- Open the API keys panel.
- Name the key (e.g. production-api), hit Generate, and copy the plaintext token immediately. It will never be shown again.
- Paste it into your server’s secret store. Never commit keys to source control or ship them in client-side bundles.
Key details
| Prefix | pl_live_ followed by 32 bytes of base64url entropy |
|---|---|
| Storage | SHA-256 hash only; plaintext is never persisted |
| Scope | validate:single (issued by default) |
| Limit | Ten active keys per account. Revoke before creating new ones. |
| Revocation | Instant from the dashboard. Subsequent calls return 401. |
Rate limits
Each key carries its own token bucket. You can burst up to ten requests immediately, and the bucket refills at one request per second thereafter. Limits are enforced per key, not per account — high-volume services should use a dedicated key.
| Burst | 10 requests |
|---|---|
| Sustained | 1 request per second |
| Success header | X-RateLimit-Remaining: <integer> |
| Exceeded | 429 Too Many Requests with Retry-After: <seconds> |
Clients should honour Retry-Afterwith a sleep or queue — retrying immediately will simply 429 again.
Errors
Every error response is JSON with a single error key describing what went wrong. No stack traces, no PII.
{ "error": "Missing bearer token" }| Status | Meaning | Typical cause |
|---|---|---|
400 | Bad request | Malformed JSON body, missing or non-string email, address fails syntax check. |
401 | Unauthenticated | Missing bearer token, token does not match any key, key revoked, or key expired. Response carries aWWW-Authenticate challenge. |
403 | Insufficient scope | Key exists but its scope list excludes validate:single. Body also carries required. |
405 | Method not allowed | Only POST is accepted on /api/v1/validate. |
429 | Rate limited | Bucket exhausted for this key. Back off per Retry-After. |
503 | Validator unavailable | The verification daemon is momentarily unreachable. Safe to retry. |
Validate an email
Verifies a single email address. The validator attempts up to three SMTP handshakes before returning — uncertain probes are resolved into a definitive invalid rather than exposed to the client.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes | Address to verify. Maximum 254 characters; rejected with 400 if it fails syntax check. |
Response body
| Field | Type | Description |
|---|---|---|
email | string | The address that was verified (normalised by the validator). |
classification | "deliverable" | "invalid" | Final verdict. See Classifications. |
Example
curl https://app.postelist.com/api/v1/validate \
-H "Authorization: Bearer pl_live_a1b2c3d4e5f6…" \
-H "Content-Type: application/json" \
-d '{"email": "ada@postelist.com"}'{
"email": "ada@postelist.com",
"classification": "deliverable"
}Classifications
The API returns one of two values. There is no risky, no catch-all, no unknown— probes that cannot be resolved after retries are recorded as invalid rather than handed back as a maybe.
deliverableThe receiving mail server confirmed the mailbox exists and is accepting mail. Safe to send.
invalidThe mailbox does not exist, the domain does not accept mail, or the address could not be confirmed after three attempts. Do not send.
Roadmap
Two additions are planned. When they ship, they will be documented here with the same precision as the rest of this reference.
- Bulk submission
POST /api/v1/jobsto hand off a list of addresses, with a polling endpoint to stream results back as JSON or CSV. - Webhook callbacks
HMAC-signed POST to a URL of your choosing when a bulk job finishes. Idempotent; retried on transient failure.