Error format
All non-2xx responses return:
{
"error": {
"code": "string",
"message": "string"
}
}
Error codes
| HTTP Status | Code | Description |
|---|---|---|
| 400 | validation_error |
Request body invalid (missing required field, wrong type) |
| 401 | unauthorized |
Missing or invalid X-Api-Key |
| 402 | insufficient_credits |
Credit balance is zero |
| 404 | not_found |
Resource (e.g., batch job ID) not found |
| 422 | unprocessable |
Request parsed but semantically invalid |
| 429 | rate_limited |
Too many requests — back off and retry |
| 500 | internal_error |
Unexpected server error |
| 503 | service_unavailable |
Upstream dependency (HLR, IP DB) temporarily down |
Handling errors in code
import { Checkharbor, CheckharborError } from "@checkharbor/node";const checkharbor = new Checkharbor({ apiKey: process.env.CHECKHARBOR_API_KEY! });
try {
const result = await checkharbor.validateEmail("test@example.com");
} catch (e) {
if (e instanceof CheckharborError) {
if (e.code === "insufficient_credits") {
// redirect to billing
}
if (e.code === "rate_limited") {
// implement exponential backoff
}
console.error(`[${e.code}] ${e.message} (status ${e.status})`);
}
}
```
from checkharbor import Checkharbor, CheckharborErrorclient = Checkharbor(api_key="chk_live_...")
try:
result = client.validate_email("test@example.com")
except CheckharborError as e:
if e.code == "insufficient_credits":
pass # redirect to billing
if e.code == "rate_limited":
pass # implement exponential backoff
print(f"[{e.code}] {e} (status {e.status})")
```
# HTTP 402 example
curl -X POST https://api.checkharbor.com/v1/email/validate \
-H "X-Api-Key: chk_live_..." \
-d '{"email":"x@y.com"}'# Response:
# HTTP/2 402
# {
# "error": {
# "code": "insufficient_credits",
# "message": "Not enough credits. Top up at console.checkharbor.com/billing."
# }
# }
```
Retry strategy
For 429 rate_limited errors, use exponential backoff:
- Wait 1s → retry
- Wait 2s → retry
- Wait 4s → retry
- Give up after 3 retries
Batch jobs use polling (GET /v1/batch/:id) rather than rate-limited single calls, so they are a better option for bulk workloads.