VELA/ CONSOLE
Self-service signup. Top up your wallet to start streaming via Vela's residential pool — no free credit on registration.

Overview

Account status & current period
Your wallet is empty — add credit to activate your sandbox and start streaming. Top up now →
This period
GB
— flows · 30d
Plan
Network
● UK ONLY

Last 7 days

DAILY

By service (30d)

By country (30d)

CountryGBFlows

Usage

Last 30 days of metered traffic

Daily breakdown

DayCountryServiceGBFlows

Tunnel credentials

Point Firefox, Chrome or your streaming app at this SOCKS5 endpoint.

Generate credential

Generate returns the credential currently active on your account (same password every time — safe to call after a reload). Rotate revokes the existing password and mints a new one. Use it the moment you suspect the password has leaked. Anything currently connected with the old password will be dropped within 30 seconds.

The password is your account secret — never share or paste it in screenshots.

Billing

Top up your wallet via card, Apple Pay, Google Pay, SEPA or crypto.

Top up

Payments

DateProviderPurposeAmountCreditStatus

Developer docs

Wire your scraper, bot, or streaming integration into Vela. Tap a section to expand.
1 · Endpoints

Two proxy frontends, both authenticated with the same SOCKS5-style username + password from the Tunnel credentials tab.

ProtocolEndpointNotes
SOCKS5gateway.vela.watch:1080TCP + UDP ASSOCIATE
2 · Username format

The username embeds your account ID, a sticky session ID, the country you want to egress through, and (optionally) the streaming service. Same session = same residential exit IP. The binding lasts until you explicitly rotate or discard it — there is no fixed expiry while traffic keeps flowing (see § 6 for the exact lifetime rules).

vela-{customer_id}-session-{session_id}-country-{cc}[-service-{svc}]

# Examples
vela-u_abc123-session-s_0001-country-uk
vela-u_abc123-session-s_0001-country-uk-service-bbc
vela-u_abc123-session-s_0001-country-it-service-netflix
3 · curl / Firefox / bots

Drop-in usage. Replace USER / PASS with the values from the Tunnel credentials tab.

# curl via SOCKS5
curl --proxy "socks5h://USER:PASS@gateway.vela.watch:1080" https://www.bbc.co.uk/iplayer

# Python (requests)
import requests
proxies = { "https": "socks5h://USER:PASS@gateway.vela.watch:1080" }
r = requests.get("https://www.bbc.co.uk/iplayer", proxies=proxies, timeout=30)

# Firefox / Chrome → Network settings → Manual proxy → SOCKS v5
# Host: gateway.vela.watch   Port: 1080   Auth: USER / PASS
4 · Streaming allowlist

Only branded streaming hostnames pass the gateway policy. Everything else is rejected (and not billed). Request additions from support.

ServiceCountryService tag
Netflix UKUKnetflix
Prime Video UKUKprime
BBC iPlayerUKbbc
ITVXUKitvx
Channel 4UKc4
Sky / NOWUKsky
Disney+ UKUKdisney
Paramount+UKparamount
Apple TV+UKappletv
DAZN UKUKdazn
5 · Account API

REST API at the same origin as this dashboard. All endpoints are authenticated with your JWT or HTTP Basic + API key.

MethodPathPurpose
GET/v1/b2b/meAccount + wallet snapshot
GET/v1/b2b/usageDaily metered usage
GET/v1/b2b/usage/timeseriesHourly time series for charts
GET/v1/b2b/usage/by-country30-day usage by country
GET/v1/b2b/usage/by-service30-day usage by streaming service
GET/v1/b2b/sessionsLive + recent sticky sessions
GET/v1/b2b/proxy/assignedYour currently-bound residential exits (see § 6 / 8)
POST/v1/b2b/proxy/rotateFree the sticky binding so the next request lands on a fresh node
POST/v1/b2b/proxy/discardSame as rotate plus blacklist the previous node for your account
POST/v1/b2b/proxy/blacklist/clearWipe your discard list
GET/v1/b2b/api-keysList your active API keys
POST/v1/b2b/api-keysMint a new API key
DELETE/v1/b2b/api-keys/{id}Revoke an API key
POST/v1/b2b/payments/checkoutStart a top-up
GET/v1/b2b/tunnel-credentialCached SOCKS5 secret (idempotent)
GET/v1/b2b/tunnel-credential?rotate=1Force a fresh secret (use after a leak)
6 · Sticky session behaviour — what actually pins you to an IP

