Errors
Understand response envelopes, diagnose failures, and decide when to retry.
https://api.dehashit.com/api/v1/Errors
Successful responses return {"status": true, "status_code": 0, "message": "...", "data": {...}}. Failed responses return status: false, set the HTTP response code to match status_code, and usually provide a machine-readable error_code. Branch on error_code, not on message. Use the HTTP status as a fallback when no error code is provided.
Error codes and recovery
| HTTP | error_code | Meaning and next step |
|---|---|---|
| 400 | invalid_request | Request payload failed validation. Inspect errors for field details. |
| 401 | unauthorized | Missing, invalid, or revoked API key. |
| 402 | insufficient_balance | Match found, but wallet balance is below the lookup fee. Number withheld. |
| 403 | forbidden | Browser origin or CSRF checks failed, permissions are insufficient, or a service key attempted batch access. |
| 404 | not_found | No matching hash, unsupported country, missing resource, or expired batch results. Do not retry unchanged. |
| 405 | — | HTTP method is not supported. This response has no error_code; check the endpoint method. |
| 409 | idempotency_key_in_progress | Batch is still processing or its results are not ready. Wait before checking the same job again. |
| 413 | payload_too_large | Request body exceeds 8 KiB, or 2 MiB for a batch upload. Reduce its size. |
| 422 | idempotency_key_reused | The retry key was used with another hash or different batch bytes. Use a new key for a new lookup or upload. |
| 429 | rate_limited | Rate limit exceeded. Wait for Retry-After seconds before retrying. |
| 502 | provider_failed | M-Pesa gateway call failed (top-ups only). |
| 503 | dataset_unavailable | Lookup is temporarily unavailable. Retry later; never billed. |
| 503 | dataset_format_legacy | Lookup is paused for maintenance. Retry later or contact support; never billed. |
| 503 | lookup_timeout | Lookup timed out. Retry; never billed. |
| 503 | unavailable | Billing or database unavailable. Never billed. |
Error handling example
curl -i -X POST https://api.dehashit.com/api/v1/msisdn/decrypt/ \
-H "X-Api-Key: invalid_key" \
-H "Content-Type: application/json" \
-d '{"msisdn_hash": "7132104d6aae9c3fac82095a42c2817952bca48e09d98d5bf4ac08218982fb90"}'import requests
res = requests.post(
"https://api.dehashit.com/api/v1/msisdn/decrypt/",
headers={"X-Api-Key": "dh_live_..."},
json={"msisdn_hash": "7132104d6aae9c3fac82095a42c2817952bca48e09d98d5bf4ac08218982fb90"},
timeout=10,
)
payload = res.json()
if not payload.get("status"):
error_code = payload.get("error_code")
if error_code == "insufficient_balance":
print("Please top up your wallet.")
elif error_code == "not_found":
print("No match for this hash.")
else:
print(f"Error {res.status_code}: {payload.get('message')}")const res = await fetch("https://api.dehashit.com/api/v1/msisdn/decrypt/", {
method: "POST",
headers: { "X-Api-Key": "dh_live_...", "Content-Type": "application/json" },
body: JSON.stringify({ msisdn_hash: "7132104d6aae9c3fac82095a42c2817952bca48e09d98d5bf4ac08218982fb90" }),
});
const body = await res.json();
if (!body.status) {
switch (body.error_code) {
case "insufficient_balance":
console.error("Top up required.");
break;
case "not_found":
console.warn("Hash not found.");
break;
default:
console.error(`Error (${res.status}): ${body.message}`);
}
}package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type APIEnvelope struct {
Status bool `json:"status"`
StatusCode int `json:"status_code"`
ErrorCode string `json:"error_code,omitempty"`
Message string `json:"message"`
}
func main() {
body, _ := json.Marshal(map[string]string{
"msisdn_hash": "7132104d6aae9c3fac82095a42c2817952bca48e09d98d5bf4ac08218982fb90",
})
req, _ := http.NewRequest("POST", "https://api.dehashit.com/api/v1/msisdn/decrypt/", bytes.NewReader(body))
req.Header.Set("X-Api-Key", "dh_live_...")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var envelope APIEnvelope
if err := json.NewDecoder(res.Body).Decode(&envelope); err != nil {
panic(err)
}
if !envelope.Status {
fmt.Printf("API error: %s (HTTP %d): %s\n", envelope.ErrorCode, envelope.StatusCode, envelope.Message)
}
}Error response
{
"status": false,
"status_code": 401,
"error_code": "unauthorized",
"message": "Invalid API key.",
"data": {}
}This 401 example shows an invalid or revoked key. A missing key returns the same envelope with the message Authentication credentials were not provided.
Unknown JSON fields are rejected (400 invalid_request). An Idempotency-Key longer than 128 characters is also 400 invalid_request. Every response carries X-Request-ID; quote it when contacting support.
Need a hand with your integration? Contact support.