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, CheckharborError
client = 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.