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
invalid_requestMalformed JSON, a missing url, a non-http(s) target, or a parameter outside its allowed range.
unauthorizedMissing, malformed, unknown, or revoked API key. The response is identical in every case.
insufficient_creditsThe balance does not cover the request. The response includes required and balance.
invalid_requestWrong HTTP method for the endpoint. All three endpoints are POST-only.
upstream_errordatamint 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?