> ## 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.

# API v1 Reference

> Legacy Developer API for existing integrations

<Warning>
  **Use API v2 for new integrations.** v2 is the recommended interface for clean generated GDELT Cloud Events, clustered Stories, Entities, normalized geography, canonical significance ranking, top-3 inline articles, and cursor pagination. See [API v2](/api-reference/v2).

  API v1 remains supported for existing direct API users and integrations.
</Warning>

## Overview

The GDELT Cloud v1 Developer API (`/api/v1/*`) provides backward-compatible programmatic access to earlier GDELT Cloud surfaces: media-event clusters, GEG entity profiles, news-domain profiles, Conflict events, and CAMEO+ events.

For new dashboards, monitoring workflows, agents, and analyst applications, prefer `/api/v2/*`.

V2 Event, Story, and Entity list endpoints default to the exact past 24 hours. Narrow with geography, category, subcategory, date windows up to 30 days, and semantic search rather than public confidence modes.

<CardGroup cols={3}>
  <Card title="API v2" icon="sparkles" href="/api-reference/v2">
    Recommended clean Events, Stories, Entities, geo discovery, summaries, and cursor pagination
  </Card>

  <Card title="Media Events" icon="newspaper">
    Legacy story clusters from articles, filterable by category, actor country, location, and event type
  </Card>

  <Card title="Entities" icon="star">
    Wikipedia-linked GEG entity profiles with sentiment, linked stories, and relationship graph
  </Card>

  <Card title="Domains" icon="globe">
    News domain profiles — stats, top persons/orgs, recent articles
  </Card>
</CardGroup>

## Authentication

All Developer API requests require an API key in the `Authorization` header:

```http theme={null}
Authorization: Bearer gdelt_sk_your_api_key_here
```

API keys use the format `gdelt_sk_<64-hex-chars>`. Generate yours in **Dashboard → Settings → API Keys**.

<Info>
  API keys require API access on your GDELT Cloud account.
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://gdeltcloud.com/api/v1/media-events?days=1&limit=5&detail=summary" \
    -H "Authorization: Bearer gdelt_sk_your_api_key_here"
  ```

  ```python Python theme={null}
  import requests, os

  resp = requests.get(
      "https://gdeltcloud.com/api/v1/media-events",
      headers={"Authorization": f"Bearer {os.environ['GDELT_API_KEY']}"},
      params={"days": 1, "limit": 5, "detail": "summary"}
  )
  data = resp.json()
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch(
    "https://gdeltcloud.com/api/v1/media-events?days=1&limit=5&detail=summary",
    { headers: { "Authorization": `Bearer ${process.env.GDELT_API_KEY}` } }
  );
  const data = await resp.json();
  ```
</CodeGroup>

<Tip>
  The equivalent v2 starting point is:

  ```bash theme={null}
  curl "https://gdeltcloud.com/api/v2/stories?date_start=2026-04-11&date_end=2026-04-17&limit=5&sort=significance" \
    -H "Authorization: Bearer gdelt_sk_your_api_key_here"
  ```
</Tip>

## Confidence Strictness Spectrum

Several GDELT Cloud product surfaces now use the same plain-language confidence spectrum:

* **High confidence** → `strict`
* **Balanced** → `balanced`
* **Broad** → `broad`

For alerting, this appears as `spec_json.filters.precision_mode`.

Plain-language meaning:

| Label               | API Value  | Meaning                                                   |
| ------------------- | ---------- | --------------------------------------------------------- |
| **High confidence** | `strict`   | Only primary clusters with strong story-family confidence |
| **Balanced**        | `balanced` | Primary clusters only                                     |
| **Broad**           | `broad`    | Include weaker/supporting cluster families too            |

This is a quality gate, not a separate family filter. It combines with the rest of your filters using logical `AND`.

It is now exposed directly on the main event-discovery APIs as the `precision` query parameter:

* `/api/v1/media-events`
* `/api/v1/conflict-events`
* `/api/v1/cameoplus-events`

## Date & Time Parameters

All v1 endpoints accept a consistent `date` + `days` pattern:

| Param  | Type         | Default   | Description                                                         |
| ------ | ------------ | --------- | ------------------------------------------------------------------- |
| `date` | `YYYY-MM-DD` | today UTC | Anchor/end date of the window. Defaults to today UTC.               |
| `days` | integer      | varies    | Window size in days ending on `date`. **Max 30 for all endpoints.** |

> **Example:** `date=2025-02-20&days=7` returns data from Feb 14-20 (7 days ending on Feb 20).

For `/api/v1/media-events` specifically: `days=1` returns only the single `date` daily bucket; `days=7` returns 7 daily buckets ending on `date`.

## Response Detail Levels

Most endpoints support a `detail` parameter for **progressive disclosure** — control how much data you receive to optimize for your use case.

### `/api/v1/media-events`

| Level      | \~Tokens/Cluster | Best For                                                           |
| ---------- | ---------------- | ------------------------------------------------------------------ |
| `summary`  | \~120            | Scanning headlines, MCP agent discovery, dashboards                |
| `standard` | \~500            | Article links + actor/location details, intermediate analysis      |
| `full`     | \~1,000          | Complete data with per-article metrics, full integration (default) |

```http theme={null}
# Compact summary cards for quick scanning
GET /api/v1/media-events?days=1&limit=10&detail=summary

