π One menu. Correct scope. Verified region. The same workflow on every platform.
π£ Follow the B3hnamR Telegram channel for release updates, setup tips, and project announcements.
π A cross-platform (Windows, Linux, macOS), menu-based PowerShell tool that deploys and manages an authorized HTTP streaming relay (a transparent reverse proxy) on your own Vercel account using the official Vercel REST API. The Linux/macOS launcher runs the exact same tool under PowerShell 7 β every feature and screen is identical to Windows.
π‘οΈ Scope & safety: this tool only manages Personal/team scopes accessible to the API token you provide. It performs no scanning, exploitation, credential harvesting, or any action against third-party systems. The relay forwards traffic only to the backend you configure via environment variables β a backend you own or are authorized to manage.
Note
π Version 2.0.0 was built from scratch. The previous implementation became detectable, so this release uses a new architecture and intentionally leaves out some legacy features. It has been tested successfully on Vercel Hobby, Pro Trial, and Pro accounts, and it currently works without requiring a custom domain.
- Highlights
- What's new in v2.0.0 vs v1.3.8
- Full changelog
- Anti-ban tutorial
- How it fits together
- 60-second quick start
- Quick setup walkthrough
- Repository layout
- Requirements
- Detailed platform setup
- Menu and project tools
- Guided deployment flow
- Environment values
- Generated client template
- Build types
- Vercel API reference
- Troubleshooting
- Support the project
- Terminal preview
- π― Scope-aware by design β Personal and team workspaces are separate, with accurate labels such
as
Hobby,Pro, andPro Trialbefore anything is deployed. - π Region settings that are verified β the selected Function region is submitted both in the
deployment payload and
vercel.json, then checked against Vercel's deployment response. - π Two relay modes β choose a streaming Node Function or a zero-compute external-origin Rewrite.
- π§ Safe guided deployment β review every value before project creation, with no empty project left behind when you cancel.
- π» One cross-platform experience β Windows PowerShell 5.1 and PowerShell 7 use the same manager;
manager.shis only the Linux/macOS launcher. - π‘οΈ Operational guardrails β encrypted profiles, explicit scope status, deployment logs, one-shot health checks, and protected bulk-delete confirmation.
β¨ v2.0.0 is a from-scratch successor to v1.3.8. The previous Windows-first installer and template-based architecture were retired after that implementation became detectable. Selected legacy presets and tools were intentionally left out in favor of a smaller, consistent deployment path. See the v2.0.0 release notes for the complete change history.
| Area | v1.3.8 | v2.0.0 |
|---|---|---|
| π§± Core architecture | Windows-first installer combining repository templates, Node/npm, and the Vercel CLI. | One PowerShell manager with embedded relay files and direct inline Vercel REST API deployment. |
| π» Platforms | Windows launcher and Windows-focused setup. | The same manager on Windows, Linux, and macOS, plus a no-sudo PowerShell bootstrap and one-line download-and-launch command. |
| π€ Accounts and scopes | One encrypted Windows token flow with a manually entered or saved team slug. | Multiple cross-platform encrypted profiles with API-listed Personal/team scopes that are remembered and revalidated per profile. |
| ποΈ Deployment choices | Seven legacy preset/custom modes, landing templates, and separate routing/control options. | Two focused transparent builds: a streaming Node Function or a zero-compute external-origin Rewrite. |
| π Function regions | Region selection and project configuration were available. | The chosen region is also submitted in the deployment payload, compared with Vercel's applied metadata, and checked at runtime without confusing Edge ingress with Function compute. |
| π‘οΈ Project safety | Project and billing tools operated through mixed CLI/API scope discovery. | Complete team/project pagination, selected-scope usage validation, scope-status checks, an explicit pre-create review gate, and guarded bulk deletion. |
| βοΈ Client setup | A client example was documented for manual completion. | A ready-to-use share link and JSON are generated after deployment checks; the Vercel domain works by default and verified custom domains are optional. |
Note
π§Ή Intentionally simplified: the v1.3.8 landing-page bundle, legacy deployment-preset matrix, CLI-linked workflow, and selected advanced diagnostics were not carried into the rebuilt core.
flowchart TD
M["PowerShell manager"] -->|"inline deployment"| A["Vercel REST API"]
A --> S["Selected Personal or Team scope"]
C["Client"] --> E["Vercel Edge"]
S -.->|owns project| E
E --> T{"Build type"}
T -->|"Node"| F["Function compute<br/>selected region"]
T -->|"Rewrite"| R["Edge rewrite"]
F --> B["Authorized backend"]
R --> B
π§© The manager controls deployment and the scope that owns each project; client traffic follows only the runtime path from Vercel Edge to the build type you selected and then to your authorized backend.
β‘ Choose the fastest launch method for your platform.
πͺ Windows β files already downloaded
.\Run-XHTTPRelayDeploy.batπ§ Linux / macOS β download and launch in one command
mkdir XHTTPRelayECO && curl -fsSL https://github.com/B3hnamR/XHTTPRelayECO/archive/refs/heads/master.tar.gz | tar -xz -C XHTTPRelayECO --strip-components=1 && cd XHTTPRelayECO && bash manager.shAlready downloaded on Linux/macOS? Run bash manager.sh from the project folder.
- π₯ Download and launch β on Windows, download the ZIP, extract it, and double-click
Run-XHTTPRelayDeploy.bat. On Linux/macOS, paste the one-line command above into Terminal. βΆοΈ Let the launcher prepare the system β Linux/macOS installs a user-local PowerShell 7 automatically whenpwshis missing; no sudo is needed.- π Sign in β paste your Vercel API token when prompted.
- π― Choose the deployment scope β select Personal or the correct team. Press Enter to accept the clearly marked remembered/default choice.
- π Deploy β choose [6] Create new relay project, enter the backend URL, and follow the guided prompts. Whenever a suggested value is shown, press Enter to accept it.
- β
Done β confirm the review screen, wait for
READY, then copy the generated client configuration. The Vercel-provided domain works; a custom domain is optional.
Tip
π‘ Run the one-line installer from a folder that does not already contain XHTTPRelayECO.
For every later launch, open that folder and run bash manager.sh.
- π§
XHTTPRelayDeploy.ps1β the main tool (menu-driven). Same file runs on Windows and Linux/macOS. - πͺ
Run-XHTTPRelayDeploy.batβ Windows double-click launcher (sets execution policy for the process only). - π§
manager.shβ Linux/macOS launcher: ensures PowerShell 7 is present (auto-installs a user-local copy if missing, no sudo) and then runs the identical tool. - πΌοΈ
showcase/terminal.pngβ the terminal preview shown at the bottom of this page. - π
CHANGELOG.mdβ release notes, including the complete v2.0.0 change summary. - π
Anti-Ban-Tutorial.mdβ the preserved Persian anti-ban setup guide. - π¦ The relay project files are embedded inside the PowerShell script and uploaded inline via
the deployment API β no Git required. The Node build ships
package.json+vercel.json+api/relay.js; the Rewrite build shipsvercel.jsonalone (see "Build types" below).
- πͺ Windows 10/11 with Windows PowerShell 5.1 or PowerShell 7+.
- π§ Linux / macOS: nothing to pre-install β
manager.shinstalls PowerShell 7 on first run (or uses an existingpwsh). To download it the box needscurlorwget, plustar. - π A Vercel account and a Vercel API token (create one at https://vercel.com/account/tokens). For team projects, the token must have access to the team.
- π A backend service you control (e.g.
https://backend.example.com:8443).
- π₯ Download the repository ZIP and extract it.
βΆοΈ Double-clickRun-XHTTPRelayDeploy.bat(or run it from Windows Terminal).- π Paste your Vercel API token when prompted.
- π― Pick the deployment scope. Enter selects the remembered scope, or Vercel's default workspace
for a new profile; every choice shows its best-effort plan (for example,
Hobby,Pro Trial, orUnknownwhen Vercel omits billing metadata). - πΎ Choose whether to save the token (encrypted). The chosen scope is remembered separately.
- π Use menu [6] Create new relay project (guided deploy) for the full first-run flow.
-
β‘ Open Terminal in the folder where you want the project, then download and launch it in one command:
mkdir XHTTPRelayECO && curl -fsSL https://github.com/B3hnamR/XHTTPRelayECO/archive/refs/heads/master.tar.gz | tar -xz -C XHTTPRelayECO --strip-components=1 && cd XHTTPRelayECO && bash manager.sh
-
π§ On the first run it installs a user-local PowerShell 7 (no sudo) if
pwshisn't already present, then drops you into the identical menu. Follow steps 3β6 from Windows above. -
π For every later launch, open the downloaded
XHTTPRelayECOfolder and runbash manager.sh.Already downloaded the files manually? Run
bash manager.shdirectly from their folder.(Prefer a system package?
sudo apt install powershell/sudo dnf install powershell/brew install powershellβ ifpwshis on your PATH,manager.shuses it and installs nothing.)
π The token is encrypted at rest (it is never printed or logged), under a per-user config folder. The encryption method depends on the OS:
| OS | Location | Encryption |
|---|---|---|
| Windows | %USERPROFILE%\.xhttp-relay\profiles\<name>.dat |
DPAPI β decryptable only by the same Windows user on the same machine. |
| Linux / macOS | ~/.xhttp-relay/profiles/<name>.dat |
AES-256 with a per-user random key in ~/.xhttp-relay/profiles/.vaultkey (file mode 600, owner-only). |
π‘οΈ Windows DPAPI binds the encrypted token to the same Windows user on the same machine. On Linux
and macOS, protection comes from AES encryption plus owner-only filesystem permissions; it is
not cryptographically bound to that user or machine. Anyone who obtains both a profile's
.dat file and .vaultkey can decrypt the token. Keep both files private, never commit or
share the profile directory, and treat backups containing both files as secrets. A privileged
administrator or malware running as your user can access locally saved credentials on any OS.
π§ Each saved profile also has a <name>.scope.json sidecar in the same directory. It contains only
the last selected scope type and user/team identifiersβnever the token, cached billing data, or
another secret. On load, the preference is bound to the authenticated user and a remembered team
must still appear in the token's team list. Missing, corrupt, stale, or legacy metadata causes the
normal scope picker to choose a new default after the complete team list is available. If Vercel
cannot finish that list, a missing remembered team is not guessed: selection stays unset until you
retry login or menu [15]. Deleting a profile removes both files.
π€ A Vercel token authenticates a user identity; it does not have one global plan. The same user
can have a Personal Hobby workspace and access to a team on Pro Trial. The selected deployment
scope determines project ownership, billing/limits, regions, permissions, environment variables,
domains, logs, and every create/delete operation.
The status panel therefore shows these separately:
Identity: personal-user Personal: Hobby
Deploy: Team example-team Scope plan: Pro Trial
Project: (none selected) Profile: personal-user
Use menu [15] Switch deployment scope at any time. Changing scope clears the selected project so an action cannot accidentally reuse a project ID from another workspace.
[1] Login with Vercel token [8] Configure environment vars
[2] Load / switch saved profile [9] Deploy or redeploy relay code
[3] Identity & scope info [10] Custom domains (list/add/verify/remove)
[4] Deployment-scope usage/status [11] Generate client template
[5] List projects [12] Delete selected project
[6] Create new relay project [13] Delete ALL projects
[7] Select existing project [14] Delete saved profile
[15] Switch deployment scope [0] Exit
π Deployment-scope usage & status (menu [4]). Reads Vercel's billing-cycle usage summary and
prints the same numbers as the dashboard β Fast Data/Origin Transfer, Edge Requests, Function Invocations,
Edge Request CPU Duration, Fluid Provisioned Memory, Fluid Active CPU, Microfrontends Routing,
and ISR Reads/Writes β each as used / limit, plus plan status and the current billing cycle.
The dashboard endpoint silently defaults to the user's default team when Personal is selected;
the tool detects that mismatch and discards those team metrics instead of labeling them Personal.
DELETE ALL before anything is removed. If any project
page fails or repeats a cursor, the tool refuses bulk deletion rather than treating a partial list
as complete. Irreversible.
π§° Project actions submenu. Choosing [7] Select existing project lists your projects and, as soon as you pick one, drops you straight into an actions menu for it β no hunting through the main menu:
--- Project actions :: harbor-router-944 ---
id: prj_...
url: https://harbor-router-944.vercel.app
[1] Configure environment variables [4] Generate client config
[2] Deploy / redeploy relay code [5] Run health check
[3] Custom domains (list/add/verify/remove) [6] Delete this project
[0] Back to main menu
π Saved tokens are named profiles, so you can keep several Vercel identities side by side and
switch without re-pasting tokens. The .dat token file uses DPAPI on Windows or AES-256 on
Linux/macOS. Menu [2] Load / switch saved profile lists them; menu [14] deletes one. Each
profile remembers whether Personal or a team was last selected and makes that the next picker's
default after verifying the user and current team access. You can always override it. An existing
single token.dat from an older version is auto-migrated to a profile named default; its
first successful scope choice creates the new preference sidecar automatically.
π Domains are managed from one submenu β list every domain on the project (the
auto-assigned *.vercel.app host is tagged and protected), add a custom domain,
check / verify one, and remove a custom domain you no longer want. Removal uses
DELETE /v9/projects/{id}/domains/{name}; the Vercel host itself cannot be removed.
π The post-deploy / menu health check decodes the x-vercel-id header and prints the
request's Edge ingress region and, for a Node deployment, its Function compute region. A
two-region value such as fra1::iad1::... means the request entered through Frankfurt but
the function ran in Washington, D.C.; a Rewrite build normally has only the edge region.
This runtime readout complements the post-deploy API check, which verifies that the
deployment's regions field contains the region(s) requested by the tool.
π§Ή Clean navigation. Each menu choice runs on a freshly-cleared screen, so you only ever
see the output of the action you just picked. When it finishes, the tool waits on
Press Enter to continue...; pressing Enter clears that output and redraws the menu. This
applies to the main menu and both sub-menus (project actions, environment variables), so a
result like a domain-status check never scrolls off into a wall of old text.
π§ The guided flow collects every setting first and creates nothing until you confirm β so if you quit at any prompt, no empty project is left in your account:
Run-XHTTPRelayDeploy.bat
-> Enter Vercel token (validated against /v2/user)
-> Deployment scope: Team example-team - Pro Trial (or choose Personal - Hobby)
-> Save token encrypted? Y (also remembers the selected scope)
--- info gathering (nothing created yet) ---
-> Project name: [Enter to auto-generate -> e.g. meridian-gateway-204]
-> Backend URL: https://backend.example.com:8443
-> Path [/api]: /api (the SAME path your client and 3x-ui inbound use; Enter = /api)
-> Build type: [1=Node function, 2=Rewrite/edge proxy] (see "Build types" below)
Node -> Allow insecure TLS? Y (Y for a self-signed backend cert)
maxDuration: [suggested from plan, e.g. 300]
Region(s): [auto-suggested from backend DNS/geo, e.g. fra1]
Rewrite -> (no insecure/maxDuration/region prompts; backend needs a valid public cert)
--- review (still nothing created) ---
-> Review box shows the chosen build + its values
-> Create the project and deploy with these settings? [Y/n]
n -> "Cancelled. No project was created." (account stays clean)
Y -> creates project, sets env vars, deploys inline files, writes a log
-> Health check? Y (one GET confirms the relay is live + reaching the backend)
-> Client UUID: [paste your UUID, or Enter for a UUID-HERE placeholder]
-> (prints a ready-to-use share link + JSON, host & path already filled in)
-> Add custom domain? n
-> Public URL: https://meridian-gateway-204.vercel.app
π‘ Why the review gate matters. v1.3.8 collected the deployment inputs first, but continued into project creation as soon as collection finished. v2.0.0 adds an explicit final review and confirmation, so you can inspect every value and cancel before the tool touches your account.
π² Leave the project-name prompt empty and the tool proposes a realistic, unique name
(e.g. cobalt-relay, meridian-gateway-204, sierra-edge). Press Enter to accept,
r to regenerate, or type your own.
π‘οΈ As soon as the token validates and a deployment scope is chosen, the tool checks that selected
Personal/team workspace's softBlock, billing status, and blocked flag. It prints a clear
warning before deployment if the actual owning scope is paused, blocked, or suspended. A
healthy selection prints <scope> status: active (no blocks detected).
β±οΈ The tool detects the selected deployment scope's plan (best-effort) and suggests a
maxDuration that works without requiring Fluid compute, so deploys don't fail on a
plan-limit error. It never assumes that a team is Pro; unknown metadata uses the safest value:
| Detected plan | Suggested (safe) | With Fluid compute |
|---|---|---|
| Hobby | 60 | up to 300 |
| Pro / Pro Trial | 300 | up to 800 |
| Enterprise | 900 | up to 800 (1800 beta) |
You can type any value at the prompt; the chosen value is shown and logged.
π During deploy the tool resolves the backend hostname's DNS, geo-locates the IP, and suggests the nearest Vercel function region. Example:
Auto hint: DNS A records for 'backend.example.com' => 203.0.113.10
Auto hint: using IP 203.0.113.10 (Germany) -> suggested region 'fra1'.
Choose Vercel Function Region(s). Enter numbers/codes separated by commas.
[1] Paris, France - eu-west-3 - cdg1
[2] Stockholm, Sweden - eu-north-1 - arn1
[3] Dublin, Ireland - eu-west-1 - dub1
[4] London, United Kingdom - eu-west-2 - lhr1
[5] Frankfurt, Germany - eu-central-1 - fra1 (suggested)
[6] Washington, D.C., USA - us-east-1 - iad1
[7] Dubai, UAE - me-central-1 - dxb1
[C] Custom region code(s)
Select region(s) [fra1]:
πΊοΈ You can pick several (5,6) or enter custom valid codes (C β sfo1,sin1), subject to the
selected scope's plan limit. The chosen list is written to vercel.json as "regions": [...]
and is also sent in the inline POST /v13/deployments request's top-level regions field, so
the API deployment does not silently fall back to the project's default. The geo lookup is a
best-effort, read-only query of your backend IP; if it fails, the picker still works with a
default.
Region limits: Hobby supports one configurable Function region; it is not fixed to
iad1. Pro / Pro Trial supports up to five Function regions, and Enterprise supports all available Function regions.iad1is merely the default for new projects when no override is applied. Selecting more regions than the plan allows makes Vercel reject the deployment before the build step.Verification: after creation, the tool compares the deployment API's returned
regionslist with the requested list. A missing API field produces an unverified warning; an explicit mismatch is an error. Either case prevents generation of a ready-to-use client config. The health probe still runs for diagnostics and decodesx-vercel-id: for a Node function, the second region is labeled Function compute while the first is labeled Edge ingress. This prevents a nearby edge location from being mistaken for the configured Function region.
π Every deploy writes a timestamped log to:
<folder containing the script>\logs\deploy-<project>-<YYYYMMDD-HHmmss>.log
The log captures each step, the generated vercel.json, the chosen maxDuration/regions, the
deployment id/URL, the polled build states, and β crucially β the build events / error
lines pulled from GET /v3/deployments/{id}/events. When a deploy ends in ERROR, the
error lines are also printed to the console. The Vercel token is never written to the log.
Important
π The relay files are generated in memory and uploaded inline (base64) via the deployment API β Vercel never pulls from your disk, so nothing needs to live in the current folder to deploy. For convenience, each deploy also writes the exact files it uploaded to:
For a Node deployment, the snapshot is:
<folder containing the script>\projects\<project>\
package.json
vercel.json
api\relay.js
For a Rewrite deployment, the same project folder contains only vercel.json.
These are BOM-free UTF-8, byte-identical to what was deployed β handy for inspection, diffing, or committing to your own repo. They are outputs, not inputs: editing them does not change a future deploy (the script regenerates them from your env/settings each time).
π©Ί After a READY build (and from the project-actions menu, option [5]), the tool offers a
health check: one harmless GET to https://<your-relay>/, with a plain-language reading:
| Result | Meaning |
|---|---|
HTTP 2xx/4xx without x-vercel-error |
Relay is live and reached your backend (a plain GET isn't a real client handshake, so 4xx is normal). |
502 Bad Gateway |
Relay is up, but the backend is unreachable β check BACKEND_URL host/port, firewall, or set ALLOW_INSECURE=1 for self-signed TLS. |
500 / FUNCTION_INVOCATION_FAILED |
The function crashed β check env vars / the deploy log. |
x-vercel-error or HTTP redirect |
Vercel returned a platform/protection response; this does not prove the relay reached the backend. |
| No response / timeout | DNS may not be propagated yet, a cold start may be in progress, or the backend/network may be unresponsive β wait ~30s and retry. |
π The response's x-vercel-id is decoded into Edge ingress and, when present,
Function compute, so the function's runtime region is not confused with the request's edge
location.
| Key | Example value | Notes |
|---|---|---|
BACKEND_URL |
https://backend.example.com:8443 |
Origin only (scheme + host + port). |
RELAY_PATH |
/api |
The single path; client = inbound (visible). |
ALLOW_INSECURE |
1 |
1 skips backend TLS verify (self-signed). |
π The relay forwards the request path to the backend unchanged, so there is exactly one path value β the one your client sends and the one your 3x-ui / Xray inbound listens on. They are the same value; you enter it once.
client ---> https://relay.example.com/api/<session> (client path = /api)
relay forwards the path unchanged
backend <--- https://hr5...:2053/api/<session> (3x-ui inbound path = /api)
- Set the same path on both sides (here
/api). It's stored asRELAY_PATH(plain, so you can see it in the env list) purely as the record of that agreed value. - If 3x-ui returns
404, its inboundpathdoesn't match the path you configured here.
Earlier versions had a separate
BACKEND_PATH; it was removed because for xHTTP the client path and the inbound path are always identical, so two settings only invited mismatches.
π Controls whether the relay verifies the backend's TLS certificate when it connects out:
0(N): verify the cert. A self-signed or hostname-mismatched backend cert β the relayβbackend handshake fails β 502.1(Y): skip verification β accept self-signed/mismatched certs. The traffic is still encrypted, just not authenticated. Use this for a typical 3x-ui box with a self-signed cert.
vless://<uuid>@xhttp-relay-prod.vercel.app:443?security=tls&sni=xhttp-relay-prod.vercel.app&fp=chrome&host=xhttp-relay-prod.vercel.app&type=xhttp&mode=auto&path=%2Fmypath&encryption=none#xhttp-relay-prod
βοΈ The moment a deploy reaches READY, the tool prints a ready-to-use config β it fills in
the host, SNI, Host header, port (443), security=tls, type=xhttp, mode=auto,
fp=chrome, and the path you used for the build automatically, taking the short
https://<project>.vercel.app host. The only thing it asks for is the client UUID:
- Paste a UUID β you get the complete share link + JSON, ready to import.
- Press Enter β the UUID field is filled with a
UUID-HEREplaceholder so you can drop in your real UUID later.
π If the project has a verified custom domain, the generator offers it as the host (so the
config uses e.g. relay.example.com instead of *.vercel.app); the Vercel host stays the default.
The same zero-friction generator is also available from project actions [4].
π The real UUID is shown masked in the on-screen summary but appears in full inside the link and
JSON (so they actually work); the share link is printed with Write-Host and is not written
to the deploy log.
π οΈ [11] Generate client template is the generic, fully-configurable form β scheme,
transport-type, xHTTP mode, and TLS fingerprint are all prompts (defaulting to
xhttp / mode=auto / fp=chrome), and you can point it at a custom domain instead of
the *.vercel.app host. Host, SNI, and Host header default to the public Vercel URL; TLS on
port 443; path defaults to the project's RELAY_PATH.
π At deploy time (guided flow and [9] Deploy/redeploy) the tool asks how to run the relay. Both forward every path to your backend unchanged; they differ in where that happens.
| Node function (default) | Rewrite / edge proxy | |
|---|---|---|
| Files deployed | package.json + vercel.json + api/relay.js |
vercel.json only |
| Where it runs | Serverless function (compute) | Vercel's edge network (no compute) |
| Self-signed backend cert | OK (ALLOW_INSECURE=1) |
Not supported β needs a valid public cert |
| Backend URL | runtime env var (edit without changing code; redeploy to apply) | baked into vercel.json (redeploy to change) |
maxDuration |
applies (Hobby ~300s / Pro ~800s with Fluid) | n/a β no function, no Function maxDuration cap |
| Region on Hobby | one configurable Function region (iad1 is the default) |
served from the nearest edge (e.g. fra1) |
| Cold starts | possible | none |
π‘ Pick Rewrite when your backend already has a trusted TLS certificate and you want the lowest-overhead path; pick Node when the backend uses a self-signed cert, or you want to swap the backend URL later without re-uploading.
Client --HTTPS:443--> Vercel project URL
--> Vercel Node.js Serverless Function (api/relay.js)
--HTTPS stream--> your backend (BACKEND_URL + original path, unchanged)
<--streamed response-- back to the client
vercel.jsonrewrites every path to/api/relay. A regular serverless function still receives the original request URL, so the relay forwards that path to the backend unchanged (pure passthrough β no strip/prepend).- Body parsing is disabled (
export const config = { api: { bodyParser: false } }) so the request body is streamed (req.pipe(proxyReq)), not buffered. - The backend hostname is used as the TLS SNI (
servername). - The backend response is piped straight back (
proxyRes.pipe(res)) β no full-response buffering.hostandaccept-encodingare removed/normalized to keep the stream clean. - A failed backend connection returns a clean 502.
maxDurationis set per-function invercel.jsonand shown during deploy. With Fluid compute (default for new projects), Hobby reaches ~300s and Pro up to 800s; lower legacy limits still work (Hobby 60s / Pro 300s).
Client --HTTPS:443--> Vercel project URL
--> Vercel Edge Network (external-origin rewrite, no function)
--HTTPS--> your backend (BACKEND_URL + original path, unchanged)
<--response-- back to the client
- The whole project is a single
vercel.jsonwith an external-origin rewrite:{ "source": "/(.*)", "destination": "https://<backend>/$1" }. There is noapi/relay.jsand nopackage.jsonβ no compute runs. - The backend origin (scheme + host + port, path stripped) is baked into
vercel.jsonat deploy time. Changing it means a redeploy. - TLS to the backend is verified at the edge β there is no insecure option, so the backend must present a valid, publicly-trusted certificate.
- CDN caching of the proxied response is disabled via the
x-vercel-enable-rewrite-caching: 0header (Vercel caches external rewrites by default since Apr 2026; a tunnel must never be cached). Verify withx-vercel-cache: MISSon a probe. - A served-from-edge response shows a single-segment
x-vercel-id(e.g.fra1::β¦), versus the Node build's Edge-ingress / Function-compute pair (fra1::iad1::β¦) β handy proof that no function executed.
Show the endpoint reference
| Operation | Method | Endpoint |
|---|---|---|
| Validate token / current user | GET | /v2/user |
| List teams | GET | /v2/teams |
| List projects | GET | /v9/projects |
| Create project | POST | /v11/projects |
| Delete project | DELETE | /v9/projects/{idOrName} |
| List env vars | GET | /v9/projects/{idOrName}/env |
| Upsert env var | POST | /v10/projects/{idOrName}/env?upsert=true |
| Delete env var | DELETE | /v9/projects/{idOrName}/env/{envId} |
| Create deployment (inline) | POST | /v13/deployments |
| Add domain | POST | /v10/projects/{idOrName}/domains |
| Domain status | GET | /v9/projects/{idOrName}/domains/{domain} |
| Verify domain | POST | /v9/projects/{idOrName}/domains/{domain}/verify |
| Build events / logs | GET | /v3/deployments/{idOrUrl}/events?builds=1 |
| Scope plan (best-effort) | GET | /v2/teams/{teamId} Β· /v2/user |
| Scope usage summary | GET | https://vercel.com/api/usage-summary |
π Team-scoped requests automatically append ?teamId=...; Personal requests do not. The usage
summary is served from the vercel.com dashboard host (not api.vercel.com) with the same bearer
token. Because that internal endpoint defaults unscoped calls to Vercel's default team, its
returned teamId and plan are validated against the selected scope before any metrics are shown.
- π "Failed to decrypt saved token" β
- Windows: the token file was created by a different Windows user or copied from another machine (DPAPI is per-user/per-machine).
- Linux / macOS: the AES key file
~/.xhttp-relay/profiles/.vaultkeyis missing, was changed, or the vault was copied without it. In either case, use [1] to log in again and re-save.
- πͺ
execution of scripts is disabledβ launch viaRun-XHTTPRelayDeploy.bat(it uses-ExecutionPolicy Bypassfor that process only). - π 403 / "Not authorized" on team resources β your token lacks team access, or you chose the wrong scope. Use [15] to switch scope, or reload with [1]/[2] if team membership changed. A remembered team that is no longer accessible is rejected by the scope picker.
- ποΈ Deployment ends in
ERRORβ open the deploy log inlogs\deploy-<project>-<time>.log. The build error lines (pulled from the deployment events endpoint) are recorded there and also printed to the console. The most common cause ismaxDurationexceeding the plan limit: accept the tool's suggested value, lower it (60 legacy Hobby, 300 legacy Pro), or enable Fluid compute in the Vercel dashboard to allow higher values. - π Invalid region / too many regions β region codes are validated against Vercel's list before deploy, so a bad custom code is ignored. Hobby supports one Function region; Pro / Pro Trial supports up to five. Vercel rejects a deployment that exceeds the selected plan's limit.
- π 502 Bad Gateway β the backend is unreachable from Vercel, or the TLS certificate is
rejected. For a self-signed backend cert, set
ALLOW_INSECURE=1(menu [8] β [4]) and redeploy. ConfirmBACKEND_URLhost/port are reachable over the public internet. - π 404 from 3x-ui / not reaching the inbound β the path you set here must equal your 3x-ui /
Xray inbound
path(they are one and the same value); the client must use that same path too. - πΆ Streaming gets buffered / truncated β long-lived streams are bounded by
maxDuration. Raise it (Fluid compute) and/or send a periodic keep-alive from the backend. A proxy in front of Vercel (e.g. Cloudflare proxied mode) may re-buffer the stream. - β»οΈ Env change has no effect β environment variables are applied at deploy time. After editing env, redeploy (env menu β [7] Redeploy, or main menu [9]).
- π Domain shows "verified: true" immediately but isn't live β use [10] Custom domains β [3] Check / verify and the returned verification challenge / DNS records, not the initial add response.
π If XHTTP Relay Deployer has been useful to you, donations help support continued development, testing, and maintenance.
| Asset / network | Donation address |
|---|---|
| TRON | TVEKp9cAU97PGfvWse7BxseeiwfCVyRef4 |
| USDT - TRC20 | TVEKp9cAU97PGfvWse7BxseeiwfCVyRef4 |
| USDT - BEP20 | 0x34E90a9476028F15064EE8fa6aa7c1b4dDE3f480 |
| TON | UQAuXUNyd4Sfvhm59Ef27UNC46oEBrVys5Ud7VLzqZOj5O13 |
Important
π₯οΈ The v2.0.0 terminal: identity and deployment ownership are always shown separately.
