<!-- Wikimedia Enterprise docs. Canonical page: https://enterprise.wikimedia.com/docs/realtime/ -->

# Realtime API

Receive real-time event updates from all [supported Wikimedia projects](https://enterprise.wikimedia.com/project-data/) using the streaming (firehose) endpoint, or via batch files that are generated hourly with changes throughout the day.

Streaming returns server-sent events (SSE) by default, or NDJSON when you pass the `Accept: application/x-ndjson` header. Batch files return NDJSON in a compressed tarball (.tar.gz).

## At a glance

- **Base URLs:** `https://realtime.enterprise.wikimedia.com` (stream) and `https://api.enterprise.wikimedia.com` (hourly batches)
- **Auth:** JWT Bearer access token ([Authentication](https://enterprise.wikimedia.com/docs/authentication/))
- **Formats:** SSE default; NDJSON via the `Accept: application/x-ndjson` header; batches are .tar.gz
- **Response model:** [RealtimeArticle](https://enterprise.wikimedia.com/docs/api/#models/RealtimeArticle)
- **Access:** paid - [contact sales](https://enterprise.wikimedia.com/contact/)
- **Status:** Realtime Firehose and Batch endpoints are fully released. Wikidata Realtime and Wikidata Batch endpoints are in beta.

## Endpoints

- [`/v2/articles`](https://enterprise.wikimedia.com/docs/api/#tag/realtime-articles/GET/v2/articles) - Stream article changes as they happen (GET, POST)
- [`/v2/wikidata`](https://enterprise.wikimedia.com/docs/api/#tag/realtime-wikidata/GET/v2/wikidata) - Stream Wikidata changes as they happen (beta) (GET, POST)
- [`/v2/batches/{date}/{hour}`](https://enterprise.wikimedia.com/docs/api/#tag/batches/GET/v2/batches/{date}/{hour}) - List all batch files for a given hour and date (GET, POST)
- [`/v2/batches/{date}/{hour}/{identifier}`](https://enterprise.wikimedia.com/docs/api/#tag/batches/GET/v2/batches/{date}/{hour}/{identifier}) - Receive info for one batch file (GET, POST)
- [`/v2/batches/{date}/{hour}/{identifier}/download`](https://enterprise.wikimedia.com/docs/api/#tag/batches/GET/v2/batches/{date}/{hour}/{identifier}/download) - Download one batch file (HEAD, GET)
- [`/v2/batches/{date}/{hour}/wikidata`](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata) - List all Wikidata batch files for a given hour and date (beta) (GET, POST)
- [`/v2/batches/{date}/{hour}/wikidata/{identifier}`](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata/{identifier}) - Receive info for one Wikidata batch file (beta) (GET, POST)
- [`/v2/batches/{date}/{hour}/wikidata/{identifier}/download`](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata/{identifier}/download) - Download one Wikidata batch file (beta) (HEAD, GET)

Batch downloads also answer HEAD requests, so you can inspect a batch's size before downloading it. Wikidata endpoints are currently in beta with no SLA.

## Worked examples

### Streaming the firehose

Connect to [Streaming Article Updates](https://enterprise.wikimedia.com/docs/api/#tag/realtime-articles/GET/v2/articles) with `curl -N` (unbuffered) and a filter so you only receive events from English Wikipedia. This example requests NDJSON with the `Accept: application/x-ndjson` header; SSE is the default when the header is omitted.

The stream is long-lived: you will continue getting data streamed to you until you close the connection yourself. It stays open even past your access token's 24-hour expiry, as long as the token was valid at the moment you opened the connection.

The stream also answers a GET request with the same parameters in the query string: one `filters` parameter per filter, each a JSON object, and one `fields` parameter per field, URL-encoded. The second example sends the same filter that way and asks for two fields; `curl -G --data-urlencode` writes the encoded form, shown in the comment.

```bash
curl -N 'https://realtime.enterprise.wikimedia.com/v2/articles' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/x-ndjson' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  --data '{ "filters": [{ "field": "is_part_of.identifier", "value": "enwiki" }] }'
```

```bash
curl -N -G 'https://realtime.enterprise.wikimedia.com/v2/articles' \
  -H 'Accept: application/x-ndjson' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  --data-urlencode 'filters={"field":"is_part_of.identifier","value":"enwiki"}' \
  --data-urlencode 'fields=name' \
  --data-urlencode 'fields=is_part_of.identifier'
# sends ?filters=%7B%22field%22%3A%22is_part_of.identifier%22%2C%22value%22%3A%22enwiki%22%7D&fields=name&fields=is_part_of.identifier
```

One event, trimmed:

```json
{
  "event": {
    "identifier": "c49d6b93-030e-422b-a904-19fcfd821aca",
    "type": "update",
    "date_created": "2026-04-22T07:24:01.47645Z",
    "date_published": "2026-04-22T07:24:03.546408Z",
    "partition": 15,
    "offset": 3465731
  },
  "name": "MasterChef (American TV series) season 4",
  "identifier": 39462622,
  "date_modified": "2026-04-22T07:23:59Z",
  "in_language": {
    "identifier": "en"
  },
  "is_part_of": {
    "identifier": "enwiki"
  },
  "namespace": {
    "identifier": 0
  },
  "version": {
    "identifier": 1350500106,
    "editor": {
      "name": "Magitroopa"
    },
    "number_of_characters": 49662
  }
}
```

`event.type` says what happened to the article. Use `event.partition` and `event.offset` to resume listening at the right place if the connection drops.

### Retrieving hourly batches

Batch files are generated hourly with the changes made throughout the day. Before downloading a batch, check that it is available with the [Hourly Batch Files Available](https://enterprise.wikimedia.com/docs/api/#tag/batches/GET/v2/batches/{date}/{hour}) endpoint.

This example request lists the batches available for August 26, 2025 at 00:00 UTC; to the right is one item of the listing response. `size` is the batch file's size in decimal megabytes, bytes divided by 1,000,000, to three decimals, and `unit_text` is always `MB` for batches. For the exact byte count, request [Project Updates (Batch) Headers](https://enterprise.wikimedia.com/docs/api/#tag/batches/HEAD/v2/batches/{date}/{hour}/{identifier}/download) and read `Content-Length`.

```bash
curl 'https://api.enterprise.wikimedia.com/v2/batches/2025-08-26/00' \
  -H 'Authorization: Bearer ACCESS_TOKEN'
```

```json
{
  "identifier": "afwiki_namespace_0",
  "version": "5a3358f08767bd7d88b9f7e8b54358fc",
  "date_modified": "2026-04-22T06:04:03.479199084Z",
  "is_part_of": {
    "identifier": "afwiki"
  },
  "in_language": {
    "identifier": "af"
  },
  "namespace": {
    "identifier": 0
  },
  "size": {
    "value": 1.418,
    "unit_text": "MB"
  }
}
```

Fetch the tarball itself from the [Hourly Batch File Download](https://enterprise.wikimedia.com/docs/api/#tag/batches/GET/v2/batches/{date}/{hour}/{identifier}/download) endpoint, using the `identifier` from the listing. Batch identifiers use the same `<language><project_code>_namespace_<number>` format as snapshots, scoped to a specific date and hour in the URL path; see [Identifiers](https://enterprise.wikimedia.com/docs/identifiers/).

### Wikidata batches

Wikidata changes ship as their own hourly batches, addressed by `items` or `properties` instead of a project identifier. [Hourly Wikidata Batch Files Available](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata) lists both batches for a given date and hour, [Wikidata Hourly Batch File Info](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata/{identifier}) reports one file's size, and [Wikidata Hourly Batch File Download](https://enterprise.wikimedia.com/docs/api/#tag/wikidata-batches/GET/v2/batches/{date}/{hour}/wikidata/{identifier}/download) returns a tar.gz file. Each line is a [wikidata\_article](https://enterprise.wikimedia.com/docs/api/#models/wikidata-article), with the same schema as [Wikidata snapshots](https://enterprise.wikimedia.com/docs/snapshot/#wikidata-snapshots). Downloading a snapshot and then ingesting every hourly batch since that first download ensures you always have an up-to-date copy of the Main Graph without the need for a constant open connection to the Realtime Stream.

```bash
curl --location 'https://api.enterprise.wikimedia.com/v2/batches/2026-09-02/05/wikidata/items/download' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  --output wikidata_items_2026-09-02_05.tar.gz
```

## Event types

Every article event has one of three `event.type` values:

- An `update` event type is sent when an article is created, its content is updated, or its name or namespace is changed.
- A `delete` event type is sent when an article has been deleted.
- A `visibility-change` event type is sent when the visibility of an article's editor, comment, or content is changed by community volunteers

Visibility-change events only occur in Realtime. They do not change the content of an article, so they're not tracked as a revision in the On-demand or Snapshot APIs.

## Parallel consumption

Using the `parts` request parameter, you can open more than one parallel connection to the Realtime API. Each connection targets a subset of data partitions, also called a *part*. The maximum allowed number of parallel connections to the Realtime API is 10. Valid values for `parts` are 0 through 9.

If you only want to open one connection that listens to all parts at the same time, you do not need to use parts. When you don't pass the `parts` parameter, the default behavior of the API is to listen to all parts at the same time.

Example POST Request using cURL to connect to the [Streaming Article Updates](https://enterprise.wikimedia.com/docs/api/#tag/realtime-articles/GET/v2/articles), using filter to receive only updates from English Wikipedia, listening to all parts:

```bash
curl --location 'https://realtime.enterprise.wikimedia.com/v2/articles' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--data '{
  "filters": [
    {
      "field": "is_part_of.identifier", "value": "enwiki"
    }
  ],
  "parts": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}'
```

## Reconnecting to the Realtime API

Realtime updates are stored for a rolling 48 hours, meaning you can use a timestamp within the last 48 hours of reconnecting to reopen a connection and get up to speed with any updates you might have missed. For the background on how parallel connections and restart support fit together, see our blog post [Realtime API Parallel Connections and Restart Support](https://enterprise.wikimedia.com/blog/realtime-api-parallel-connections-restart-support/). If you know the timestamp of when your connection to the Realtime stream was closed, you can easily reconnect using one of these two methods:

### Use `since`

This is the simplest and recommended method to reconnect to the Realtime stream. Save the latest timestamp you received for each `event.partition` while you were connected to the streaming endpoint. We recommend using `event.date_published` for this. Pass the last timestamp you received in the since parameter for all partitions to ensure you don't miss any events. If you use `since` to reconnect, you may receive events from some partitions that you already obtained in your previous connection. Therefore we recommend recording the IDs of incoming events to discard duplicate events, ensuring [idempotence](https://en.wikipedia.org/wiki/Idempotence).

Example POST request using cURL asking for all Realtime streaming updates for English Wikipedia since the timestamp `2025-04-15T15:33:50Z`.

```bash
curl --location 'https://realtime.enterprise.wikimedia.com/v2/articles' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--data '{
  "filters": [
    {
      "field": "is_part_of.identifier", "value": "enwiki"
    }
  ],
  "since":"2025-04-15T15:33:50Z"
}'
```

If you use the `since` parameter you cannot specify `parts`. The `since` parameter will automatically apply to all parts at the same time. If you try to pass `since` while also using the `parts` parameter, you will receive the following error message:

```json
{
  "status": 422,
  "message": "for parallel consumption, specify either offsets or time-offsets (since_per_partition) parameter"
}
```

### Use `since_per_partition`

Where the `since` parameter only takes one timestamp as input, `since_per_partition` allows you to define different timestamps for different partitions, so you can start consuming data from different timestamps in different partitions when reconnecting. This is useful if you are using `parts` to consume subsets of partitions, whether you're doing this with one or multiple parallel connections.

The simplest and recommended way to reconnect with `since_per_partition` is to open a single connection. For every partition, find the last `event.date_published` value you received before you disconnected. When reconnecting, send the request parameter parts with the value `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` and the `since_per_partition` object with key-value pairs mapping every part to a corresponding `event.date_published` value, or any other RFC 3339 format timestamp.

The advantage of using `since_per_partition` over using since is that the chances of receiving duplicate events are much lower, as you are supplying precise timestamps per partition. This makes it much less likely that you will receive events that you had already received before reconnection.

Example request with `since_per_partition`:

```bash
curl --location 'https://realtime.enterprise.wikimedia.com/v2/articles' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--data '{
  "filters": [
    {
      "field": "is_part_of.identifier", "value": "enwiki"
    }
  ],
  "parts": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  "since_per_partition": {
    "0": "2023-06-05T12:00:00Z",
    "1": "2023-06-05T12:00:00Z",
    "2": "2023-06-05T12:00:00Z",
    [...],
  }
}'
```

## Response model

Realtime endpoints return the [RealtimeArticle](https://enterprise.wikimedia.com/docs/api/#models/RealtimeArticle) model. Realtime endpoints return fields that are not available in the [article model](https://enterprise.wikimedia.com/docs/api/#models/article) in the [event](https://enterprise.wikimedia.com/docs/api/#models/event) object: `date_published`, `partition`, and `offset` are only populated in Realtime. `event.type:visibility-change` only occurs on Realtime endpoints.

## See also

- [Snapshot API](https://enterprise.wikimedia.com/docs/snapshot/) - download entire projects as compressed NDJSON tarballs.
- [Identifiers](https://enterprise.wikimedia.com/docs/identifiers/) - the batch identifier format, and every other one in the API.
- [Status Codes](https://enterprise.wikimedia.com/docs/status-codes/) - the HTTP responses these endpoints return.
- [Credibility Signals](https://enterprise.wikimedia.com/api/credibility-signals/) - use visibility and other signals to decide what content to trust.