# Standard detail with article links
GET /api/v1/media-events?days=7&limit=5&detail=standard

# Full data (default, backward-compatible)
GET /api/v1/media-events?days=1&limit=10&detail=full
```

**`summary`** returns compact headline cards: cluster\_id, label, category, scope, time\_bucket, article\_count, avg\_goldstein, avg\_tone, quad\_class, event\_description, location, top 5 entity names, top 5 source domains, and languages.

**`standard`** adds trimmed representative articles (URL, title, domain, date, weight), resolved actor/event/location details, and top 10 linked entities.

**`full`** (default) returns the complete unmodified response including per-article metrics, all linked entities, and lat/long coordinates.

#### Summary Response Shape

```json theme={null}
{
  "clusters": [
    {
      "cluster_id": "abc123",
      "cluster_label": "French workers stage nationwide strikes",
      "category": "politics_governance",
      "scope": "national",
      "time_bucket": "2025-02-20T00:00:00Z",
      "article_count": 47,
      "avg_goldstein": -5.0,
      "avg_tone": -3.2,
      "quad_class": 3,
      "event_description": "Protest",
      "location": "France",
      "top_entities": ["Emmanuel Macron", "CGT", "Marine Le Pen"],
      "top_sources": ["reuters.com", "bbc.com", "lemonde.fr"],
      "languages": ["English", "French"]
    }
  ],
  "metadata": { "cluster_count": 10, "execution_time_ms": 120 }
}
```

#### Standard Response Shape

```json theme={null}
{
  "clusters": [
    {
      "cluster_id": "abc123",
      "cluster_label": "French workers stage nationwide strikes",
      "category": "politics_governance",
      "scope": "national",
      "article_count": 47,
      "resolved_metrics": {
        "primary_actor1": { "name": "France", "country_code": "FRA" },
        "primary_event": { "code": "14", "description": "Protest" },
        "primary_location": { "country_name": "France", "adm1_name": "Ile-de-France" },
        "avg_goldstein": -5.0,
        "avg_tone": -3.2
      },
      "representative_articles": [
        {
          "source_url": "https://reuters.com/...",
          "page_title": "French workers walk out in nationwide strike",
          "domain": "reuters.com",
          "article_date": "2025-02-20",
          "article_weight": 0.72
        }
      ],
      "linked_entities": [
        { "name": "Emmanuel Macron", "type": "person" },
        { "name": "CGT", "type": "organization" }
      ]
    }
  ]
}
```

<Tip>
  **For MCP agents:** Start with `detail=summary` to discover what's happening, then use the cluster endpoint to deep-dive into specific stories.
</Tip>

### `/api/v1/media-events/cluster`

| Level      | \~Tokens | Description                                                                                 |
| ---------- | -------- | ------------------------------------------------------------------------------------------- |
| `summary`  | \~500    | Voting articles (URL, title, domain, date, geo) + top 10 common entities + resolved metrics |
| `standard` | \~1,500  | Adds event metrics/actors, top 5 entities per voting article, paginated additional articles |
| `full`     | \~3,000+ | All entities per voting article, top 10 per paginated article, quad\_classes                |

#### Summary Response Shape

```json theme={null}
{
  "success": true,
  "cluster": {
    "cluster_id": "abc123",
    "cluster_label": "UN Security Council convenes for urgent meeting",
    "category": "conflict_security",
    "scope": "global",
    "article_count": 81
  },
  "resolved_metrics": {
    "avg_goldstein": -2.7,
    "avg_tone": -3.4,
    "primary_quad_class": 3,
    "primary_event": { "description": "Use conventional military force" },
    "primary_location": { "country_name": "Iran", "adm1_name": "Tehran" }
  },
  "voting_articles": [
    {
      "source_url": "https://...",
      "page_title": "UN Security Council holds emergency session",
      "domain": "cnn.com",
      "article_weight": 0.72,
      "article_date": "2025-02-27",
      "geo_country_name": "Iran"
    }
  ],
  "common_entities": [
    { "name": "Iran", "type": "organization", "wikipedia_url": "https://..." }
  ],
  "metadata": {
    "total_count": 81,
    "voting_article_count": 5,
    "common_entity_count": 10
  }
}
```

#### Standard Response Shape

```json theme={null}
{
  "success": true,
  "cluster": { "cluster_id": "abc123", "article_count": 81 },
  "resolved_metrics": { "..." : "same as summary + actor details" },
  "voting_articles": [
    {
      "source_url": "https://...",
      "page_title": "...",
      "domain": "cnn.com",
      "article_date": "2025-02-27",
      "article_weight": 0.72,
      "geo_country_name": "Iran",
      "linked_entities": [
        { "name": "Iran", "type": "organization" },
        { "name": "United Nations", "type": "organization" }
      ]
    }
  ],
  "articles": [
    {
      "source_url": "https://...",
      "page_title": "...",
      "domain": "bbc.com",
      "article_date": "2025-02-27"
    }
  ],
  "common_entities": [ "..." ],
  "metadata": {
    "total_count": 81,
    "voting_article_count": 5,
    "page_count": 10,
    "additional_total": 76,
    "has_more": true
  }
}
```

### `/api/v1/entity-geg`

| Level      | \~Tokens | Description                                                                  |
| ---------- | -------- | ---------------------------------------------------------------------------- |
| `summary`  | \~300    | Entity basics + 3 story ref cards + 10 co-occurrence ref cards. No timeline. |
| `standard` | \~1,200  | Full entity master + 20 story refs + 25 co-occ refs + timeline               |
| `full`     | \~1,500  | Full entity master + paginated story refs + 50 co-occ refs + timeline        |

## Cluster Deep-Dive (`/api/v1/media-events/cluster`)

After discovering stories with `/api/v1/media-events`, drill into a specific cluster to see all articles, key entities, and apply filters.

### Parameters

| Param           | Type         | Default      | Description                                                   |
| --------------- | ------------ | ------------ | ------------------------------------------------------------- |
| `cluster_id`    | string       | **required** | Cluster ID from a `media-events` response                     |
| `date`          | `YYYY-MM-DD` | today UTC    | Same date used in the discovery call                          |
| `days`          | integer      | `1`          | Same window used in the discovery call (max 30)               |
| `detail`        | string       | `summary`    | `summary`, `standard`, or `full`                              |
| `actor_country` | string       | —            | ISO-3 code to filter by actor nationality (e.g. `CHN`, `USA`) |
| `location`      | string       | —            | FIPS 2-letter to filter by event location (e.g. `IR`, `US`)   |
| `language`      | string       | —            | ISO 639-1 to filter by article language (e.g. `en`, `fr`)     |
| `domain`        | string       | —            | Filter to a specific source domain                            |
| `category`      | string       | —            | Filter by topic category                                      |
| `limit`         | integer      | `10`         | Additional articles (standard/full only, max 50)              |
| `offset`        | integer      | `0`          | Pagination for additional articles                            |

### Filters

Use filters to explore specific angles of a story:

```http theme={null}
# How is China involved in this story?
GET /api/v1/media-events/cluster?cluster_id=abc123&actor_country=CHN

