Developer documentation
Wire your VPN, streaming app or QA pipeline into the Vela residential gateway. One credential, drop-in SOCKS5, billed per byte.
01Quickstart
Create a business account, top up your wallet, copy your SOCKS5 credential from the console, and point any SOCKS5h client at the gateway:
# SOCKS5 (remote DNS) — UK residential exit to BBC iPlayer
curl --proxy "socks5h://USER:PASS@gateway.vela.watch:1080" \
https://www.bbc.co.uk/iplayer
gateway.vela.watch:1080 · SOCKS5 (TCP + UDP ASSOCIATE). A new account starts at a zero balance — top up first, the gateway refuses a zero-balance session.02Authentication
The proxy speaks standard SOCKS5 username/password auth:
- Username — encodes routing (account, session, country, service). See §03.
- Password — your API key (
sk_live_…), minted in the console or via the REST API. The same key is reused across sessions; rotate it if leaked.
The REST API (same origin as the console) is authenticated with a Bearer JWT from /v1/b2b/login, or with your API key.
03Username format
The username embeds your account ID, a sticky session token, the egress country, and optionally a streaming service:
vela-{account}-session-{session}-country-{cc}[-service-{svc}]
# Examples
vela-u_abc123-session-s0001-country-uk
vela-u_abc123-session-s0001-country-uk-service-bbc
session— opaque token, up to 64 chars,[a-z0-9_]. Same session = same residential exit IP (sticky).country— ISO 3166 alpha-2 (e.g.uk,de).service— optional streaming service tag (see §04); pins the session to that service's routing.
04Countries & service tags
The gateway is streaming-scoped: only allow-listed streaming hostnames pass; anything else is refused (and not billed). Need a service or country added? Ask sales.
| Service | Service tag |
|---|---|
| Netflix | netflix |
| Prime Video | prime |
| BBC iPlayer | bbc |
| ITVX | itvx |
| Channel 4 | c4 |
| Sky / NOW | sky |
| Disney+ | disney |
| Paramount+ | paramount |
| Apple TV+ | appletv |
| Discovery+ | discovery |
| DAZN | dazn |
| Max | max |
GET /v1/b2b/countries and the public GET /v1/status. Additional countries are onboarded on request.05Code examples
# curl curl --proxy "socks5h://USER:PASS@gateway.vela.watch:1080" https://www.bbc.co.uk/iplayer # Python (requests + PySocks) import requests proxies = {"http": "socks5h://USER:PASS@gateway.vela.watch:1080", "https": "socks5h://USER:PASS@gateway.vela.watch:1080"} r = requests.get("https://www.bbc.co.uk/iplayer", proxies=proxies, timeout=30) # Node (undici / fetch with socks) import { SocksProxyAgent } from 'socks-proxy-agent'; const agent = new SocksProxyAgent('socks5h://USER:PASS@gateway.vela.watch:1080'); const res = await fetch('https://www.bbc.co.uk/iplayer', { dispatcher: agent }); # Go (golang.org/x/net/proxy) dialer, _ := proxy.SOCKS5("tcp", "gateway.vela.watch:1080", &proxy.Auth{User: "USER", Password: "PASS"}, proxy.Direct)
Browsers: set Manual proxy → SOCKS v5, host gateway.vela.watch, port 1080, with your username/password.
06Sticky sessions & rotation
A session pins to one residential exit IP and stays put until you rotate it — there is no fixed expiry while traffic keeps flowing (idle sessions roll off after a long TTL). To move a session to a fresh node:
# release the binding — next request lands on a new node curl -X POST -H "Authorization: Bearer $JWT" \ -H "Content-Type: application/json" \ -d '{"session":"s0001","country":"uk"}' \ https://vela.watch/v1/b2b/proxy/rotate # rotate AND blacklist the previous node for your account curl -X POST ... https://vela.watch/v1/b2b/proxy/discard
GET /v1/b2b/proxy/assigned lists your active sessions with opaque node references — never raw exit IPs.
07Multi-session (for VPN providers)
One business account can run unlimited concurrent sticky sessions — one per your end-user. Put any token in the session field and each gets its own dedicated residential exit, all drawing on a single wallet and credential:
vela-u_abc123-session-enduser_4471-country-uk-service-bbc vela-u_abc123-session-enduser_9920-country-uk-service-netflix
Rotate or discard any single user's exit independently; no per-session fees, no setup.
Sub-account spend caps
Mint a separate API key per sub-brand or customer and give it an optional spend cap. A key with a quota is refused once it is reached — so one delegated sub-account can never drain your whole wallet — while your other keys keep working. Usage is tallied per key.
# create a key capped at 50 GB curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \ -d '{"label":"reseller-A","quota_gb":50}' \ https://vela.watch/v1/b2b/api-keys # later: raise the cap and reset the monthly tally curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \ -d '{"quota_gb":100,"reset_used":true}' \ https://vela.watch/v1/b2b/api-keys/{key_id}/quota08REST API
Base:
https://vela.watch. Auth:Authorization: Bearer <JWT>.
Method Path Purpose POST /v1/b2b/signup Create a business account POST /v1/b2b/login Get a JWT GET /v1/b2b/me Account + wallet snapshot (incl. needs_topup)GET /v1/b2b/countries Available egress countries GET /v1/b2b/tunnel-credential Your SOCKS5 username + key GET /v1/b2b/usage Daily metered usage GET /v1/b2b/usage/by-country · /by-service · /timeseries Usage breakdowns GET /v1/b2b/api-keys List keys POST /v1/b2b/api-keys Mint a key (optional quota_gbsub-account cap)POST /v1/b2b/api-keys/{id}/quota Update a key's spend cap / reset its usage DEL /v1/b2b/api-keys/{id} Revoke a key POST /v1/b2b/proxy/rotate · /discard Move a sticky session GET /v1/b2b/proxy/assigned Active sessions (no raw IPs) GET /v1/b2b/webhooks List webhooks POST /v1/b2b/webhooks Register a webhook DEL /v1/b2b/webhooks/{id} Delete a webhook POST /v1/b2b/payments/checkout Top up the wallet 09Webhooks
Register a public HTTPS endpoint to be notified when your wallet runs low — so you can top up before your users' streams drop.
curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \ -d '{"url":"https://your-app.com/vela-hook","events":["balance.low","balance.empty"]}' \ https://vela.watch/v1/b2b/webhooksEvents:
balance.low(wallet under 1 GB),balance.empty(wallet at zero).Delivery is a signed POST. Verify the
X-Vela-Signature: sha256=<hex>header — it is an HMAC-SHA256 of the raw body using your webhook secret:# payload { "event":"balance.low", "customer_id":"u_abc123", "balance_bytes": 943718400, "balance_gb": 0.94, "ts":"…" }Security: webhook URLs must be public HTTPS — internal/loopback/private addresses are rejected. Always verify the signature before trusting a delivery.10Billing
- Pay-as-you-go, per byte (upstream + downstream both counted), debited atomically from a pre-paid wallet.
- From €10/TB by volume; €5 minimum top-up to start.
- A zero-balance session is refused.
GET /v1/b2b/mereturnsneeds_topup: true— top up via the console or/v1/b2b/payments/checkout.- Non-streaming destinations are refused and never billed.
11Troubleshooting
Symptom Cause / fix SOCKS connection refused immediately Wallet empty (top up) or destination not a streaming host (gateway is streaming-only). 403on RESTWrong account kind (B2C token on a B2B endpoint) or missing token. 401on RESTMissing/expired JWT — re-login. SOCKS auth fails repeatedly Wrong username format or stale API key. Re-copy the credential; rotate the key if leaked. Playback geo-blocked Pin the correct servicetag +countryin the username.Questions an integrator should ask us? Talk to sales · Acceptable Use