Skip to content
SimpleCold

API docs

Get started

SimpleCold API reference

On this page

Verify email addresses from your own code. Every result comes back with a category, a reason code and a plain-English reason. Every example in these docs uses the real request and response shapes.

Endpoints

All endpoints use the same API key, sent as a Bearer token.

MethodPathWhat it does
GET/api/v1/api-validation/validateChecks that your API key works. Uses no credits.
GET/api/v1/api-validation/singleVerifies one address in real time.
GET/api/v1/api-validation/single/resultCollects the final result of a check that came back as processing. Uses no credits.
POST/api/v1/api-validation/batchVerifies up to 50 addresses in one request.
POST/api/v1/api-validation/bulkUploads a CSV file and starts a background job.
GET/api/v1/api-validation/bulk/:id/statusReports a bulk job's status and progress.
GET/api/v1/api-validation/bulk/:id/download-resultDownloads a bulk job's results as CSV or JSON.

Base URL

Base URL
https://simplecold.com/api/v1

The paths in these docs are relative to that base. For example, the single endpoint is https://simplecold.com/api/v1/api-validation/single.

Authentication

Send your API key in the Authorization header on every request:

Text
Authorization: Bearer <your-api-key>

There is no query-string key and no basic auth. See Using your API key for examples and the errors you can get back.

Response format

Successful JSON responses use one envelope. The result is always inside payload:

200 · Success
{
  "code": "SUCCESS",
  "message": "Successfully performed operation.",
  "payload": { "...": "..." },
  "requestId": "9b07c1d2-..."
}

Errors raised by the API use a second shape:

4xx / 5xx · Error
{
  "code": "FAILURE",
  "message": "Invalid API key",
  "data": null
}

If a query parameter, path parameter or body field fails validation (for example a malformed email address), you get a 400 with the list of problems in data:

400 · Invalid input
{
  "success": false,
  "message": "Please check your input and try again.",
  "data": [
    {
      "validation": "email",
      "code": "invalid_string",
      "message": "Invalid email address",
      "path": ["email"]
    }
  ]
}

Rate-limit responses use the same code and message fields, with details in data, plus status and error fields kept for older integrations (see Rate limits):

429 · Rate limited
{
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded. Maximum 100 requests per minute per API key.",
  "data": {
    "policy": "api.single",
    "retryAfterSeconds": 1,
    "limit": 100,
    "scope": "apiKey",
    "blocked": false
  },
  "status": 429,
  "error": "Rate limit exceeded. Maximum 100 requests per minute per API key."
}

So branch on the HTTP status code, and read the error text as body.message ?? body.error. Server errors (5xx) return the message Internal Server Error.

Every response, success or error, also carries an X-Request-Id header with the same value as requestId.

Bulk downloads are the one exception: a successful download returns the file itself, not the JSON envelope.

Rate limits

Limits are counted per API key, per minute.

EndpointLimit per key
GET /api-validation/single and GET /api-validation/single/result100 requests per minute (shared)
POST /api-validation/batch10 requests per minute
POST /api-validation/bulk10 uploads per minute
GET /api-validation/bulk/:id/status120 requests per minute
GET /api-validation/bulk/:id/download-result30 requests per minute

Each key has its own budget, and your organisation as a whole gets three keys' worth, so extra keys don't multiply the limit. Responses carry the standard RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset and RateLimit-Policy headers. When you go over, you get a 429 with a Retry-After header; wait that many seconds before trying again. Rate limits has every limit, the headers and retry code.

Credits

One credit verifies one address.

  • Single and batch: credits for the request are reserved when it arrives and charged once each address has a final result. If an address comes back processing, collecting its result later does not charge again.
  • Bulk: credits for every unique address in the file are reserved when you upload it. Duplicate addresses in the file are removed first and are not charged.
  • Test addresses never use credits on the single and batch endpoints. See Test emails.
  • Test keys (sc_test_…) never use credits at all. See Sandbox.

If your balance can't cover a request, it fails with a 400 and the message Insufficient credits. (or Please buy credits. when the balance is empty). Retrying won't help; top up in the dashboard.

Getting started

  1. Create an account. Sign up at simplecold.com/dashboard/signup and verify your email.
  2. Create an API key. Open API keys in the dashboard. See Create an API key.
  3. Check the key. Call GET /api-validation/validate. It uses no credits.
  4. Build against the sandbox. Create a test key and use the sandbox addresses: every result, processing and polling, simulated errors, bulk jobs and webhooks, with no credits and a zero balance. Switch to a live key when you're done.
  5. Or try a live key with test addresses. The test emails return fixed results and don't use credits on single and batch requests, even with a balance of zero.
  6. Pick the endpoint that fits:

There are no official SDKs. Everything is plain HTTPS and JSON. Long-running work can be collected by polling, or pushed to you with webhooks.

Support

Questions about an integration? Contact support. Include the requestId from the response if you are asking about a specific result.

Introduction | SimpleCold API docs