> ## Documentation Index
> Fetch the complete documentation index at: https://technologychecker.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> API error codes (400, 401, 403, 404, 429, 500), JSON error format, example responses, and a step-by-step guide for handling and retrying failed requests.

All API errors return a consistent JSON format:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error description"
  }
}
```

## Error codes

| Status | Code               | Description                                                         |
| ------ | ------------------ | ------------------------------------------------------------------- |
| 400    | `VALIDATION_ERROR` | Invalid request parameters                                          |
| 401    | `UNAUTHORIZED`     | Missing or invalid API key                                          |
| 403    | `FORBIDDEN`        | Insufficient permissions for this endpoint                          |
| 404    | `NOT_FOUND`        | Resource not found (domain, technology, etc.)                       |
| 409    | `CONFLICT`         | Resource already exists                                             |
| 429    | `RATE_LIMIT`       | Rate limit exceeded — see [rate limits](/docs/api-reference/rate-limits) |
| 500    | `INTERNAL_ERROR`   | Server error — retry after a brief delay                            |

## Examples

<Tabs>
  <Tab title="401 Unauthorized">
    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "UNAUTHORIZED",
        "message": "Missing or invalid API key"
      }
    }
    ```

    **Fix:** Check that your `Authorization` header includes a valid `Bearer` token. See [how to get your API key](/docs/api-reference/authentication#how-to-get-your-api-key).
  </Tab>

  <Tab title="404 Not found">
    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "NOT_FOUND",
        "message": "No data found for domain unknown-site.xyz"
      }
    }
    ```

    **Fix:** The domain might not be in the database yet. Try [live detection](/docs/api-reference/introduction#live-detection) for real-time scanning.
  </Tab>

  <Tab title="429 Rate limited">
    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "RATE_LIMIT",
        "message": "Rate limit exceeded. Retry after 12 seconds."
      }
    }
    ```

    **Fix:** Wait for the `Retry-After` header value, then retry. See [retry strategy](/docs/api-reference/rate-limits#retry-strategy) for backoff code examples.
  </Tab>

  <Tab title="400 Validation">
    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Parameter 'domain' is required"
      }
    }
    ```

    **Fix:** Check the endpoint's required parameters in the API reference.
  </Tab>
</Tabs>

## How to handle errors

<Steps>
  <Step title="Check the status code">
    Use the HTTP status code for control flow. `2xx` means success, `4xx` means client error, `5xx` means server error.
  </Step>

  <Step title="Read the error code">
    The `error.code` field provides a machine-readable error type you can switch on in your code.
  </Step>

  <Step title="Retry when appropriate">
    Retry on `429` (after `Retry-After` seconds) and `500` (with exponential backoff). Do not retry `400`, `401`, `403`, or `404`.
  </Step>
</Steps>

<Tip>
  Always check `success: false` in the response body in addition to HTTP status codes. This gives you both the error code and a human-readable message for logging.
</Tip>

## Related pages

<CardGroup cols={2}>
  <Card title="Rate limits" icon="gauge-high" href="/docs/api-reference/rate-limits">
    Request limits and retry strategies for 429 errors.
  </Card>

  <Card title="Authentication" icon="lock" href="/docs/api-reference/authentication">
    Fix 401 errors with proper API key setup.
  </Card>

  <Card title="Credits" icon="coins" href="/docs/api-reference/credits">
    Avoid credit exhaustion errors with usage monitoring.
  </Card>

  <Card title="Live detection" icon="bolt" href="/docs/api-reference/introduction#live-detection">
    Resolve 404 errors with real-time scanning.
  </Card>
</CardGroup>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Which errors should I retry?">
    Retry `429` (rate limit) after waiting the `Retry-After` header value, and `500` (server error) with exponential backoff. Do not retry `400` (validation), `401` (auth), `403` (permissions), or `404` (not found) — these require fixing the request itself.
  </Accordion>

  <Accordion title="Why am I getting 404 for a domain lookup?">
    The domain might not be in the pre-crawled database yet. Try the [live detection endpoint](/docs/api-reference/introduction#live-detection) (`POST /v1/technology-lookup-live`) for real-time scanning. Live detection costs 5 credits.
  </Accordion>

  <Accordion title="What does FORBIDDEN (403) mean if my API key is valid?">
    A `403` response means your API key is valid but doesn't have permission for the requested endpoint. This typically happens when your plan doesn't include access to a specific feature, or your account has been restricted. Check your plan's included endpoints in [credits](/docs/api-reference/credits) and contact support if the issue persists.
  </Accordion>

  <Accordion title="How do I debug VALIDATION_ERROR responses?">
    A `400 VALIDATION_ERROR` means your request parameters are malformed or missing. Read the `error.message` field — it tells you exactly which parameter is wrong (e.g., "Parameter 'domain' is required"). Double-check required parameters, data types, and value formats against the endpoint's documentation in the [API reference](/docs/api-reference/introduction).
  </Accordion>

  <Accordion title="Does the API use the same error format for all endpoints?">
    Yes. Every error response follows the same JSON structure: `{"success": false, "error": {"code": "ERROR_CODE", "message": "..."}}`. The `code` field is a machine-readable string you can use in your error handling logic, and `message` is a human-readable description. This applies across all `/v1/*` endpoints.
  </Accordion>
</AccordionGroup>