# French-language coverage only
GET /api/v1/media-events/cluster?cluster_id=abc123&language=fr

# Only Reuters articles
GET /api/v1/media-events/cluster?cluster_id=abc123&domain=reuters.com
```

When filters are applied, the response includes `filtered_count` showing how many articles match.

<Tip>
  **Always pass `date` and `days`** matching the `media-events` discovery call to ensure efficient partition-scoped queries.
</Tip>

## Semantic Search (`/api/v1/media-events`)

The `search` parameter enables natural-language semantic search across media event clusters. When provided, clusters are ranked by **embedding similarity** (cosine distance) instead of article count.

```http theme={null}
# Find stories about AI regulation
GET /api/v1/media-events?search=AI+regulation+European+Union&detail=summary

# Semantic search + category filter
GET /api/v1/media-events?search=trade+war+tariffs&category=economy_business&detail=summary

# Semantic search + actor country + location
GET /api/v1/media-events?search=nuclear+negotiations&actor_country=IRN&location=US&detail=summary

# Semantic search over a week
GET /api/v1/media-events?search=climate+change+protests&days=7&detail=summary
```

### How it works

1. Your query text is converted server-side into a semantic representation
2. Matching records are scored against pre-computed article representations
3. Results are grouped by cluster and ranked by semantic similarity

### Combining with filters

All filters work with `search` — they combine as **AND** (each filter narrows results):

| Filter                                            | Works with `search`? | How it's applied                                                 |
| ------------------------------------------------- | -------------------- | ---------------------------------------------------------------- |
| `date` / `days`                                   | ✅                    | Time window constraint                                           |
| `category`                                        | ✅                    | Cluster-level pre-filter                                         |
| `scope`                                           | ✅                    | Cluster-level pre-filter                                         |
| `actor_country`                                   | ✅                    | Event-level pre-filter (restricts article candidates before ANN) |
| `event_type`                                      | ✅                    | Event-level pre-filter                                           |
| `location`                                        | ✅                    | Event-level pre-filter                                           |
| `language`                                        | ✅                    | Language pre-filter                                              |
| `domain`                                          | ✅                    | Domain pre-filter                                                |
| `goldstein_min/max`, `tone_min/max`, `quad_class` | ✅                    | Post-resolution filter                                           |

<Tip>
  Semantic search is best for **conceptual queries** — topics, themes, or ideas described in natural language. Use structured filters for precise criteria like specific countries, event types, or date ranges. Combine both for the most targeted results.
</Tip>

## Pagination (`/api/v1/media-events`)

`/api/v1/media-events` supports numeric offset pagination via the `offset` parameter:

| Param    | Type    | Default | Description                 |
| -------- | ------- | ------- | --------------------------- |
| `offset` | integer | `0`     | Number of clusters to skip. |

```http theme={null}
# Page 1 (first 10)
GET /api/v1/media-events?days=1&limit=10&offset=0

