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

# Error reference

> Every `code` the v2 API returns, what it means, and what to do about it.

Every error carries a stable `code`. **Branch on the code, not the HTTP status and not the
message** — the status is shared across unrelated failures and the message is prose we may
reword. Where a finite set of legal values exists, the body carries it in
`details.accepted_values`, so a 400 is usually enough to fix the call without reading anything.

## Authentication

The request never reached a handler. Check the key, not the query.

| Code               | HTTP | What happened                                                | What to do                                                             |
| ------------------ | ---- | ------------------------------------------------------------ | ---------------------------------------------------------------------- |
| `MISSING_API_KEY`  | 401  | No `Authorization` header was sent.                          | Send `Authorization: Bearer gdelt_sk_…`.                               |
| `INVALID_API_KEY`  | 401  | The key is not recognised.                                   | Check for a truncated paste; create a new key if unsure.               |
| `INVALID_TOKEN`    | 401  | The bearer token is malformed or expired.                    | Re-issue the token.                                                    |
| `API_KEY_DISABLED` | 403  | The key was disabled — usually by the automated abuse sweep. | Check the owner mailbox for the notice, then create a replacement key. |
| `ADMIN_REQUIRED`   | 403  | An admin-only preview surface.                               | Not available on customer keys.                                        |

## Entitlement

The endpoint exists and your key is valid, but this workspace does not carry the flag it needs. Always an explicit error — never an empty result, which would be indistinguishable from "we have no data for you".

| Code                           | HTTP | What happened                                                                                 | What to do                                                                            |
| ------------------------------ | ---- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `PLAN_REQUIRED`                | 403  | The endpoint is behind an entitlement this workspace does not carry. The body names the flag. | Read `details.required_flag`; that flag is what has to be enabled for this workspace. |
| `BRIEF_ACCESS_DENIED`          | 403  | Briefs are not enabled for this workspace.                                                    | Requires `can_use_briefs`.                                                            |
| `DETAILED_BRIEF_NOT_AVAILABLE` | 403  | The requested brief depth is not enabled.                                                     | Request a shallower `depth`, or enable `can_use_detailed_briefs`.                     |
| `PAYMENT_OVERDUE`              | 402  | The workspace is past due and reads are paused.                                               | Settle the balance; access resumes without a new key.                                 |

## Validation

A parameter was rejected rather than silently ignored. A filter that looks accepted and does nothing produces a confident, wrong answer, so the API fails loudly instead. The body carries `details.accepted_values` wherever a finite set exists.

