Error codes

Every error HempData returns comes with a stable code and a doc_url that deep-links to the matching row below. Handle codes, not messages — messages may be tuned; codes are contracts.

Envelope shape:
{
  "success": false,
  "data": null,
  "meta": { "request_id": "req_...", "api_version": "v1" },
  "errors": [
    {
      "code": "MONTHLY_QUOTA_EXCEEDED",
      "message": "You've used all 10 product checks on the free tier this month.",
      "doc_url": "https://api.hempdata.io/errors#error-MONTHLY_QUOTA_EXCEEDED"
    }
  ]
}
Code HTTP What it means How to recover
ENDPOINT_UNREACHABLE 400 We could not reach your webhook endpoint URL. Verify the URL, DNS, and that the server accepts HTTPS POSTs from the public internet. #
ENDPOINT_VALIDATION_FAILED 400 The webhook-subscription test event to your endpoint returned a non-2xx. Ensure your endpoint returns HTTP 200-299 for the test event. Log the request body to debug. #
HTTPS_REQUIRED 400 Webhook endpoints must use HTTPS. Expose your endpoint over HTTPS (terminate TLS at your load balancer or use a tunnel such as ngrok for local development). #
INVALID_KEY_TYPE 400 An endpoint requiring a publishable key received a secret key (or vice-versa). Use `hda_*_pk_*` for client-side widgets and `hda_*_sk_*` for server-side calls. #
INVALID_SIGNATURE 400 A webhook signature failed verification against the shared secret. Check your webhook signing secret. Re-fetch it from the sender dashboard if you rotated it. #
INVALID_TIER 400 Billing checkout was requested with an unknown tier name. Use one of: retailer, brand, enterprise. See hempdata.io/pricing. #
INVALID_URL 400 The provided `endpoint_url` is not a valid URL. Send a fully-qualified HTTPS URL (include scheme + host). #
MISSING_ENDPOINT 400 Webhook subscription request did not include `endpoint_url`. Send `endpoint_url` as a public HTTPS URL in the body. #
MISSING_FIELDS 400 Required fields are missing from the request body. Re-read the reference for that endpoint and include every field marked required. #
MISSING_SIGNATURE 400 A webhook was received without the required signature header. Send `Stripe-Signature` (or the documented signature header) with every webhook. Only HempData-originated webhooks should hit this endpoint. #
STATE_REQUIRED 400 The widget could not auto-detect a state and none was provided. Pass `state` explicitly, or enable auto-detect with a verified origin. #
VALIDATION_ERROR 400 The request body or query parameters failed validation. Inspect the `message` field for the specific path that failed, fix the field, and retry. #
DEMO_KEY_INVALID 401 The presented demo key is not the active playground demo key. Only the published `hd_demo_public_*` key works. Sign up for a real key for your own app. #
MISSING_ADMIN_KEY 401 An `/ops/*` endpoint was called without the required admin shared secret. Send `X-Admin-Key: <secret>`. `/ops/*` is for HempData operators only. #
UNAUTHORIZED 401 The API key is missing, malformed, or does not match any active key on file. Send a valid key as `Authorization: Bearer hda_live_sk_...`. Generate or rotate a key at hempdata.io/dashboard. #
DEMO_ORIGIN_DENIED 403 A playground demo key was presented from an origin not on the allow-list. Only the hempdata.io and api.hempdata.io playgrounds may use demo keys. Use your own key elsewhere. #
DEMO_PATH_DENIED 403 A playground demo key was used on a path demo keys are not authorized for. Demo keys work only on a curated subset of read endpoints. Use your own key to access everything else. #
FORBIDDEN 403 The key is valid but the subscriber or key is deactivated, or the caller lacks access to the requested resource. Reactivate the key in the dashboard, or contact [email protected] if you expect access. #
NOT_FOUND 404 The endpoint, resource, or record you asked for does not exist. Double-check the path and any IDs. Browse the /reference page for the current surface. #
ALREADY_EXISTS 409 A record with the given identifier (most often email) already exists. Fetch the existing record or use a different identifier. For subscribers, log in instead of re-registering. #
DEMO_RATE_LIMITED 429 The public playground demo key exceeded its per-hour or per-day cap. Sign up for a free account at hempdata.io/signup — your own key gets a real monthly quota. #
MONTHLY_QUOTA_EXCEEDED 429 You hit the monthly product-check or state-lookup cap for your tier. Wait until the 1st of next month, or upgrade at hempdata.io/pricing. `resets_at` is in the error body. #
RATE_LIMITED 429 You exceeded the per-minute request limit for your tier. Back off exponentially (start 1s, cap 60s) and honor `Retry-After`. Upgrade at hempdata.io/pricing for a higher limit. #
DEMO_MISCONFIGURED 500 The playground demo key is not configured on the server. Contact [email protected] — this is a server-side misconfiguration, not your request. #
HANDLER_ERROR 500 A webhook handler or internal function threw an uncaught error. Retry the webhook per your sender’s retry policy. Send the `request_id` to support for investigation. #
INTERNAL_ERROR 500 An unhandled server error occurred. Retry with exponential backoff. Send the `request_id` from the response to [email protected] for investigation. #
PRICE_NOT_FOUND 500 No Stripe price exists for the requested tier + billing period. Contact [email protected]. Most often resolved by picking a different billing_period. #
PRODUCT_NOT_FOUND 500 The Stripe product catalogue is not configured on the server. Contact [email protected] — server-side setup issue. #
DEMO_DISABLED 503 The public playground is temporarily disabled on the server. Retry later, or sign up for a real account — authenticated traffic is unaffected. #
DEMO_GLOBAL_CAPACITY 503 The playground demo hit its global hourly cap across all anonymous callers. Try again in an hour, or sign up for a free account for your own capacity. #
DEMO_RATE_LIMIT_UNAVAILABLE 503 Demo rate-limiting depends on Redis; Redis is unreachable. Retry in a moment. Authenticated callers with their own key are unaffected. #
OPS_DISABLED 503 The admin ops surface is disabled on this server. Contact HempData. The public API is unaffected. #
SERVICE_UNAVAILABLE 503 A backing service (database or Redis) is temporarily unreachable. Retry with exponential backoff. Check /status for live health. Contact support if it persists >5 min. #

Missing a code? Send the request_id from the error envelope to [email protected] and we will document it.