For providers
Header documentation
How your panel drives the client's presentation through plain HTTP response headers: the mechanism, the parsing rules, compatibility, delivery through a proxy and a CDN, a rollout checklist. The full header list is in the reference.
How it works
The client fetches the subscription with a plain HTTP request. The body is a mihomo config; the response headers carry everything else: service name, remaining traffic, theme, widget set, billing links. No SDK, no plugin and no agreement with us is required.
Headers are re-read on every profile update — manual or scheduled. Values belong to the profile, not to the application: the theme comes from whichever profile is currently active.
HTTP/1.1 200 OK
Content-Type: application/yaml; charset=utf-8
Subscription-Userinfo: upload=13421772800; download=83994443776; total=214748364800; expire=1798761600
Profile-Title: Nebula VPN
ReClash-ServiceName: Nebula VPN
ReClash-Hex: 2FD3B6:vibrant
ReClash-SupportURL: https://nebula.example/help
Three layers of headers
The headers ReClash reads fall into three groups — it helps to know which does what. The full list of each layer is in the reference.
- Common
- Standard Clash headers —
subscription-userinfo,profile-titleand the rest. If you already send them, nothing changes. - ReClash
- Twenty
reclash-*headers — everything that makes the dashboard yours: theme, ring, widgets, announcements. Only ReClash reads them. - Aliases
- The
flclashx-*headers ReClash reads for compatibility — so you need not redo anything. See “Compatibility”.
Headers are presentation hints, not a trust mechanism. The user can override nearly everything you send.
Parsing rules
These rules hold for every header at once — keep them in mind as you read the reference.
- Case does not matter
- Header names are compared case-insensitively:
ReClash-Hex,reclash-hexandRECLASH-HEXare the same header. - reclash-* wins
- When
reclash-*, an alias and a common header all arrive,reclash-*wins. - Repeats are joined
- Several identical headers are joined with commas, exactly as HTTP does.
- Empty is ignored
- Empty values and unknown tokens are dropped: a typo cannot break the app.
- Base64 for non-ASCII
- Text headers accept a
base64:orbase64,prefix. For Cyrillic and emoji it is mandatory — an HTTP header is no place for them. - HTTPS only in links
- All URLs are absolute and HTTPS. The one exception is the background, which also accepts
http. Credentials in URLs are rejected.
Compatibility
ReClash reads some FlClashX headers so providers do not have to redo anything. The order in the table is the priority order: the first non-empty value wins. In the reference the alias is shown right on its header's card.
| What it sets | Priority |
|---|---|
| Announcement | reclash-announce → announce |
| Support URL | reclash-supporturl → support-url → flclashx-supporturl |
| Update interval | reclash-autoupdateinterval (min) → profile-update-interval (h) → flclashx-autoupdateinterval (h) |
| Service name | reclash-servicename → flclashx-servicename |
| Service logo | reclash-servicelogo → flclashx-servicelogo |
| Server-info group | reclash-serverinfo → flclashx-serverinfo |
| Plan URL | reclash-buyplan → flclashx-buyplan |
| Traffic URL | reclash-buytraffic → flclashx-buytraffic |
| Report URL | reclash-reporturl → report-url |
| Proxy view | reclash-view → flclashx-view |
| Theme | reclash-hex → flclashx-hex |
| Background | reclash-background → flclashx-background |
| New domain | reclash-newdomain → flclashx-newdomain |
The active-protection text, hero ring, widgets, reclash-custom, reclash-settings and fallback hosts have no aliases — they are ReClash features.
Delivery and debugging
The most common problem is that the headers are right at the origin but the client never sees them. Start by looking at what actually goes over the wire:
# what actually reaches the client
curl -sSI 'https://sub.nebula.example/sub/TOKEN' | grep -i 'reclash\|subscription\|profile\|content-disposition'
# the subscription body, without headers
curl -s 'https://sub.nebula.example/sub/TOKEN' | head -20The output should carry your reclash-* and subscription-userinfo. If they are missing, the problem is between the panel and the client, not in the values themselves.
- Headers never reach the client
- A reverse proxy or CDN is almost always stripping them. nginx does not forward arbitrary upstream headers by default — check that nothing
proxy_hide_headersreclash-*before the subscriptionlocation, and that the panel emits them upstream of the proxy. Grab a ready nginx or Caddy snippet in the builder. - Cyrillic arrives as garbage
- An HTTP header carries ASCII only. Encode any non-Latin text — service name, announcement, connection headline — with a
base64:prefix. The builder does this for you. - Values show up twice
- The panel already sends a header and your proxy adds it again: nginx's
add_headerappends rather than replaces. Hide the original withproxy_hide_header, or set the value in one place only. - The CDN caches a stale response
- If the subscription goes through a CDN, it may serve a cached response with the old headers. Exclude the subscription path from the cache, or send
Cache-Control: no-storeon it. - The header arrives but is ignored
- Check the spelling and value against the reference: unknown tokens and empty values are dropped silently. The name's case does not matter, but
reclash-viewandreclash-hexparse by strict rules — see “Parsing rules”.
Devices and HWID
When the user enables device-identifier sharing, the subscription request carries a few extra headers. They exist so you can show a sensible device list and a plan device limit.
| Request header | Value |
|---|---|
x-hwid | Stable 16-character device hash |
x-device-os | Operating-system name |
x-ver-os | Operating-system version |
x-device-model | Device model or host name |
Responding to the client
| Response header | What the client shows |
|---|---|
x-hwid-max-devices-reached | Shows the device-limit message and offers reclash-supporturl when available. |
x-hwid-not-supported | Shows that the selected client/device mode is unsupported. |
Rollout checklist
- Send
subscription-userinfo— it is the most visible thing to the user. - Add
reclash-servicenameand a logo: the dashboard stops being nameless. - Set
reclash-supporturl— fewer “where do I write?” messages. - Pick a colour via
reclash-hexand check it in the live preview in the builder. - Verify with curl:
curl -sI 'https://…/sub' | grep -i reclash. - Make sure the headers survive your reverse proxy and CDN.
- Do not send
reclash-settingswithout a reason.
The source of truth for this page is PROVIDER_HEADERS.md in the repository. If the two ever disagree, the repository is right.