| Code                               | HTTP | What happened                                                                                                                                                                                                                                                                                                                                                                                 | What to do                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `UNKNOWN_PARAM`                    | 400  | A strict descriptor-backed endpoint received a query parameter it does not declare.                                                                                                                                                                                                                                                                                                           | Read `details.param`, `details.did_you_mean` and `details.accepted_params`; correct or remove the parameter.                                                                                                                                                                                                                                                                           |
| `UNSUPPORTED_FILTER`               | 400  | A parameter this endpoint deliberately does not support. Rejected rather than ignored.                                                                                                                                                                                                                                                                                                        | Read `details.alternatives` — the reference lists a replacement for every rejected parameter.                                                                                                                                                                                                                                                                                          |
| `INVALID_CURSOR`                   | 400  | The pagination cursor could not be read. Cursors are opaque — construct them only by copying `pagination.next_cursor`.                                                                                                                                                                                                                                                                        | Restart the walk from the first page and follow `pagination.next_cursor`.                                                                                                                                                                                                                                                                                                              |
| `CURSOR_STALE`                     | 400  | The cursor is valid but no longer describes this result set: it was issued against a pre-built daily snapshot, and this request is either being answered live or against a snapshot that has since been rebuilt. Continuing would repeat some rows and skip others, so the request is refused rather than answered plausibly. `details.reason` is `row_source_changed` or `snapshot_rebuilt`. | Restart the walk from the first page. A walk that must not be interrupted can pin itself to the live path by including a filter only the live path answers, such as `sort=recent`.                                                                                                                                                                                                     |
| `UNSUPPORTED_PARAM`                | 400  | A parameter that is not part of this endpoint at all.                                                                                                                                                                                                                                                                                                                                         | Check the parameter reference for the endpoint you are calling.                                                                                                                                                                                                                                                                                                                        |
| `INVALID_DATE`                     | 400  | A date is not `YYYY-MM-DD`.                                                                                                                                                                                                                                                                                                                                                                   | Use ISO dates. Times are not accepted on date parameters.                                                                                                                                                                                                                                                                                                                              |
| `INVALID_DATE_RANGE`               | 400  | `date_start` is after `date_end`.                                                                                                                                                                                                                                                                                                                                                             | Swap them.                                                                                                                                                                                                                                                                                                                                                                             |
| `DATE_WINDOW_TOO_LARGE`            | 400  | The window exceeds this endpoint's maximum span.                                                                                                                                                                                                                                                                                                                                              | Narrow the window and page through it. Unbounded scans are refused, not served slowly.                                                                                                                                                                                                                                                                                                 |
| `DATE_RANGE_REQUIRED`              | 400  | This endpoint will not run unbounded.                                                                                                                                                                                                                                                                                                                                                         | Pass `days` or an explicit `date_start`/`date_end`.                                                                                                                                                                                                                                                                                                                                    |
| `INVALID_LIMIT`                    | 400  | `limit` is outside the accepted range.                                                                                                                                                                                                                                                                                                                                                        | Use the documented maximum and paginate with `cursor`.                                                                                                                                                                                                                                                                                                                                 |
| `INVALID_BBOX`                     | 400  | A bounding box is malformed or inverted.                                                                                                                                                                                                                                                                                                                                                      | The axis order differs by family, and a swapped box usually returns an empty or wrong 200 rather than this error. Events, stories, facilities and energy take **latitude first** — `lat_min,lon_min,lat_max,lon_max`. Maritime takes **longitude first** — `min_lon,min_lat,max_lon,max_lat`. The per-parameter description in the spec is authoritative for the path you are calling. |
| `INVALID_NEAR`                     | 400  | The `near` grammar does not match this endpoint's.                                                                                                                                                                                                                                                                                                                                            | Events and stories take `lat,lon` with a separate `radius_km`; facilities and energy take a single `lat,lon,radius_km` triple. The spec carries the right example per path.                                                                                                                                                                                                            |
| `INVALID_ENTITY_ID`                | 400  | A bare name was sent where a resolved id is required.                                                                                                                                                                                                                                                                                                                                         | Resolve it first with `GET /api/v2/search`, then pass the `e_…` id.                                                                                                                                                                                                                                                                                                                    |
| `AMBIGUOUS_LEGACY_ID`              | 409  | A legacy facility-unit id maps to more than one canonical physical site.                                                                                                                                                                                                                                                                                                                      | Use a canonical `s_…` site id returned by `GET /api/v2/facilities`; candidate ids are in `details.canonical_site_ids`.                                                                                                                                                                                                                                                                 |
| `ENTITY_REQUIRED`                  | 400  | This endpoint is per-entity and no entity was named.                                                                                                                                                                                                                                                                                                                                          | Pass `entity`.                                                                                                                                                                                                                                                                                                                                                                         |
| `FILTER_REQUIRED`                  | 400  | This endpoint needs at least one narrowing filter.                                                                                                                                                                                                                                                                                                                                            | Add a geography, taxonomy or entity filter.                                                                                                                                                                                                                                                                                                                                            |
| `INVALID_LIST_SOURCE`              | 400  | An unknown screening list, or one we declare but do not yet carry.                                                                                                                                                                                                                                                                                                                            | Branch on `details.reason`: `unknown_source_key` vs `declared_but_not_ingested`. Never an empty success — on a sanctions surface that would read as a clean result.                                                                                                                                                                                                                    |
| `EVENT_FAMILY_CATEGORY_CONFLICT`   | 400  | A deprecated `event_family` contradicts the `category` sent with it.                                                                                                                                                                                                                                                                                                                          | Drop `event_family`; `category` implies the family.                                                                                                                                                                                                                                                                                                                                    |
| `SUBCATEGORY_REQUIRES_CATEGORY`    | 400  | `subcategory` was sent with no `category`. Sub-event types are scoped by category and several labels are ambiguous without one.                                                                                                                                                                                                                                                               | Send `category` too. `details.accepted_categories` lists the categories that have subcategories.                                                                                                                                                                                                                                                                                       |
| `INVALID_SUBCATEGORY_FOR_CATEGORY` | 400  | The `subcategory` is a real taxonomy code but not one that belongs to the `category` sent with it.                                                                                                                                                                                                                                                                                            | Read `details.accepted_values` — it is the subcategory list for the category you actually asked for.                                                                                                                                                                                                                                                                                   |
| `STORY_CATEGORY_CONFLICT`          | 400  | `story_category` and the deprecated `category` spelling of it were both sent, naming different values.                                                                                                                                                                                                                                                                                        | Send one. `story_category` is the current spelling.                                                                                                                                                                                                                                                                                                                                    |
| `INVALID_NUMBER_RANGE`             | 400  | A metric `_min` is greater than its `_max`, so the range is empty. Refused rather than served as a (correct but useless) empty result.                                                                                                                                                                                                                                                        | Read `details.min_value` / `details.max_value` and swap them.                                                                                                                                                                                                                                                                                                                          |
| `EVENT_FAMILY_METRIC_CONFLICT`     | 400  | A metric only one event family publishes (magnitude, systemic\_importance, propagation\_potential, market\_sensitivity — all CAMEO+) was combined with a taxonomy filter that commits the request to the other family. Unsatisfiable by construction: the conflict detail table has no such column.                                                                                           | Read `details.metric_family` and `details.implied_family` — they disagree. Drop the metric filter, move the taxonomy filter into `details.metric_family`, or use a metric both families publish (`details.accepted_metrics_for_family`).                                                                                                                                               |

