Transports and Russia
Partner API v1 · revision 1.13 · 9 November 2026 · What changed
The transports, direct and via-RU routes, and which lines to hand out to users in Russia.
All the guides · OpenAPI spec and explorer · Need more? Talk to us · Partner terms
This guide is for partners whose subscribers are in Russia, where home and mobile networks filter VPN traffic with deep packet inspection (DPI). It covers:
- olcRTC, for days when only whitelisted services work: what it is and is not, what it costs and how your subscribers get it;
- the transports the network offers, and what each one is for;
- direct routes, and two-hop routes through an entry node in Russia;
- what we recommend for Russian mobile networks, and what we cannot promise;
- which apps to give your subscribers;
- the route filters, for example to offer only the routes through the entry in Russia, or only direct ones.
Endpoints, fields and error codes are in the API reference, Partner API. Creating subscribers and fetching their subscription are covered in the quick start, and paying for traffic in Paying for your subscribers' traffic. Money is in nanoTON: 1 TON = 1,000,000,000 nano.
olcRTC for whitelist days
On some days, some mobile networks let through only a whitelist of approved services. Reality, Hysteria2 and XHTTP then have nothing to connect to.
olcRTC travels inside a video call on a public video service: Sber SaluteJazz, VK Calls or MTS Link today. Yandex Telemost and WB Stream are carriers too, and neither is offered at the moment: Telemost's service cuts the streams of a call to a trickle, and WB Stream has closed to outside users. On a whitelist day olcRTC works where one of these services is on the whitelist. We cannot tell you in advance which of them are.
What it is and is not
- It is a tunnel inside a video call on Sber SaluteJazz, VK Calls or MTS Link (Yandex Telemost and WB Stream when they are offered), services a whitelist may leave reachable. A subscriber has one key and one line per service, and its usage is metered per subscriber.
- It needs an olcRTC-capable client: Ghostlane, or your own app built on the open-source
engine (the
jsonsubscription format is there for that). - Its availability is not promised. It depends on other companies' video services, so we cannot say that it works on a given network or day. You pay only for traffic that went through.
- Its places are limited. Everyone on the network shares them, and a partner has a share of them.
- It carries less than the other transports. Everyone in a room shares what the room carries.
What it costs
From 20 November 2026 olcRTC traffic has a price of its own: one price per GB for the whole network, whatever the exit or the route. It is the payer's price, with the 20% network fee included. It is set and charged in TON, at the amounts below; the dollar figures are approximate, at 1 TON = $1.44. If the TON rate moves by more than 10 %, we may adjust the TON amounts; a rise is announced 30 days ahead, like any rise. A GB is 1,073,741,824 bytes, upload and download together.
| From (00:00 UTC) | olcRTC, per GB | In TON | In nanoTON |
|---|---|---|---|
| Until 20 November 2026 | The route's own price, as today | — | — |
| 20 November 2026 | About $0.03 | 0.0208 TON | 20,800,000 |
| 8 December 2026 | About $0.05 | 0.0347 TON | 34,700,000 |
| 22 December 2026 | About $0.08 | 0.0556 TON | 55,600,000 |
- The olcRTC price applies when the traffic moves: it is read at every charge and never locked into a session. The other transports keep their rule: a session keeps the price it started with, or a lower one after a drop.
- A rise is announced at least 30 days before it starts. A cut may start at once. The price in
force and the steps to come are in
olcrtc_pricingonGET /. The partner dashboard's olcRTC line shows what your subscribers' olcRTC traffic of the last 30 days costs at the last step.account - olcRTC never passes the entry node in Russia, so a route through the entry adds nothing to it.
- A free trial covers olcRTC traffic: nothing is charged inside it.
- Reality, Hysteria2 and XHTTP keep their prices: the node's price per GB plus the 20% fee, locked when the session starts.
- The same prices apply to partners and to people who use ProofKit directly.
The rest of the rules are in The olcRTC price; how your olcRTC share grows with your olcRTC traffic is in Your share.
How your subscribers get it
In the subscription, in the
ghostlaneandjsonformats. Use?format=ghostlaneon the subscription endpoint, or the hostedhttps://proofkit.org/(every line) orsub/ {sub_token}/ unified https://proofkit.org/(the olcRTC lines alone).sub/ {sub_token}/ olcrtc ?format=jsoncarries the olcRTC entries too.- The
happformat never carries olcRTC, because Happ, Hiddify and v2rayNG cannot run it. - A
happfetch never takes an olcRTC place.
- The
Only once ProofKit switches olcRTC on for your partner account. This switch, the one exit and the share below apply to the subscription and, once subscriptions are switched on for you, to the per-session calls as well.
After the other lines. The olcRTC lines come at the end of the list: one line per video service on one exit, all on the subscriber's own key. They are named
{prefix} DE · olcRTC,{prefix} DE · olcRTC · WB,{prefix} DE · olcRTC · SJand{prefix} DE · olcRTC · VK. A service appears only while the exit serves it, and a service whose server on that exit has been down for more than two hours is left out of the list until it is up again.Outside the subscription, on the same terms.
POST /andapi/ v1/ partner/ subscribers/ {external_id}/ olcrtc GET /also return olcRTC lines (api/ v1/ partner/ subscribers/ {external_id}/ sessions/ {session_id}/ configs olcrtc_url,olcrtc_urls). With subscriptions switched on for you, they follow the subscription's rules:- While olcRTC is off for you,
POST …/answersolcrtc 403 OLCRTC_NOT_ENABLEDandconfigscarries no olcRTC fields. - A subscriber holds one olcRTC place, whichever call made it. A place made by one of these calls is that place: the subscription serves it while its exit is in the list, and makes no second one.
- A new place needs room in your share and in your part of the room, and an exit your
filters keep. When none can be made,
POST …/answersolcrtc 503 NO_OLCRTC_NODEandconfigsleaves the olcRTC fields out. - Do not call either endpoint for a subscriber unless you mean to hand out olcRTC.
A partner without subscriptions switched on is bounded by the rooms' own capacity alone on these two calls: the switch and the share do not apply to it.
- While olcRTC is off for you,
One exit per subscriber.
- The subscription gives each subscriber an olcRTC key on one exit of its list.
- Subscribers are spread over the exits: each one starts at a place in the list fixed by its id.
- A subscriber tries the same exit first on every refresh, so it gets its old place back when that place is free.
- The exit is one of those your filters keep; which one, you cannot choose. With no exit
filter it can be any exit, in Europe or not. If you filter the
jsonentries yourself, keep the olcRTC ones whatever theirexit_country, or the subscriber holds a place it cannot use. - A subscriber that holds a key gets that exit's lines back on every fetch, while the exit is in its list and serves a video service.
- If your exit filter later drops that exit, the key stays while the subscriber has any live
session there, and its list carries no olcRTC line at all: the place still counts, so no
second one is made. A dropped route that has carried traffic stays open, so this can last.
To move the subscriber's olcRTC to an exit you keep, end its sessions on the dropped exit
(
GET …/, thensessions DELETE …/for each whosesessions/ {session_id} origin_idis that exit). The key is revoked about 5 minutes later, and the nextghostlaneorjsonfetch seats the subscriber on an exit you keep, within your share. - olcRTC lines come only for exits in the list. With the entry filter set to routes through the entry only, an exit that has no entry linked to it has no route in the list, and so no olcRTC line either.
Your share
- olcRTC places are scarce: 16 people at a time on each exit today, across all of its video services. Our own users and every partner share them.
- Your share is the larger of a fifth of the network's olcRTC places, rounded up, and 8 places plus one for every 15.625 GiB of olcRTC traffic your subscribers moved in the last 30 days (traffic inside a free trial counts). ProofKit can agree a different share with you; it replaces this one.
- A subscriber counts against your share while it holds an olcRTC key on an exit and has moved
any traffic through that exit in the last 5 minutes, on any of its lines there, Reality
included, not only olcRTC. The same rule takes a slot on that exit, and sets
holds_slotin the occupancy Ghostlane shows. The share counts keys: a subscriber with keys on two exits counts on each where it is present. - A new subscriber is given a place only while fewer of your subscribers than your share are counted.
- On any one exit you hold a part of its keys, idle keys included: a fifth of them at the default share (7 of the 32 keys an exit of 16 places holds), more in proportion as your traffic earns you a larger share, and never more than half (a share ProofKit agrees with you does not change it).
- When you are at your share, or no exit has a free place, the olcRTC lines are left out of that subscriber's list. The rest of the list is served as usual.
- A key held for 30 minutes, whose subscriber has moved no traffic through that exit for 30 minutes, can be taken back for someone who needs the place. Its next refresh asks for a place again. When it is seated on the same exit again, it gets the same key back, so the line it holds works again unchanged.
What to expect
- olcRTC is slower than the other transports: a call carries less.
- It relays UDP too, for example voice calls, at olcRTC's lower speed.
- It leaves to the internet from the exit's own address.
Keep Ghostlane current. Older releases do not know every video service.
In short
- Every route in a subscription comes with up to three lines: VLESS Reality (always), Hysteria2 and XHTTP (when the route carries them). One Happ subscription URL holds them all.
- Every exit comes direct, and through each entry node linked to it. Lines through an entry in
Russia are named
… via RU. - Your route filters, set in the dashboard, can narrow that for all your subscribers: certain exits only, only the routes through the entry in Russia, only direct routes, fewer transports. For Russian mobile networks we recommend both kinds of route and all three transports (see Choosing which lines your subscribers get).
- A route that cannot be started on a fetch is left out of that answer, for example when a node is offline or full, your balance is at zero, the fetch's 5 seconds run out, or the subscriber holds 50 sessions. A later fetch adds it once the cause has passed.
- ProofKit switches subscriptions on for each partner. Until then the subscription endpoint
answers
403 SUBSCRIPTION_NOT_ENABLED, and the hosted URLs serve an older list (see the quick start). - Reality, Hysteria2 and XHTTP can all go through the entry in Russia. olcRTC never does.
- olcRTC runs only in an olcRTC-capable app, such as Ghostlane. Each subscriber gets olcRTC on one exit your filters keep, within your partner share, once ProofKit switches olcRTC on for you.
- olcRTC has a price of its own from 20 November 2026, one price per GB for the whole network. Until then it costs the route's price (see What it costs).
- We have no measurements from inside Russian mobile networks. The recommendations below follow from what each transport is built to survive and what it costs. They are not results per mobile operator.
Terms
| Word | In the API | What it is |
|---|---|---|
| Exit | node_type: "origin" | Runs Xray, decrypts the traffic and sends it to the internet. Every route ends at one exit. |
| Entry | node_type: "edge" | A relay in front of an exit. It runs no Xray and never decrypts anything. |
| Route | a session | One exit, either direct or through one entry. It has one price per GB, set when the route starts. The price follows a later drop in a node's own price once the lower price has stood for 3 hours, never a rise (olcRTC traffic aside: see What it costs). |
| Line | one item in the list | One route over one transport, such as DE via RU · Hysteria2. |
The transports
| Transport | Line in the list | How it travels | Direct: the app connects to |
|---|---|---|---|
| VLESS Reality | vless://…?type=tcp&security=reality&…&flow=xtls-rprx-vision#… | TCP. A real TLS 1.3 handshake that names the exit's cover site (its SNI). | The exit, TCP 443 |
| Hysteria2 | hysteria2://…?sni=…&obfs=salamander&obfs-password=…&insecure=0&pinSHA256=…#… | QUIC over UDP, with Salamander obfuscation. The link pins the exit's certificate hash. | The exit, UDP 443 |
| XHTTP | vless://…?type=xhttp&security=reality&…&mode=packet-up#… | VLESS sent as many HTTP requests, with REALITY in front. | The exit, TCP 8444 |
| olcRTC | olcrtc://telemost…, olcrtc://wbstream…, olcrtc://mtslink…, olcrtc://salutejazz…, olcrtc://vkcalls… | Inside a video call on Yandex Telemost, WB Stream, MTS Link, Sber SaluteJazz or VK Calls. The exit's olcRTC server waits in the same room. | The video service |
Hysteria2 links use the hysteria2:// scheme, never hy2://. The ports shown here and below
are the defaults. A node can use others, and each line always carries the right one.
WebTunnel is not in the table: it is an optional line for routes through an entry or straight to an exit, off until you list it in your Subscription tab (see WebTunnel).
A GB costs the same whichever of Reality, Hysteria2 and XHTTP carries it, because the price
belongs to the route. All three lines of a route share its credential. olcRTC traffic is
metered per GB like the rest. While no olcRTC price is in force (olcrtc_pricing on
GET /), it is charged at the price of the subscriber's
direct route to that exit: the exit's price plus the fee; only a subscriber with no direct
route to that exit is charged a via RU route's price for it. With an olcRTC price in force
it costs that price, whatever the route. The steps are in What it costs.
What each one is for
VLESS Reality is the floor. Every route has a Reality line, and a route that cannot make one is left out of the list.
- To an observer it looks like HTTPS to the cover site.
- A probe that connects to the exit is passed through to the real cover site.
- It does not hide the exit's IP address, and a filter can block or slow an address without identifying the protocol.
- It is one long TLS connection, and behaviour-based DPI can flag that shape.
- If the cover site itself is blocked on a network, the line goes with it. Each exit has its own cover site.
Hysteria2 is for networks where UDP passes but TCP is slowed, and for lossy links.
- Salamander scrambles every packet, the first one included, so there is no QUIC header or server name to fingerprint.
- It needs UDP. Where UDP is blocked, as on some mobile networks, it does not connect. Where UDP is throttled, it is slow.
XHTTP is for networks whose DPI flags a long Reality connection while TCP still works, and where UDP is blocked.
- The traffic is split into separate HTTP requests and responses.
- It uses its own port: TCP 8444 direct, or a port between 40000 and 49999 on the entry. It fails on networks that let only ports 80 and 443 through.
- It needs an Xray-core app (see Apps).
olcRTC is for days when a network lets through only a whitelist of approved services, so the other three have nothing to connect to. See olcRTC for whitelist days.
- It is slower than the other three, because a video call carries less.
- Treat it as the fallback, not the default.
Direct or through an entry in Russia
For each exit, the subscription gives:
- a direct route, where the app connects to the exit itself;
- one two-hop route through each entry linked to that exit. The app connects to the entry, and the entry forwards the bytes, still encrypted, through a tunnel between the two servers.
An entry sees the subscriber's IP address, not the sites they visit. The exit sees the sites, and the connection reaches it from the entry. The encryption of Reality, Hysteria2 and XHTTP runs from the app to the exit, and the entry does not decrypt it.
Why an entry in Russia. A filter that targets connections to foreign addresses does not touch a connection to a server inside the country. From the entry on, the traffic is a tunnel between two servers, not a phone talking to a VPN node abroad. That is why the route exists. We have not measured how often it makes the difference on a given network. The link between the entry and the exit crosses the border too. It has been filtered before, and we changed its tunnel to keep it working.
Which transports go through the entry
| Transport | Direct | Through the entry | Two-hop? |
|---|---|---|---|
| VLESS Reality | exit, TCP 443 | entry, TCP 443. The entry picks the exit by the cover-site name, and the Reality keys and SNI are the exit's. | Yes, on every two-hop route |
| Hysteria2 | exit, UDP 443 | entry, one UDP port per exit in 30000–39999, relayed to the exit | Yes, when the entry–exit link has a Hysteria2 relay port |
| XHTTP | exit, TCP 8444 | entry, one TCP port per exit in 40000–49999, relayed to the exit | Yes, when the entry–exit link has an XHTTP relay port |
| olcRTC | through the video service to the exit | — | No. olcRTC never uses the entry. |
Hysteria2 through the entry is not refused: the entry relays its UDP. A route whose link has no
Hysteria2 relay port carries no Hysteria2, and it has no Hysteria2 line in the list. If you
connect on that route with "transport": "hysteria2" (see
Choosing which lines your subscribers get), the
answer is 400 TRANSPORT_NOT_SUPPORTED. XHTTP lines follow the same rule with their own relay
port: no XHTTP relay port, no XHTTP line. connect checks only Hysteria2 and ignores every other
transport value. The subscription simply leaves out the lines a route does not carry.
Through the entry, Hysteria2 and XHTTP use high ports, and only Reality stays on 443. So on a
network that opens only ports 80 and 443, the one … via RU line that can still connect is
Reality. Direct lines stay on 443 too: Reality on TCP 443, and Hysteria2 on UDP 443 where UDP
passes.
Finding the entries in Russia
In GET /, an entry in Russia has node_type: "edge" and
country: "RU". It also carries entry_region: "RU", which appears only on an entry in Russia.
An exit located in Russia is not an entry and has no entry_region. The catalogue lists only the
nodes that are active now, and agent_online says whether a node's agent is connected at this
moment. A node that stops reporting leaves the catalogue after 5 minutes, but its routes stay in
your subscribers' lists until it has been offline for 30 minutes.
On 2026-09-26:
- There is one entry in Russia. It is linked to every exit, and each link has a Hysteria2 and an
XHTTP relay port, so every exit has a
via RUroute with all three lines. - The exits are in CA, DE, ES, FR, GB, IL, IN, IT, JP, KR, MX, NL, PL, SE, US and ZA. The ones in Europe are DE, ES, FR, GB, IT, NL, PL and SE.
- The one entry is shared by everyone on the network: our own users and every partner. If it is
offline, every
via RUline fails at once, and the direct lines are what is left.
The catalogue gives the live list. The subscription's json entries show which routes exist and
which transports each one carries.
What a route through the entry costs
A route's price per GB is set when it starts:
route price = (exit price + entry price) + 20% network fee (fee rounded down, once, on the sum)
direct = exit price + 20% network fee
The catalogue quotes each node for you:
| Field | Meaning |
|---|---|
price_per_gb_nano | The node's price for you, with any agreed price applied, before the fee |
total_price_per_gb_nano | The same with the fee: what a GB through this node alone costs you |
fee_bps | The fee in basis points: 2000 = 20% |
A two-hop route costs the exit's total_price_per_gb_nano plus the entry's, or 1 nano more,
because the fee is rounded down once, on the sum.
Example. Take an exit at 10,000,000 nano per GB and an entry at 10,000,000 nano per GB (these are example prices; read yours from the catalogue):
| Route | Before the fee | You pay per GB |
|---|---|---|
| Direct | 10,000,000 | 12,000,000 nano (0.012 TON) |
| Via the entry | 20,000,000 | 24,000,000 nano (0.024 TON) |
On 2026-09-26, the entry's list price is 10,000,000 nano per GB before the fee. Every
exit's is the same except DE's, which is 1,000,000. So a via RU route costs twice the direct
one on most exits, and eleven times on DE. An agreed price changes these numbers; the catalogue
gives yours.
- A GB here is a GiB (1,073,741,824 bytes), with upload and download added together.
- Only traffic is charged. A line nobody uses costs nothing.
- If a node's own price drops later, running routes follow the drop once the lower price has stood for 3 hours, and any change of the node's price starts those 3 hours again. A rise does not reach a route that is already running.
- A change to your agreed price reaches only the routes started after it.
Recommendations for Russian mobile networks
What we can tell you. We have no measurement point inside Russian mobile networks.
- Nothing in our data says which operator lets which transport through, in which region, or on which day.
- Blocking differs from one Russian network to another, and it changes over time.
- We do not promise speeds, or results per operator, or that any transport "works on all Russian mobile networks".
What the list is built for: a subscriber whose line stops working switches to another line in the same list, with no call from your backend. The list holds every exit direct and through the entry, each with Reality, and with Hysteria2 and XHTTP where the route carries them, less any route a fetch could not start and anything your route filters leave out.
Give your subscribers the whole list. Do not cut it down to a single transport or a single path. Hysteria2 alone fails wherever UDP is blocked. Reality alone has nothing to fall back to when an exit's address or its long connections are flagged. In the dashboard's Subscription tab, that means entry "All" and all three transports checked; narrowing the exits is fine.
Direct Reality first. A direct line never costs more than the same exit
via RU, which adds the entry's price. Reality is the transport every listed app runs.If an exit's direct lines fail or crawl, try the same exit
via RU. The phone then connects to a server in Russia. It costs both nodes' prices plus the fee.If Reality connects but stalls or drops, try Hysteria2 when UDP passes, and XHTTP when it does not.
If only a handful of services work at all (a whitelist day), switch to olcRTC in an olcRTC-capable app. See olcRTC for whitelist days. Subscribers who use only Happ, Hiddify or v2rayNG have no line for those days: olcRTC comes only in the
ghostlaneandjsonformats. We do not rank exits for Russian networks; the node-level fallback is the entry in Russia, not a particular exit.Keep the subscription refreshing. A line's credential stays the same while its route runs. A route ends, for example:
- when your balance reaches zero. The route whose traffic took the balance to zero is disconnected at once, and every other route you pay for within about 15 seconds. Fetches start no new ones, so your subscribers' lists come back without them. After a top-up the next fetch starts every route again, each with a new credential. See When the balance reaches zero.
- when its node has been offline for 30 minutes. The next fetch starts it again with a new credential.
An olcRTC room that dies is replaced with a new room address and the same key. The app picks up these changes on its next refresh. The list tells the app how often to refresh: every hour by default. You set the refresh interval in the dashboard's Subscription tab, from 1 to 168 hours.
Test with your own users before you scale. Try each kind of line on the mobile networks your subscribers use. Nobody can measure those networks from outside. Do it with a few subscribers and a little traffic, which you pay for per GB. A free trial exists only by agreement with ProofKit (see The free trial).
| What the subscriber sees | Line to try |
|---|---|
| Nothing unusual | DE Direct (Reality) |
| An exit's direct lines fail or are very slow | DE via RU |
| Reality stalls or drops, UDP passes | DE Direct · Hysteria2, then DE via RU · Hysteria2 |
| Reality stalls or drops, UDP blocked | DE Direct · XHTTP, then DE via RU · XHTTP |
| Only ports 80 and 443 open | Reality lines (TCP 443), direct or via RU; DE Direct · Hysteria2 (UDP 443) where UDP passes |
| Only a few whitelisted services reachable | olcRTC (Ghostlane format) |
DE stands for any exit. A second exit in one country is numbered (DE 2), and so is a second
entry in one country for the same exit (via RU 2). The names carry your prefix when you have
set one in the dashboard's Subscription tab, for example My VPN DE via RU · Hysteria2. A
prefix is at most 32 characters and cannot contain #, ?, &, $ or control characters.
Russian sites. The list carries no routing rules, so every site sees a foreign address. On today's exits that is a Cloudflare WARP address for TCP traffic, and the exit's own address for UDP and for olcRTC. Some Russian sites refuse visitors from foreign addresses. Sending Russian sites straight from the phone, and everything else through the VPN, is a setting in the app, not in the list. Ghostlane calls this mode "Bypass Russia", and other apps have their own routing rules.
Device limits. A device limit means Happ, v2RayTun or Ghostlane for your subscribers, or the soft mode. A limit counts only the devices that name themselves, and those three apps do (see Apps). Hiddify, v2rayNG and Streisand send no device id, so under a limit they get no list at all, unless you set Apps that do not name the device in the Subscription tab to "get the list and are not counted": then they are served, and never limited. See Subscriber device limit.
The host the subscription itself rides on
Everything above is about the lines inside a subscription — where the traffic goes. The subscription URL is the other thing a filter can see: it is the address your subscribers' apps come back to for their config, on every refresh.
By default that address is on proofkit.org. If that name is blocked, live tunnels keep
working (the lines point at node addresses), but nobody can refresh: no new config, no
changed routes, no olcRTC lines. Two ways off the shared name:
- Your own domain, our serving. Add
sub.yourdomain.com CNAME subs.proofkit.org(DNS-only) and request the domain on the Partner page. Your links then ride on a name nobody else blocks for you — a different name on direct IP addresses, not the shared host. If it gets blocked in its turn, disable it and request another: three at a time, replaced in minutes.GET /'saccount hosted_basenames the host in force. - Your own domain, your server. The S2S proxy under Serving it under your domain: the same independence, your infrastructure too.
Measure your customers' networks
Which transports and which exits work on an operator's network is measured from phones on that network, and the phones are yours. In the Partner page's Subscription tab, Network watch takes a phone by name and gives you a link to download the ProofKit Reach app for it: install the app on a phone with a local SIM, open it once, and it checks your lines from that operator's network every 30 minutes, on at most 20 MB of the SIM's data a day. The phone is bound to its network by its first report; Network watch then shows what each of your lines (every exit country you sell, direct and through the entry, on each transport) looks like from that network, with how long the state has held. A phone on Wi-Fi or with a VPN running measures nothing until it is back on mobile data, and one reporting from another operator than the one it was bound to reads away. Ten phones at a time; a download link opens a page whose button downloads the app once, within ten minutes (the link itself can be sent through any chat); New link makes a new one, with a new key, so an app installed from an older link stops. Removing a phone there ends it at once. Network watch is switched on per partner by ProofKit: ask in a ticket if your dashboard does not show it.
Apps
| Transport | Apps |
|---|---|
| VLESS Reality | Happ, v2rayNG, Hiddify, Streisand, Ghostlane, and other Xray-core or sing-box apps |
| Hysteria2 | Happ, v2rayNG, Hiddify, Ghostlane |
| XHTTP | Xray-core apps: Happ, v2rayNG, Ghostlane. sing-box-based apps cannot run it. |
| olcRTC | An olcRTC-capable app. Ghostlane is one. |
A device limit counts the apps that name their device, and not every app does:
| App | Names the device |
|---|---|
| Happ | yes |
| v2RayTun | yes |
| Ghostlane | yes |
| Hiddify | no |
| v2rayNG | no |
| Streisand | no |
| Shadowrocket, Karing, Clash Mi, Throne | off by default |
The sing-box apps send none either. Under a limit, an app that names no device gets no list while
your partner's setting is "get no list" (strict, the default), and the list, uncounted, while it
is "get the list and are not counted" (soft).
Which subscription format to give each app:
happ(the default). A base64 list for Happ, Hiddify and v2rayNG: Reality, Hysteria2 and XHTTP, and no olcRTC.ghostlane. The same lines as plain text, followed by the olcRTC lines when olcRTC is on for your account.
A subscriber can use both formats at once, for example the Happ URL in Happ and the Ghostlane URL in Ghostlane. They carry the same routes and the same credentials.
Serve ?format=ghostlane under your own domain the same way as happ: your server answers its
own URL and passes the body on unchanged, with the headers (which you may rewrite, for
example to show your own quota and expiry in subscription-userinfo). The hosted
https://proofkit.org/ URLs show proofkit.org. Ghostlane also reads olcRTC room occupancy from proofkit.org (see
Ghostlane shows occupancy).
Ghostlane is an open-source client (github.com/ghostlane-project) that runs Reality, Hysteria2 and XHTTP, and also runs olcRTC. Your subscribers need it only for olcRTC; for the other three, any app in the table works.
Choosing which lines your subscribers get
The subscription (GET /) gives every
route the subscriber may use that your route filters keep. With no filters, that is every exit
direct, and through every entry linked to it.
Route filters in the dashboard
The owner sets three filters in the Subscription tab of the partner dashboard (#/).
They apply to every subscriber's list at once, in every format and at the hosted URLs, from each
subscriber's next fetch. The full rules are in Route filters.
| Field in the tab | API name | Choices |
|---|---|---|
| exit countries | sub_exit_countries | Country codes such as DE, NL; blank keeps every exit |
| entry | sub_entry | All (all), Direct only (direct), Via entry edge only (via_edge) |
| transports | sub_transports | Reality, Hysteria2, XHTTP and WebTunnel; the first three checked, and WebTunnel not, is the same as no filter (see WebTunnel) |
Only the routes through the entry in Russia. Set entry to "Via entry edge only"
(via_edge). Every Reality, Hysteria2 and XHTTP line then connects to the entry in Russia, is
named … via RU, and costs the exit's price plus the entry's, plus the fee.
- An exit with no entry linked to it drops out of the list, and so does its olcRTC line.
- If the one entry is offline, all those lines fail at once: there are no direct lines to fall back to.
- olcRTC never uses the entry, so its lines still come, on one exit, when olcRTC is on for you.
While no olcRTC price is in force (
olcrtc_pricingonGET /), its traffic is charged at the price of the subscriber's direct route to that exit only while the subscriber holds one (see The transports). Under this filter the subscription gives the subscriber no direct route, so its olcRTC traffic is charged theaccount via RUroute's price, unless the subscriber holds a direct session on that exit anyway: one you made withconnect, or the direct sessionPOST …/makes on an exit where the subscriber held no session. While that session lives, its olcRTC traffic is charged at the direct price. With an olcRTC price in force, it costs that price whatever the route.olcrtc
Only direct routes. Set entry to "Direct only" (direct). The list has no … via RU lines,
and each route costs the exit's price plus the fee. Your subscribers lose the route that first
reaches a server inside Russia, the fallback for an exit whose direct lines fail.
Transports for Russian mobile networks. Keep all three.
- Reality is the floor: every listed app runs it, and through the entry it is the one line that stays on port 443. Do not leave it out.
- Hysteria2 is the line for networks where UDP passes but TCP is slowed.
- XHTTP is the line for networks where UDP is blocked and a long Reality connection is flagged. Leave it out only if your subscribers' app cannot run it: sing-box-based apps such as Hiddify cannot, Happ and v2rayNG can.
- A transport left out is missing from every route. Hysteria2 alone fails wherever UDP is blocked.
What we recommend for Russian mobile networks is both kinds of route and all three transports: entry "All" and every transport checked. Narrowing the exits, for example to Europe, does not weaken the list in the same way: each exit kept still comes direct and through the entry, with all three transports.
The filters apply to the subscription only: connect and the catalogue ignore them.
Lists per subscriber
To give some subscribers a narrower list than the others, fetch
?format=json, keep the entries you want and serve your own body. The answer looks like this:{ "entries": [ { "url": "vless://…", "transport": "vless_reality", "remark": "My VPN DE via RU", "session_id": "…", "origin_id": "…", "edge_id": "…", "exit_country": "DE", "entry_country": "RU" } ], "upload": 0, "download": 0 }transportisvless_reality,hysteria2,vless_xhttporolcrtc. An olcRTC entry also hascarrier:telemost,wbstream,mtslink,salutejazzorvkcalls.remarkis the line's name, your prefix included.entry_countryis the entry's country ("RU"for the entry in Russia), andedge_idis the entry's id. Both arenullon a direct line and on every olcRTC line, so pick olcRTC lines bytransport, not by a missing entry.uploadanddownloadare the subscriber's bytes this calendar month (UTC).- A JSON fetch still starts every route.
- When olcRTC is on for your account, a JSON fetch also takes an olcRTC place, as a Ghostlane fetch does.
Or connect route by route. Call
POST /withapi/ v1/ partner/ subscribers/ {external_id}/ connect exit_countryand"entry_country": "RU", then read the route's lines fromGET /.api/ v1/ partner/ subscribers/ {external_id}/ sessions/ {session_id}/ configs - If no entry in Russia is linked to the chosen exit and free, the route is created
direct, without an error. Check
edge_idin the answer:nullmeans direct. - Use the country code as the catalogue writes it (
"RU"). - To name the entry exactly, pass its
edge_idfrom the catalogue together withexit_country. The exit is then chosen among those linked to that entry. - If you pass both
origin_idandedge_id, the call does not check that the two are linked. Name only a pair you know is linked: the subscription'sjsonentries show the pairs that exist. - The lines from
configsare named after the route (DE via RU), without your prefix. - A route you connect yourself is closed if it has carried no traffic an hour after it was
made, and its credential is removed from the node. Connect again, or use the subscription,
whose routes are kept while they are active. Once subscriptions are on for you, a
subscription fetch for the same subscriber lists a route you connected, if your filters
keep it, and adopts it as a subscription line: it is then kept like the others. A pair of
origin_idandedge_idthat is not linked shows up that way too, with lines that do not work, until you end its session. - On an exit that serves a video service,
configsalso returns olcRTC lines and can take a room key there, on the terms in How your subscribers get it.
- If no entry in Russia is linked to the chosen exit and free, the route is created
direct, without an error. Check