Network Configuration
Section titled “Network Configuration”This page covers outbound traffic: where your container’s connections exit to the internet. You route them through a SOCKS5, HTTP, or HTTPS proxy, or block them entirely. The route is applied on the host, so nothing inside the container is configured.
API endpoints summary
Section titled “API endpoints summary”Complete endpoint documentation:
- GET /api/v1/containers/{id}/network - Get current network config
- PATCH /api/v1/containers/{id}/network - Configure proxy/VPN/block mode
- DELETE /api/v1/containers/{id}/network - Remove config (restore default)
- POST /api/v1/containers/{id}/network/start - Start container network proxy/blocking
- POST /api/v1/containers/{id}/network/stop - Stop container network proxy/blocking
Two different proxies on Hoody
Section titled “Two different proxies on Hoody”Hoody uses the word proxy for two systems that work in opposite directions:
| System | Direction | Purpose |
|---|---|---|
| Hoody Proxy | Internet → Container | Makes services accessible via URLs |
| Network Configuration (this page) | Container → Internet | Changes exit IP address |
Hoody Proxy is how other people reach your containers, inbound. Network Configuration is how your container reaches the internet, outbound. The two run alongside each other: the proxy handles inbound service requests, network configuration handles outbound connections.
Four routing types
Section titled “Four routing types”A new or changed update configures the route and starts it in the same call; the response reports status: "running". Repeating an unchanged configuration keeps the route’s current state and can answer configured without starting it, so use network start to bring a stopped route back. network stop disables the configured route or block policy without deleting it, and network start switches it back on. The dns_servers field is accepted for compatibility but not applied: containers resolve names through the host’s resolver, and the API reports ["1.1.1.1", "8.8.8.8"] whatever you send.
SOCKS5 proxy (recommended)
Section titled “SOCKS5 proxy (recommended)”Routes all TCP traffic through the SOCKS5 upstream:
# Route all container traffic through SOCKS5 proxyhoody network update --container $CONTAINER_ID \ --type socks5 \ --proxy "socks5://username:password@proxy.example.com:1080"await client.api.network.update(CONTAINER_ID, { type: 'socks5', proxy: 'socks5://username:password@proxy.example.com:1080',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "socks5", "proxy": "socks5://username:password@proxy.example.com:1080" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Saves the SOCKS5 route, replacing any existing network configuration; the route is running when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"socks5","proxy":"socks5://username:password@proxy.example.com:1080"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
What happens:
- All container TCP connections route through the SOCKS5 proxy
- The container appears to originate from the proxy’s IP
- Authentication is supported (username:password)
Rules for the proxy address (all three types):
- Write it as
scheme://[username:password@]host:port. The scheme may be left out (typesupplies it); if you write one, it must matchtype. A mismatch such assocks5://…withtype: "http"is refused with400. - The port is required: a plain number from 80 to 65535, with no leading zero.
- The host is a hostname or a plain IPv4 address such as
203.0.113.10; IPv6 addresses and other number forms (0x…, leading zeros) are refused. - The username may contain only letters, digits,
_and-; the password may also contain:. - Anything after the port (a path,
?queryor#fragment) is dropped. - To change only the address, send it without credentials: the saved username and password are kept when the scheme, host and port stay the same, and dropped when any of them changes.
Why SOCKS5 is recommended:
- It forwards any TCP protocol natively, without
CONNECTtunneling - SSH, databases, Git, and custom protocols all work
- Many providers, including VPN services, offer SOCKS5 with credentials
- Nothing inside the container needs configuring
HTTP proxy
Section titled “HTTP proxy”# Route container traffic through HTTP proxyhoody network update --container $CONTAINER_ID \ --type http \ --proxy "http://user:pass@corporate-proxy.com:8080"await client.api.network.update(CONTAINER_ID, { type: 'http', proxy: 'http://user:pass@corporate-proxy.com:8080',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "http", "proxy": "http://user:pass@corporate-proxy.com:8080" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Saves the HTTP proxy route, replacing any existing network configuration; the route is running when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"http","proxy":"http://user:pass@corporate-proxy.com:8080"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Use for: Corporate proxy requirements, environments that mandate an HTTP forward proxy
Note: type: http configures the upstream as an HTTP proxy. Hoody still DNATs all container TCP egress through it, using the proxy’s CONNECT tunneling for non-HTTP destinations, so this is not limited to plain HTTP payloads. SOCKS5 remains the most broadly compatible upstream.
HTTPS proxy
Section titled “HTTPS proxy”# Route container traffic through HTTPS proxyhoody network update --container $CONTAINER_ID \ --type https \ --proxy "https://user:pass@secure-proxy.com:443"await client.api.network.update(CONTAINER_ID, { type: 'https', proxy: 'https://user:pass@secure-proxy.com:443',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "https", "proxy": "https://user:pass@secure-proxy.com:443" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Saves the HTTPS proxy route, replacing any existing network configuration; the route is running when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"https","proxy":"https://user:pass@secure-proxy.com:443"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Use for: Encrypted HTTP proxy connections
Note: type: https configures the upstream as an HTTPS proxy (CONNECT tunneling); all TCP egress is DNATed through it just as with the http type, so this is not restricted to HTTPS payloads.
Block (no outbound traffic)
Section titled “Block (no outbound traffic)”# Block all outbound internet traffichoody network update --container $CONTAINER_ID --type blockawait client.api.network.update(CONTAINER_ID, { type: 'block',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "block"}'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Applies the block policy: all outbound internet for the container is off when the call returns. Route it through a different container’s curl-1, because the block cuts the target container’s egress, so the call cannot be served by the container it blocks.
# Configure and start
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"block"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Block mode blocks all outbound internet. The container can still:
- Be accessed via Hoody Proxy URLs (terminal, files, display)
- Access localhost services and /ramdisk
It cannot make any outbound internet connections.
Use block mode for a workload that has no business talking to the internet. Outbound access is off as soon as the block configuration is applied; network stop switches it back on and network start switches it off again.
Host-level routing
Section titled “Host-level routing”Without it, each application carries its own proxy setting:
export HTTP_PROXY=http://proxy:8080npm config set proxy http://proxy:8080git config http.proxy http://proxy:8080# Every single application needs its own settingOn Hoody, one update call covers every application in the container:
# Configure SOCKS5 proxy for all container traffichoody network update --container $CONTAINER_ID \ --type socks5 \ --proxy "socks5://user:pass@proxy.example.com:1080"await client.api.network.update(CONTAINER_ID, { type: 'socks5', proxy: 'socks5://user:pass@proxy.example.com:1080',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "socks5", "proxy": "socks5://user:pass@proxy.example.com:1080" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
One call saves the SOCKS5 route for every application in the container, with nothing configured inside; the route is running when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"socks5","proxy":"socks5://user:pass@proxy.example.com:1080"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Every application then routes through SOCKS5: npm downloads, curl requests, Python/Node.js/Go apps, SSH connections, and database connections. None of them carry a proxy setting.
What that gives you:
- Universal routing, covering every TCP protocol
- No application-level configuration
- Tamper-proof routing, since the container cannot bypass it
- Easy VPN provider switching
Use cases
Section titled “Use cases”Change the exit IP for a geo-restricted API
Section titled “Change the exit IP for a geo-restricted API”Your server is in Germany, but the API requires a US IP:
# Route through US proxy for geo-restricted APIshoody network update --container $CONTAINER_ID \ --type socks5 \ --proxy "socks5://user:pass@us-proxy.example.com:1080"await client.api.network.update(CONTAINER_ID, { type: 'socks5', proxy: 'socks5://user:pass@us-proxy.example.com:1080',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "socks5", "proxy": "socks5://user:pass@us-proxy.example.com:1080" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Applies the US proxy route; the container’s exit IP switches to the proxy’s location when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"socks5","proxy":"socks5://user:pass@us-proxy.example.com:1080"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Requests from the container now appear to originate from the proxy’s location.
Route through a corporate proxy
Section titled “Route through a corporate proxy”# Route through corporate HTTP proxy for compliancehoody network update --container $CONTAINER_ID \ --type http \ --proxy "http://employee:pass@corporate-proxy.com:8080"await client.api.network.update(CONTAINER_ID, { type: 'http', proxy: 'http://employee:pass@corporate-proxy.com:8080',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "http", "proxy": "http://employee:pass@corporate-proxy.com:8080" }'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Saves the corporate HTTP proxy route for compliance logging; the route is running when the call returns.
# Configure and start
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"http","proxy":"http://employee:pass@corporate-proxy.com:8080"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
All HTTP traffic is logged by the corporate proxy for compliance.
Restrict an AI workload’s outbound network access
Section titled “Restrict an AI workload’s outbound network access”# Block all outbound traffic for AI sandboxhoody network update --container $CONTAINER_ID --type blockawait client.api.network.update(CONTAINER_ID, { type: 'block',});curl -X PATCH "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "block"}'One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Applies a block policy so a compromised AI workload cannot reach the internet directly (DNS to the host resolver stays open). Route it through a different container’s curl-1, because the block cuts the target container’s egress, so the call cannot be served by the container it blocks.
# Configure and start
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=PATCH&bearer_token=TOKEN&json={"type":"block"}&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
In block mode, AI-generated code cannot:
- Call external APIs
- Download packages
- Open outbound connections of its own
DNS queries still reach the host resolver, which the block rules leave open, so this is not a guarantee against every exfiltration channel.
Test from several regions at once
Section titled “Test from several regions at once”Spawn containers with different exit IPs and run the same request from each:
A PATCH that changes the configuration replaces the previous route and starts the new one; there is no separate activation step. A PATCH that repeats the current configuration keeps the route’s current state, so use network start to bring a stopped route back.
Layering network, firewall, and permissions
Section titled “Layering network, firewall, and permissions”Three layers control traffic, and they stack.
Step 1: Route through the VPN:
A successful PATCH applies the VPN route as soon as it returns.
Step 2: Block the rest of the TCP range. Drops are evaluated before allows, so the drop has to leave out port 443 rather than cover 1-65535:
Result: traffic routes through the VPN, and the firewall permits only HTTPS among TCP traffic; add separate UDP and ICMPv4 deny rules if those protocols must also be blocked.
The three layers:
| Layer | Controls | Page |
|---|---|---|
| Network Config | Exit IP routing (outbound) | This page |
| Firewall | Packet filtering (ingress/egress) | Firewall → |
| Proxy Permissions | HTTP service access (inbound) | Permissions → |
Inside the container there is an optional fourth layer. An optional program sandbox restricts one daemon program. Under network.mode: restricted Landlock limits the TCP ports it may bind and connect to, for every destination including loopback and the platform address, but not UDP or destination hosts, and refuses MPTCP, io_uring and TCP Fast Open sends so those limits cannot be bypassed; mode: none removes its external networking, UDP included, while Unix sockets reachable by path stay reachable. Setting network.udp: "deny" stops the program from creating UDP sockets under any mode. Separately, its ingress rules filter IPv4 TCP arriving on eth0 at its declared ports. By default those rules let packets whose source is loopback or the gateway through, which covers callers inside the container and the platform’s own calls from the gateway. A public request forwarded by the proxy keeps the client’s own address, and one another container sends to the program’s public URL arrives from the server’s address, so both are filtered.
Use all three together to control exit routing, packet filtering, and HTTP service access.
Manage an existing configuration
Section titled “Manage an existing configuration”Get the current config
Section titled “Get the current config”# View current network configurationhoody network get --container $CONTAINER_IDconst config = await client.api.network.get(CONTAINER_ID);console.log(config.data); // { type, proxy, dns_servers, status, remote_status }curl "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN"One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Returns the container’s current network configuration.
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=GET&bearer_token=TOKEN&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Remove the config and restore the default
Section titled “Remove the config and restore the default”# Remove network config, restore direct connectionhoody network delete --container $CONTAINER_ID --yesawait client.api.network.delete(CONTAINER_ID);curl -X DELETE "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network" \ -H "Authorization: Bearer $TOKEN"One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Removes the network configuration and restores the container’s direct connection. Route it through a different container’s curl-1 — if the current config is what’s broken, the target’s own egress can’t serve this link either.
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network&method=DELETE&bearer_token=TOKEN&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Start or stop the network proxy
Section titled “Start or stop the network proxy”# Start network proxy/blockinghoody network start --container $CONTAINER_ID
# Stop network proxy/blockinghoody network stop --container $CONTAINER_ID --yes// Start network proxy/blockingawait client.api.network.start(CONTAINER_ID);
// Stop network proxy/blockingawait client.api.network.stop(CONTAINER_ID);# Start network proxy/blockingcurl -X POST "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network/start" \ -H "Authorization: Bearer $TOKEN"
# Stop network proxy/blockingcurl -X POST "https://api.hoody.com/api/v1/containers/$CONTAINER_ID/network/stop" \ -H "Authorization: Bearer $TOKEN"One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Starts or stops the configured route or block policy without deleting it. Route them through a different container’s curl-1 — stopping a block or a dead proxy is exactly when the target’s own egress can’t serve the link.
# Start
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network/start&method=POST&bearer_token=TOKEN&response=transparent
# Stop
https://PROJECT_ID-OTHER_CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://api.hoody.com/api/v1/containers/CONTAINER_ID/network/stop&method=POST&bearer_token=TOKEN&response=transparent The link carries a credential and executes with it, so it is as sensitive as the credential itself — and it passes through the cURL service's request log on the way, not just the target's. Share it only where you would share the secret, and prefer a delegated token with minimal permissions and an expiry: see API tokens.
Verify the exit IP
Section titled “Verify the exit IP”From inside the container:
# Via hoody-terminalcurl ifconfig.me
# Should show VPN IP, not server IPBest practices
Section titled “Best practices”Use SOCKS5 for universal routing
Section titled “Use SOCKS5 for universal routing”Hoody DNATs all container TCP egress regardless of proxy type, but a SOCKS5 upstream natively forwards any TCP protocol (SSH, databases, custom protocols) without relying on CONNECT tunneling. Use SOCKS5 unless your environment specifically requires an HTTP/HTTPS forward proxy.
Test the config before production
Section titled “Test the config before production”Test in a dev container first:
Verify the exit IP with curl ifconfig.me from inside the container, test app connectivity, then apply the same configuration to production.
Write a descriptive route comment
Section titled “Write a descriptive route comment”# Good comment{"comment": "UK VPN for BBC API - geo-restricted content"}
# Vague comment{"comment": "vpn"}Combine routing with firewall rules
Section titled “Combine routing with firewall rules”Route through the VPN, then restrict the allowed destinations with firewall rules.
Useful questions
Section titled “Useful questions”Does Network Configuration affect container service URLs?
Section titled “Does Network Configuration affect container service URLs?”No. Hoody Proxy service URLs (terminal, files, display) remain accessible. Network Configuration only affects outbound connections from the container.
What happens if the SOCKS5 proxy goes down?
Section titled “What happens if the SOCKS5 proxy goes down?”The container cannot make outbound connections. Update the config with a different proxy, or call DELETE /network to revert to a direct connection.
Can I use multiple proxies simultaneously?
Section titled “Can I use multiple proxies simultaneously?”Network Configuration takes one proxy per container. For multi-hop, configure the first SOCKS5 through Network Configuration and run a second SOCKS5 client inside the container. You can also spawn multiple containers, each with a different proxy.
Does this work with WireGuard or OpenVPN?
Section titled “Does this work with WireGuard or OpenVPN?”Not yet. Network Configuration currently supports SOCKS5, HTTP, and HTTPS proxy routing only. WireGuard routing is planned for a future update. Many VPN providers offer SOCKS5 endpoints as an alternative.
For a real WireGuard tunnel, run the client inside the container instead. That path is yours to configure, and it comes with rules of its own. See VPN Inside a Container →.
Do changes require a container restart?
Section titled “Do changes require a container restart?”No. Changes apply immediately to new connections. Existing connections may continue using the old route.
Can containers communicate with each other in block mode?
Section titled “Can containers communicate with each other in block mode?”No. Block mode blackholes all new outbound TCP from the container, including connections to other containers’ service URLs, which resolve to public addresses. The blocked container itself stays reachable from outside via its own service URLs; it just can’t dial out. If two containers need to talk while one is blocked, have the unblocked one initiate the connection.
Troubleshooting
Section titled “Troubleshooting”No internet access after configuring the VPN
Section titled “No internet access after configuring the VPN”Solutions:
- Verify the network service is running:
GET /containers/{id}/network→ check"status": "running" - Test proxy from host:
curl --proxy socks5://user:pass@vpn.com:1080 https://ifconfig.me - Check proxy URL format:
socks5://username:password@host:port - Remove config and test direct:
DELETE /containers/{id}/network
DNS resolution fails
Section titled “DNS resolution fails”Solutions:
-
Custom DNS is not the fix: the
dns_serversfield is accepted but not applied, and containers resolve through the host’s resolver whatever you send. If resolution fails only with a route active, check the route end to end: that the proxy or VPN endpoint is reachable and answering (test it from outside the container), that the container’s firewall lets DNS out, and that the route’s own resolver works. -
Ensure the firewall allows DNS:
Proxy authentication fails
Section titled “Proxy authentication fails”Check:
- The credentials are correct
- The username uses only letters, digits,
_and-, and the password only those plus:(other characters are refused) - The VPN subscription is active
- Test from your own computer:
curl --proxy socks5://user:pass@vpn.com:1080 https://ifconfig.me
Exit IP not changing
Section titled “Exit IP not changing”Verify:
- The network service is running:
GET /network→ checkremote_status.is_runningistrue(orstatusisrunning) - Test from container:
curl ifconfig.me(should show proxy IP, not server IP) - Check DNS leaks:
curl -4 ifconfig.me(force IPv4)
What’s next
Section titled “What’s next”Complete networking setup:
- Firewall → - Granular traffic rules
- VPN Inside a Container → - Run a WireGuard tunnel inside the container
- SSH Access → - Secure shell and SFTP
- IPv4 Management → - Dedicated IPs (coming soon)
What this page covered:
- Network Configuration controls outbound traffic and the exit IP
- Hoody Proxy controls inbound traffic and service URLs
- SOCKS5 routes any TCP protocol, which makes it the most versatile upstream
- Routing is applied on the host, so containers need no configuration
- Block mode drops outbound traffic except DNS to the host resolver