## Data availability

The request is valid, but the evidence required to answer it under the requested semantics is not available. Never interpret this as an empty result or as evidence that nothing happened.

| Code                             | HTTP | What happened                                                                                                                    | What to do                                                                                                                                      |
| -------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `ENTITY_ATTRIBUTION_UNAVAILABLE` | 503  | Material entity attribution is unavailable for the requested window, so the API refuses to substitute broad story co-occurrence. | Retry later or use a window with ready attribution. Send `entity_match=coverage` only if broad co-occurrence is the question you intend to ask. |

## Not found and withdrawn

The id is well-formed but resolves to nothing, or to something that has since been superseded. A withdrawn or merged record returns a pointer to its replacement rather than a bare 404.

| Code                  | HTTP | What happened                                                                                                                                                 | What to do                                                                                                                                          |
| --------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NOT_FOUND`           | 404  | No record with that id.                                                                                                                                       | Ids are opaque — do not construct them. Re-fetch from a list endpoint.                                                                              |
| `NOT_FOUND_IN_WINDOW` | 404  | The id resolves to nothing INSIDE the date window the request asked for. It may exist outside it.                                                             | Drop start\_date/end\_date — a by-id read defaults to the record's own date — or widen the window.                                                  |
| `ENDPOINT_REMOVED`    | 410  | A retired endpoint. It existed, it is intentionally gone, and it will not return.                                                                             | Read `details.replacement` — it names the /api/v2 path that answers the same question. The `Link: rel="successor-version"` header carries it too.   |
| `ENTITY_NOT_FOUND`    | 404  | The entity id does not resolve.                                                                                                                               | It may have merged; re-resolve the name through `GET /api/v2/search`.                                                                               |
| `STORY_MERGED`        | 404  | The story was adjudicated a duplicate and folded into another.                                                                                                | Follow the replacement id in the body. This is not an error to retry.                                                                               |
| `EVENT_WITHDRAWN`     | 404  | The event stopped resolving and no single replacement could be determined — it was suppressed in review, or merged in a way that names no one live successor. | Read the reason in the body; do not treat the prior record as still true. Re-query GET /api/v2/events for the current event covering this incident. |
| `EVENT_MERGED`        | 404  | The event was adjudicated a duplicate and folded into another event, which is live.                                                                           | Follow `successor_event_id` in the body. This is not an error to retry.                                                                             |

## Limits

The request was well-formed and refused on volume or account state.

| Code             | HTTP | What happened                                     | What to do                                                                   |
| ---------------- | ---- | ------------------------------------------------- | ---------------------------------------------------------------------------- |
| `RATE_LIMITED`   | 429  | Too many requests per minute.                     | Back off and retry. Concurrency, not volume, is usually the cause.           |
| `QUOTA_EXCEEDED` | 429  | The Query Unit allowance for the period is spent. | Wait for the period to roll over, or raise the allowance for this workspace. |

## Server

Our fault. Safe to retry with backoff.

| Code                          | HTTP | What happened                                                                                                                                                                                | What to do                                                                                                     |
| ----------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `INTERNAL_ERROR`              | 500  | An unhandled failure.                                                                                                                                                                        | Retry with backoff. If it persists, send us the request id from the response.                                  |
| `PLAN_FEATURES_ERROR`         | 500  | Entitlements could not be resolved for this workspace.                                                                                                                                       | Transient — retry. Not a statement about what your workspace carries.                                          |
| `ORG_RESOLUTION_ERROR`        | 500  | The workspace behind the key could not be resolved.                                                                                                                                          | Transient — retry.                                                                                             |
| `SEMANTIC_SEARCH_UNAVAILABLE` | 503  | The embedding call behind `search=` failed or timed out, so the query could not be embedded. Nothing is served in its place — a lexical fallback would silently answer a different question. | Retry shortly. To proceed without it, drop `search` and narrow with `category`, `country` or `entity` instead. |

## Rejected values, by vocabulary

A closed vocabulary rejects anything outside its list. Most return `INVALID_ENUM`; a few carry
their own code so a caller can branch without inspecting `details`. Derived from the same
vocabulary registry the server validates against.

| Code                  | Vocabularies                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_CATEGORY`    | [`event_category`](/reference/enums#event_category)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `INVALID_CONTINENT`   | [`continent`](/reference/enums#continent)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `INVALID_ENUM`        | [`actor_role`](/reference/enums#actor_role), [`actor_type`](/reference/enums#actor_type), [`atlas_coverage_tier`](/reference/enums#atlas_coverage_tier), [`atlas_gpr_component`](/reference/enums#atlas_gpr_component), [`atlas_gpr_construction`](/reference/enums#atlas_gpr_construction), [`atlas_gpr_metric`](/reference/enums#atlas_gpr_metric), [`atlas_gpr_variant`](/reference/enums#atlas_gpr_variant), [`atlas_level`](/reference/enums#atlas_level), [`atlas_posture_scope`](/reference/enums#atlas_posture_scope), [`atlas_posture_window`](/reference/enums#atlas_posture_window), [`atlas_weighting`](/reference/enums#atlas_weighting), [`brief_audience`](/reference/enums#brief_audience) and 55 more |
| `INVALID_LIST_SOURCE` | [`exposure_list`](/reference/enums#exposure_list), [`list_source_key`](/reference/enums#list_source_key)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `INVALID_REGION`      | [`region`](/reference/enums#region)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `INVALID_TRACKER`     | [`gem_tracker`](/reference/enums#gem_tracker)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `UNSUPPORTED_FILTER`  | [`gem_heavy_industry_tracker`](/reference/enums#gem_heavy_industry_tracker)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

<Info>
  An **observed** vocabulary never rejects on membership — it is a dated measurement, not an
  allowlist, and the API accepts values outside it. Only closed vocabularies appear above.
</Info>
