Skip to main content
Context.dev errors include an HTTP status, a human-readable message, and usually a stable error_code. Use the status to identify the broad category and the code to decide what the application should do.

Start with the evidence

Before changing retry logic:
  1. Record the operation, timestamp, status, error_code, and response headers.
  2. Confirm that CONTEXT_DEV_API_KEY exists without printing its value.
  3. Reproduce the request with raw HTTPS so SDK serialization is not part of the test.
  4. Compare the request with the operation’s current API-reference page.
  5. Check the status page when unrelated operations fail at the same time.
Choose an operation, then compare cURL with your SDK. The SDK examples disable automatic retries so you can inspect the first response. Keep diagnostic output private and redact it before sharing.
If raw HTTPS succeeds and the SDK call fails, inspect the installed package version, generated method signature, serialized path, and request body.

Trace a request through logs

Save the original call’s request_id or X-Request-Id. Use that ID with Retrieve Request Log to inspect retained inputs, response content, status, and credit usage. A restricted key needs logs:read; log endpoints cost zero credits and use a separate rate limit. Replace the example UUID below with the ID of the call you are investigating. The returned data.request_id identifies that original call; the outer request_id identifies the log-retrieval request itself.
These examples use the SDKs’ low-level request methods to send the current API contract, including fields not yet exposed by the 2.14.0 typed helpers. Authentication, retries, and error handling still come from the SDK. See SDK compatibility.
Keep diagnostic output to metadata you need; retained inputs and responses can contain application data even after credential redaction. Recognized credential fields, nested header entries, and credentials in URLs are redacted on ingestion and when older logs are read. ZDR requests retain operational metadata without request/response content. To find related calls, List Request Logs accepts key_id, path, status_code, error_code, tags, and time filters. The dashboard’s per-key usage links apply key filters to both charts and logs. to defaults to now and from to 24 hours before to. Explicit ranges longer than 30 days are accepted; a larger query window does not extend the retention of available records.

Decide by status

The same error_code can appear under different statuses on different operations. Build logic around the combination documented for the endpoint you call.

Input and website errors

WEBSITE_BLOCKED on the scrape endpoints is not billed. For any error response that includes key_metadata, use credits_consumed as the operation-specific billing evidence. Direct HTTP and PDF fetching requires public HTTP(S) destinations and checks redirects, DNS/IP safety, and TLS certificates. Correct an invalid certificate or private destination instead of retrying the same inaccessible source. Challenge pages are not usable content; scraping tries available fallback routes and returns WEBSITE_BLOCKED when access remains blocked.

Authentication and access

For 401 UNAUTHORIZED:
Common causes are a misspelled variable, an unloaded .env file, a rotated key, or initializing the client before environment loading runs. For 401 DISABLED, check the key and organization state in the dashboard. Contact [email protected] if access remains disabled; do not keep retrying. For 403, inspect the code: Repeating a 401 or 403 request does not repair credentials or permissions.

Handle timeouts

timeoutOpts.milliseconds sets the request deadline. behavior: "fail" is the default; supported operations can instead return usable incomplete data with behavior: "return-partial". Preserve partial: true or finalDOMState: "still-loading". If no usable result exists, the request fails without a charge. See Timeouts and partial results, including the product-catalog migration. Cache misses and operations that crawl or run models can take longer than cache hits. For a Brand request on a cold domain, a timeout below 10 seconds can return 422 COLD_DOMAIN_TIMEOUT_TOO_LOW before retrieval starts. Raise the budget or prefetch the identifier before it is needed. For 408 REQUEST_TIMEOUT:
  • Move optional work to a background job.
  • Increase timeoutOpts.milliseconds only when the product can wait longer.
  • Use a smaller crawl or extraction scope.
  • Retry with a small total attempt count.
  • Do not hide a multi-minute retry chain inside a user request.

Handle email rejection

Invalid email

Brand-by-email, people enrichment, and email prefetch operations can return:
  • FREE_EMAIL_DETECTED
  • DISPOSABLE_EMAIL_DETECTED
  • INPUT_VALIDATION_ERROR for malformed input
Treat these as validation outcomes. Ask for a work email, allow manual company entry, or skip enrichment. Do not retry the same address.

Content limits

Changing a timeout or retry delay does not fix a size or media-type failure.

Handle ZDR errors

Do not silently retry without zdr; that changes the data-handling promise. Either stop the request or follow an explicitly approved non-ZDR path. See Zero Data Retention.

Batch and monitor errors

These codes describe resource state rather than a transient transport problem:
  • BATCH_LIMIT_EXCEEDED: wait for active work to finish or reduce concurrency.
  • BATCH_NOT_COMPLETED: keep polling with backoff; results are not ready.
  • BATCH_NOT_CANCELLABLE: the batch has reached a state that cannot be cancelled.
  • IDEMPOTENCY_KEY_CONFLICT: the key was reused with a different body; use the original body or a new key.
  • MONITOR_LIMIT_EXCEEDED: reduce monitor count or change the plan.
  • MONITOR_PAUSED: resume the monitor before running it.
  • MONITOR_NO_WEBHOOK: add a webhook before rotating its secret.
Use the Batch guide or Monitor guide for the relevant state machine.

Diagnose SDK mismatches

Check these when cURL works:
  • The installed package version matches the documentation you followed.
  • Parameter casing matches the language, such as maxAgeMs in TypeScript and max_age_ms in Python.
  • The SDK sends the documented HTTP method and path.
  • A generated union accepts only fields from one request variant.
  • An SDK’s automatic retry policy is not masking the first response.
The old unversioned Go SDK v1.5.0 and the PHP SDK v2.14.0 have known Brand request compatibility issues. Check the versions and examples in the SDK guide. Use raw HTTP when your installed client cannot represent the current POST /brand/retrieve request.

Handle partial success

A 200 can still contain:
  • Missing optional Brand fields.
  • An empty Markdown result because an include selector matched nothing.
  • Page-level crawl failures inside an otherwise successful crawl response.
  • Skipped or blocked pages in structured extraction metadata.
  • Low-confidence classification candidates.
Validate the product outcome, not only the status code. Preserve the user’s input and render a stable fallback when optional enrichment is absent.

Contact support

If the problem persists, contact [email protected] with:
  • Operation path and HTTP method.
  • UTC timestamp and region.
  • Status, error_code, response headers, and response body.
  • A redacted request body or query.
  • SDK language and exact package version, if applicable.
  • Whether the equivalent cURL request succeeded.
Remove API keys, private page content, cookies, authorization headers, and personal data before sending the report.

Next steps

Rate limits

Read limit headers and recover from 429 responses.

Production checklist

Add retries, fallback states, and request observability.

API stability

Separate API contract changes from SDK compatibility issues.