Errors

Every failure returns the same envelope, so one error handler covers the whole API.

The envelope

{
  "error": {
    "code": "insufficient_credits",
    "message": "This request costs 17 credits and your balance is 4. Top up or upgrade to continue.",
    "required": 17,
    "balance": 4
  }
}

Branch on code, never on message. The message is written for a human reading a log and will change as the copy improves. The code is the stable contract.

Statuses

400invalid_request

Malformed JSON, a missing url, a non-http(s) target, or a parameter outside its allowed range.

401unauthorized

Missing, malformed, unknown, or revoked API key. The response is identical in every case.

402insufficient_credits

The balance does not cover the request. The response includes required and balance.

405invalid_request

Wrong HTTP method for the endpoint. All three endpoints are POST-only.

502upstream_error

datamint could not reach its own extraction engine. The request was not served.

Two that are easy to misread

401 does not distinguish between failure modes. A key that never existed and a key that was revoked produce byte-identical responses. That is deliberate. See Authentication. Do not write retry logic that depends on telling them apart.

502 is about datamint, not your target. It means the request reached the API but the extraction engine behind it could not be reached, so no extraction happened. It is not a signal that the target site failed to respond: a target that refuses or times out surfaces through the extraction result, not as a 502. Treat a 502 as retryable on a short backoff.

Not billed

Requests that fail before extraction (400, 401, 402, 405, and 502) do not consume credits. The quota check happens before any upstream work, so a refusal costs nothing.

Credits are consumed on successful delivery. See Credits.

Need volume pricing or a custom parser?