# Page 2 (next 10)
GET /api/v1/media-events?days=1&limit=10&offset=10

# Page 3
GET /api/v1/media-events?days=1&limit=10&offset=20
```

If the response returns fewer clusters than `limit`, you have reached the last page.

## Error Codes

| Code                  | HTTP | Meaning                                                       |
| --------------------- | ---- | ------------------------------------------------------------- |
| `MISSING_API_KEY`     | 401  | No `Authorization` header                                     |
| `INVALID_API_KEY`     | 401  | Wrong format or revoked key                                   |
| `API_ACCESS_DENIED`   | 403  | Plan does not include API access                              |
| `RATE_LIMITED`        | 429  | Per-minute RPM limit exceeded. Includes `Retry-After` header. |
| `QUOTA_EXCEEDED`      | 429  | Monthly QU limit reached                                      |
| `PLAN_FEATURES_ERROR` | 500  | Could not load plan features                                  |

```python theme={null}
resp = requests.get(url, headers=headers)

if resp.status_code == 200:
    data = resp.json()
elif resp.status_code == 429:
    retry_after = int(resp.headers.get("Retry-After", 60))
    print(f"Rate limited — retry in {retry_after}s")
elif resp.status_code == 401:
    print("Invalid API key")
elif resp.status_code == 403:
    print("Plan does not include API access")
```

## Reference Codes

### Categories (`category` param)

| Value                 | Label    |
| --------------------- | -------- |
| `conflict_security`   | Conflict |
| `politics_governance` | Politics |
| `crime_justice`       | Crime    |
| `economy_business`    | Economy  |
| `science_health`      | Health   |
| `disaster_emergency`  | Disaster |
| `society_culture`     | Society  |
| `technology`          | Tech     |

### Scope (`scope` param)

| Value      | Description                                         |
| ---------- | --------------------------------------------------- |
| `local`    | Event affects a single city/region                  |
| `national` | Event affects a single country                      |
| `global`   | Event involves 2+ countries or international bodies |

### CAMEO Country Codes (`actor_country` param)

3-letter ISO codes: `USA`, `GBR`, `CHN`, `RUS`, `DEU`, `FRA`, `ISR`, `IRN`, `SAU`, `IND`

### Event Codes (`event_type` param)

Pass the root code prefix: `14`=Protest, `18`=Assault, `19`=Fight, `13`=Threaten, `11`=Disapprove.
See the full [CAMEO event code table](https://gdeltproject.org/data/documentation/CAMEO.Manual.1.1b3.pdf) for all codes.

### Article Weight

Measures uniqueness of a news article:

```
article_weight = 1 / log₂(event_count + 1)
```

| event\_count | article\_weight | Interpretation             |
| ------------ | --------------- | -------------------------- |
| 1            | 1.000           | Unique — highest quality   |
| 3            | 0.500           | Moderate redundancy        |
| 10           | 0.289           | Appears across many events |

Cluster articles are sorted by `article_weight DESC`.