The session token in the SOCKS5 username is a stable opaque string you control. Pick one per logical "user" or "scrape job" and reuse it for as long as you want the same exit IP. The gateway pins (customer, session, country, service) → one residential node and keeps that binding alive under the following rules:

EventBinding survives?Detail
Your SOCKS5 client opens and closes TCP connections normallyYesSOCKS5 is per-request — every new request re-authenticates with the same username, hits the same sticky key, same node.
You keep using the same session for hours / daysYesEvery flow refreshes the binding's idle timer (rolling window).
You go idle (no traffic at all)Yes up to 7 days idleHard ceiling: the binding key has a 7-day idle TTL so abandoned sessions eventually free their slot. Configurable via STICKY_TTL_SECONDS at the gateway. Active traffic resets this — it only matters when you stop sending requests.
You call POST /v1/b2b/proxy/rotateNo — by your requestBinding deleted. Next request picks a fresh node from the country pool. Previous node remains available to come back on a future re-roll.
You call POST /v1/b2b/proxy/discardNo — by your requestBinding deleted and the previous node is blacklisted for your account. Use after detecting a bad IP (banned by destination, slow, etc.).
The residential node goes unhealthy or is removedNo — by usBinding cleared automatically, next request re-picks. Should be rare.

What this means in practice: there is no hidden 30-minute or 1-hour expiry. The gateway will keep sending you out the same residential IP indefinitely as long as you keep using the same session and the upstream stays healthy. The only ways the IP changes are: (1) you call rotate/discard, (2) the node disappears server-side, or (3) you stop sending traffic for more than 7 days. Rotating IPs has a cost — destinations see a new TLS + cookie handshake and many treat that as a re-login, so don't rotate inside an active video stream.

7 · IP selection & rotation — how it works step by step

Each request you send through the gateway is mapped to one residential exit IP by the following deterministic pipeline. Understanding this is the difference between a working scraper and a banned account.

┌─ STEP 1 ─ Username parse ──────────────────────────────────────┐
│ The gateway splits your username on the wire:                  │
│   vela-{customer}-session-{session}-country-{cc}-service-{svc} │
│   ↑           ↑                ↑              ↑                │
│   identity    stickiness key   pool filter    optional filter  │
└────────────────────────────────────────────────────────────────┘

┌─ STEP 2 ─ Sticky lookup (Redis) ───────────────────────────────┐
│ Key:   sticky:{customer}:{session}:{country}:{service}         │
│ If hit → reuse the SAME upstream IP from last time.            │
│ Idle TTL refreshes on every flow (rolling, default 7 days).    │
│ Active traffic = effectively no expiry.                        │
└────────────────────────────────────────────────────────────────┘

┌─ STEP 3 ─ Pool selection (cache miss only) ────────────────────┐
│ Filter the residential pool down to nodes where:               │
│   node.country == requested country, AND                       │
│   node.healthy == true, AND                                    │
│   (no -service- given OR node.capabilities contains it)        │
│ Hash-pick deterministically: hash(customer+session) % len(pool)│
│ → Same session always lands on the same node while it exists.  │
└────────────────────────────────────────────────────────────────┘

┌─ STEP 4 ─ Persist + dial ──────────────────────────────────────┐
│ Write the choice back to Redis with sticky TTL.                │
│ Dial the destination through that node (SOCKS5 or HTTP CONNECT)│
│ Tunnel the bytes, meter both directions, decrement wallet.     │
└────────────────────────────────────────────────────────────────┘

Choosing the right pattern

GoalWhat to doEffect
Persist one identity (Netflix login, DRM session)Keep session constant across all requestsSame exit IP for the whole job. DRM stays happy.
Rotate IP every request (defeat rate-limits)Randomise session per request (UUID v4)Each call hits a different residential node from the country pool.
Parallel scrapers, independent IPsOne session per worker, kept stable inside itN workers → up to N distinct exits, each one sticky.
Force a fresh IP mid-jobCall POST /v1/b2b/proxy/rotate (keeps session stable) OR change the session suffix onceBoth clear the binding and trigger a new pool pick. The old node is not blacklisted unless you call /discard.
Country switchChange countryDifferent country pool. Different exit IP, different geo.

