# Subscription formats

### Supported protocols

| Protocol    | Scheme                   | Description                        |
| ----------- | ------------------------ | ---------------------------------- |
| VLESS       | `vless://`               | Main protocol                      |
| VMess       | `vmess://`               | JSON-based configuration in base64 |
| Trojan      | `trojan://`              | Password authentication            |
| Shadowsocks | `ss://`                  | SIP002 and modern format           |
| Hysteria2   | `hysteria2://`, `hy2://` | Multi-port support                 |
| SOCKS5      | `socks://`               | Proxying through SOCKS5            |
| WireGuard   | `wireguard://`           | WireGuard tunneling                |

> Schemes `ssr://`, `tuic://`, `hysteria://` are recognized by the app, but **are not parsed** — servers with these schemes will be skipped.

### Subscription body formats

#### 1. Base64-encoded links

The most common format. The response body is base64 and, when decoded, contains links one per line:

```
base64(
  vless://uuid@server1:443?security=tls#Server1
  vless://uuid@server2:443?security=tls#Server2
)
```

URL-safe Base64 is supported (`-` → `+`, `_` → `/`).

#### 2. Plain text links

Links in plain text, one per line:

```
vless://uuid@server1:443?security=tls#Server1
vmess://eyJhZGQiOiJzZXJ2ZXIyIn0=
trojan://password@server3:443#Server3
socks://user:pass@server4:1080#Server4
wireguard://secretKey@server5:51820?publickey=KEY&address=10.0.0.2#Server5
```

#### 3. JSON formats

**Array of full xray configs:**

```json
[
    { "outbounds": [...], "routing": {...} },
    { "outbounds": [...], "routing": {...} }
]
```

**Full xray config** (single object with `inbounds` and `outbounds`):

```json
{
    "inbounds": [...],
    "outbounds": [...],
    "routing": {...},
    "dns": {...}
}
```

More details: full-xray-config.md.

#### 4. Mixed format

Server links + routing strings + metadata in one body:

```
vless://uuid@server1:443?security=tls#Server1
vless://uuid@server2:443?security=tls#Server2
://autorouting/onadd/https://example.com/routing.json
#announce: Scheduled maintenance tomorrow
```

**Supported special strings in the body:**

| Pattern                            | Description                                           |
| ---------------------------------- | ----------------------------------------------------- |
| `://autorouting/onadd/{url}`       | Auto-updating routing profile (URL, with `sourceURL`) |
| `://autorouting/add/{url}`         | Auto-updating routing profile (URL, with `sourceURL`) |
| `://routing/onadd/{url}`           | One-time profile import by URL (without auto-update)  |
| `://routing/onadd/{base64}`        | Static routing profile                                |
| `://routing/add/{base64}`          | Static routing profile                                |
| `://onadd/{url or base64}`         | Short form (without auto-update)                      |
| `://routing/{base64}`              | Short form                                            |
| `#announce: text`                  | Announcement (supports `base64:...`)                  |
| `#profile-title: text`             | Subscription name (supports `base64:...`)             |
| `#support-url: URL`                | Support link                                          |
| `#profile-web-page-url: URL`       | Provider website link                                 |
| `#announce-url: URL`               | Announcement link                                     |
| `#profile-update-interval: number` | Update interval (hours)                               |

Special strings are extracted from the body and are not included in the server list.

> **Priority:** values from HTTP headers take precedence over values from the body. Inline metadata in the body is used as a fallback if the corresponding header is missing.

***

### HTTP headers

#### Subscription headers

| Header                    | Type   | Description                                                             |
| ------------------------- | ------ | ----------------------------------------------------------------------- |
| `profile-title`           | string | Subscription name (up to 25 characters). Supports base64                |
| `subscription-name`       | string | Alternative `profile-title` (fallback)                                  |
| `profile-description`     | string | Subscription description. Supports base64                               |
| `profile-update-interval` | int    | Update interval in hours                                                |
| `subscription-userinfo`   | string | Traffic statistics and expiration date                                  |
| `support-url`             | URL    | Support link                                                            |
| `profile-web-page-url`    | URL    | Provider website link. Alternative: `homepage`                          |
| `announce-url`            | URL    | Announcement link                                                       |
| `announce`                | string | Announcement text (up to 200 characters). Supports base64               |
| `autorouting`             | URL    | Auto-updating routing profile source URL                                |
| `routing`                 | string | Routing profile (base64 or full URL)                                    |
| `sort-order`              | string | Server sorting order: `ping`, `name`, `none`                            |
| `content-disposition`     | string | Fallback for subscription name (extensions `.txt`, `.yaml` are removed) |

#### Profile Title

Supports two formats:

**Plain text:**

```
profile-title: My VPN
```

**Base64 with description:**

```
profile-title: base64:TWVNdiBWUE4KV2VsY29tZSB0byBvdXIgc2VydmljZQ==
```

When base64-decoded: the first line is the name, the rest is the description.

#### Subscription User Info

```
subscription-userinfo: upload=0;download=1073741824;total=10737418240;expire=1735689600
```

| Field      | Type | Description                               |
| ---------- | ---- | ----------------------------------------- |
| `upload`   | int  | Outgoing traffic (bytes)                  |
| `download` | int  | Incoming traffic (bytes)                  |
| `total`    | int  | Traffic limit (bytes)                     |
| `expire`   | int  | Expiration date (Unix timestamp, seconds) |

> If `expire` > 32000000000 — the value is interpreted as milliseconds and converted to seconds.

**Hiding the traffic block:**

If the server returns `subscription-userinfo: 0`, the traffic block on the main screen is completely hidden. Use this when traffic statistics are not provided.

#### Announce

The announcement text is displayed on the main screen as a banner. Up to **5 lines** of text are supported, after which the text is truncated with an ellipsis.

```
announce: Server update on March 15
```

```
announce: base64:0J7QsdC90L7QstC70LXQvdC40LUg0YHQtdGA0LLQtdGA0L7Qsg==
```

#### Sort Order

Sets the server sorting order in the app. When the subscription is updated, the value is applied to the global sorting setting.

```
sort-order: ping
```

| Value  | Description                            |
| ------ | -------------------------------------- |
| `none` | Default order (as in the subscription) |
| `ping` | By ping (fastest first)                |
| `name` | Alphabetically                         |

***

### Request headers (client → server)

When updating the subscription, the app sends:

| Header            | Description                        |
| ----------------- | ---------------------------------- |
| `User-Agent`      | `INCY/<version>/<platform>`        |
| `Accept`          | `*/*`                              |
| `Accept-Language` | Device language tag (e.g. `ru-RU`) |
| `Accept-Encoding` | iOS only: `gzip, deflate, br`      |
| `x-app-version`   | App version                        |
| `x-device-locale` | Device language                    |
| `x-client`        | `INCY`                             |

When HWID sending is enabled, additionally:

| Header           | Description                                                                   |
| ---------------- | ----------------------------------------------------------------------------- |
| `x-hwid`         | Hardware ID (more details)                                                    |
| `X-Device-ID`    | Alias for `x-hwid` on Android (some server stacks expect exactly this header) |
| `x-device-os`    | Platform (`iOS`, `Android`, `Linux`, `Windows`)                               |
| `x-ver-os`       | OS version                                                                    |
| `x-device-model` | Device model                                                                  |

> All HTTP headers are case-insensitive. The server may look at `x-hwid` or `X-HWID` — the same bytes will be received.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://incy.gitbook.io/docs/docs-en/developer-documentation/subscription-formats.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
