> For the complete documentation index, see [llms.txt](https://docs.infoway.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.infoway.io/en-docs/websocket/websocket-subscribe-method/real-time-news.md).

# Real-Time News (News) Subscription

#### Overview

This WebSocket API provides real-time news push notifications.

After the connection is established, the client subscribes by **language (`lang`)**:

* `data.lang` is required. It must be a single language code (case-insensitive; normalized to lowercase on the server). See the language enum below for supported values
* A new subscription on the same connection **overwrites** the previous `lang`
* The package must have news permission enabled (`newsFlag=1`); otherwise the handshake fails
* Each `apikey` is allowed **only one** connection; a new connection is rejected if one already exists

#### Language Enum

`lang` supports only the following values. The right column is the associated country/market code (`en` maps to global, with an empty country code):

| lang      | Country / Market Code | Description         |
| --------- | --------------------- | ------------------- |
| `en`      | (empty)               | English             |
| `zh-Hans` | `CN`                  | Simplified Chinese  |
| `zh-Hant` | `HK`                  | Traditional Chinese |
| `ja`      | `JP`                  | Japanese            |
| `ko`      | `KR`                  | Korean              |
| `de`      | `DE`                  | German              |
| `fr`      | `FR`                  | French              |
| `es`      | `ES`                  | Spanish             |
| `pt`      | `BR`                  | Portuguese          |
| `ru`      | `RU`                  | Russian             |
| `tr`      | `TR`                  | Turkish             |

#### Request Frequency

Keep the connection alive with heartbeats. It is recommended to send a heartbeat every **30 seconds** (protocol number `10010`). If the server does not receive a heartbeat (business heartbeat or WebSocket Ping) for more than **60 seconds**, the connection will be closed automatically.

#### Error Code Explanation

Please refer to the WebSocket error code documentation for further details.

Common handshake / connection errors:

| code  | Description                                          |
| ----- | ---------------------------------------------------- |
| `200` | Handshake success                                    |
| `507` | Missing parameter (e.g. `data` / `data.lang`)        |
| `513` | Heartbeat timeout                                    |
| `514` | Incorrect WebSocket path                             |
| `515` | Request is not JSON                                  |
| `517` | Handshake failed: apikey is missing                  |
| `518` | Handshake failed: apikey does not exist              |
| `519` | Handshake failed: no news permission (`newsFlag!=1`) |
| `520` | Handshake failed: apikey already connected           |
| `521` | Handshake failed: server connection limit reached    |

#### Subscription Address

```
wss://data.infoway.io/news?apikey=YourAPIKey
```

> The path must be `/news`, and `apikey` must be passed as a query parameter.

#### Request Quantity

Each WebSocket connection keeps only **one** active subscription at a time (a new subscription overwrites the previous one). Each `apikey` is allowed only **one** concurrent connection.

#### Request (Protocol Number: 10020)

```json
{
    "code": 10020,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0",
    "data": {
        "lang": "en"
    }
}
```

| Parameter | Type    | Required | Description                                                                            | Example                            |
| --------- | ------- | -------- | -------------------------------------------------------------------------------------- | ---------------------------------- |
| `code`    | Integer | Yes      | Protocol number for the request                                                        | Real-time news subscribe: `10020`  |
| `trace`   | String  | Yes      | Trace ID (random string)                                                               | `423afec425004bd8a5e02e1ba5f9b2b0` |
| `data`    | JSON    | Yes      | Subscription data                                                                      |                                    |
| `＜lang`   | String  | Yes      | Language to subscribe (single language, case-insensitive). See the language enum above | `en`                               |

#### Response (Protocol Number: 10021)

```json
{
    "code": 10021,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0",
    "msg": "ok",
    "data": {
        "lang": "en"
    }
}
```

| Parameter | Type    | Required | Description                                | Example                                    |
| --------- | ------- | -------- | ------------------------------------------ | ------------------------------------------ |
| `code`    | Integer | Yes      | Response protocol number                   | Real-time news subscribe response: `10021` |
| `trace`   | String  | Yes      | Trace ID from the request                  | `423afec425004bd8a5e02e1ba5f9b2b0`         |
| `msg`     | String  | Yes      | Response message                           | `ok`                                       |
| `data`    | JSON    | Yes      | Active subscription criteria               |                                            |
| `＜lang`   | String  | Yes      | Subscribed language (normalized lowercase) | `en`                                       |

#### Push (Protocol Number: 10022)

```json
{
    "code": 10022,
    "data": {
        "dk": "a1b2c3d4e5f6...",
        "country": "US",
        "lang": "en",
        "route": "lang",
        "title": "Apple raises full-year revenue forecast",
        "published": 1747552358,
        "urgency": 2,
        "provider": "reuters",
        "symbols": ["AAPL"],
        "link": "https://www.example.com/article/123",
        "content": "Apple Inc said on Monday it expects...",
        "sd": "Apple raises full-year outlook on strong iPhone demand"
    }
}
```

| Parameter    | Type    | Required | Description                                | Example                                   |
| ------------ | ------- | -------- | ------------------------------------------ | ----------------------------------------- |
| `code`       | Integer | Yes      | Push protocol number                       | Real-time news push: `10022`              |
| `data`       | JSON    | Yes      | Push data entity                           |                                           |
| `＜dk`        | String  | Yes      | Deduplication key (`md5(title + content)`) | `a1b2c3d4e5f6...`                         |
| `＜country`   | String  | No       | Country (may be empty for global feeds)    | `US`                                      |
| `＜lang`      | String  | Yes      | Language                                   | `en` / `zh-Hans`                          |
| `＜route`     | String  | Yes      | Ingestion route                            | `country` / `lang`                        |
| `＜title`     | String  | Yes      | Title                                      | `Apple raises full-year revenue forecast` |
| `＜published` | Long    | Yes      | Publish timestamp (Unix seconds)           | `1747552358`                              |
| `＜urgency`   | Integer | Yes      | Urgency level (lower means more urgent)    | `2`                                       |
| `＜provider`  | String  | Yes      | News provider                              | `reuters` / `gelonghui`                   |
| `＜symbols`   | Array   | No       | Related symbols                            | `["AAPL"]`                                |
| `＜link`      | String  | No       | External link (flash/brief news)           | `https://www.example.com/article/123`     |
| `＜content`   | String  | No       | Plain-text content                         |                                           |
| `＜sd`        | String  | No       | Summary (shortDescription)                 |                                           |

#### Heartbeat (Protocol Number: 10010)

```json
{
    "code": 10010,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0"
}
```

The server refreshes the connection activity timestamp and **does not send a business response**. You may also use standard WebSocket `Ping` / `Pong` to keep the connection alive.