Important: rotating IPs has a cost. A new sticky session triggers a fresh TLS + cookie handshake at the destination, and many streaming services interpret it as a suspicious re-login. Don't rotate inside a video stream — only between scrape jobs.

8 · Session control — rotate, discard, list assigned IPs

Three endpoints let you take direct control of which residential exit your session lands on. Pool-wide listing is never exposed — you only ever see the IPs you've actually been routed through.

MethodPathEffect
GET/v1/b2b/proxy/assignedLists your currently-bound sticky exits (session, country, exit IP, node_ref). Blacklist size only — never the IDs.
POST/v1/b2b/proxy/rotateBody {session, country, service?}. Frees the binding, next request picks a fresh node from the country pool. Previous node can come back.
POST/v1/b2b/proxy/discardBody {session, country, service?}. Same as rotate plus blacklists the previous node so it never comes back for your account. Max 64 entries, 30-day TTL.
POST/v1/b2b/proxy/blacklist/clearWipes your discard list. Use when the pool has shrunk past usefulness.

What you see vs what stays hidden

FieldExposed?Why
exit_ip✓ for your own bindingsYour destination saw it already. No new info leaked.
node_ref✓ opaque hashStable per-customer so you recognise "same exit, different session". HMAC of (your customer id, internal node id) — useless to anyone else.
Internal node idPool identifiers stay private.
Unused pool membersYou only see what you've been routed through. The catalogue stays hidden.
Discarded node ids✗ — count onlyCardinality lets the UI render a badge without listing the contents.
# list current assignments
curl -H "Authorization: Bearer $JWT" https://vela.watch/v1/b2b/proxy/assigned

# rotate (same session keeps working, lands on a new IP)
curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \
  -d '{"session":"scrape-001","country":"UK"}' \
  https://vela.watch/v1/b2b/proxy/rotate

# discard the bad IP, blacklist it for this account
curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \
  -d '{"session":"scrape-001","country":"UK"}' \
  https://vela.watch/v1/b2b/proxy/discard

Lifetime, exactly: the binding has no fixed expiry. It survives every TCP connect/disconnect cycle of your SOCKS5 client and every minute of active traffic. The only timer is a 7-day idle TTL — i.e. if you send no traffic at all for 7 consecutive days the binding rolls off. Active traffic resets that timer on every flow. So in practice: you keep the same IP until you call /rotate, /discard, or stop using the session entirely. Override the default 7-day idle ceiling at the deployment level with STICKY_TTL_SECONDS.

9 · SOCKS5 ATYP — --socks5 vs --socks5-hostname

Our policy filter inspects the destination hostname, not the post-DNS IP. SOCKS5 supports two address types: ATYP=1 (IPv4) and ATYP=3 (domain). Pick the right one or every request gets denied even with valid credentials.

Client settingWhat the gateway seesResult
curl --socks5 USER:PASS@host:1080ATYP=1 IPv4 (client did local DNS)Denied — gateway can't match an IP to the streaming allowlist.
curl --socks5-hostname USER:PASS@host:1080ATYP=3 domain stringAllowed if the host suffix matches the allowlist.
socks5h:// URL scheme (Python requests, Go)ATYP=3 domain stringAllowed — same as --socks5-hostname.
socks5:// URL schemeImplementation-dependent (usually ATYP=1)Likely denied. Use socks5h:// instead.

Why we enforce ATYP=3: a hostname is the only thing we can match against the streaming allowlist without trusting the client's DNS. If we accepted ATYP=1 we'd have to do a reverse-DNS or re-resolution — both lossy, both spoofable. Sending the hostname through the proxy also means DNS itself egresses through the upstream node, not your machine — important if you don't want your home ISP seeing every streaming query.

# Correct
curl --socks5-hostname USER:PASS@gateway.vela.watch:1080 https://www.netflix.com/
curl --proxy socks5h://USER:PASS@gateway.vela.watch:1080 https://www.bbc.co.uk/iplayer

# Wrong — denied
curl --socks5 USER:PASS@gateway.vela.watch:1080 https://www.netflix.com/
curl --proxy socks5://USER:PASS@gateway.vela.watch:1080 https://www.bbc.co.uk/iplayer