Skip to content
Hoody.com

A container’s default service URLs embed its project and container IDs, so they work but nobody can remember or type them. A proxy alias gives the same service a second hostname that you choose: my-api.node-us.containers.hoody.com instead of the generated form.

This page covers how aliases are created, what they route to, how they handle paths and expiration, and how they interact with proxy permissions. It follows on from how the Hoody Proxy works.


This page explains alias concepts and usage patterns. The endpoint reference carries the full request and response schemas.

Alias management:

Related:


Spawning a container produces service URLs automatically:

https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com

Those URLs have a fixed set of properties:

  • Created automatically, with nothing to configure
  • Unique per service, built from cryptographic IDs
  • Effectively unguessable, so sharing the URL is what grants access
  • Working for every program the container runs
  • Impossible to type or remember
  • Unsafe to leak: if one is shared accidentally before permissions are configured, anyone holding the URL can reach the service
  • Not brandable, since you cannot put one on a business card

Create an alias and the service gets a hostname you choose:

Terminal window
POST /api/v1/proxy/aliases
{
"container_id": "890abcdef12345678901cdef",
"alias": "my-api",
"program": "http",
"port": 3000
}

Result:

https://my-api.node-us.containers.hoody.com

Both hostnames reach the same container and the same service.


A container running a web server or an API can be reached two ways.

https://67e89abc123def456789abcd-890abcdef12345678901cdef-http-8080.node-us.containers.hoody.com

Problems in production:

  • Exposes project and container IDs (48 characters of sensitive data)
  • Impossible to remember or type
  • Unprofessional for customers and users
  • Cannot go on business cards, marketing material, or documentation
https://my-api.node-us.containers.hoody.com

Benefits:

  • Keeps internal IDs out of the URL you hand out — though some programs still return them in their responses
  • Short enough to remember and type
  • Suited to public APIs and web services
  • Usable as a CNAME target for a custom domain

The name is my-api, not api. A bare api — and anything starting api- — is one of the router-reserved names in Naming rules below: the alias is created, and the hostname never resolves.

Then connect your domain:

api.mycompany.com CNAME my-api.node-us.containers.hoody.com

https://api.mycompany.com then routes to your container, and no ID appears in the URL.

For a web server or API inside a container, use program: "http" with port:

Terminal window
POST /api/v1/proxy/aliases
{
"container_id": "890abcdef12345678901cdef",
"alias": "my-api",
"program": "http", // Routes to container's HTTP service
"port": 3000 // Port your server listens on inside the container
}

That maps to the web server running on the port you named (3000, 8080, 5000, or whatever your process listens on). The proxy then routes https://my-api.node-us.containers.hoody.com to that HTTP service automatically.

Typical production workflow:

  1. Deploy your Node.js, Python, or Go API in a container
  2. Create an alias with program: "http" and your server’s port
  3. Point your domain at the alias
  4. Configure authentication with proxy permissions

Aliases follow this pattern:

https://{alias}.{serverName}.containers.hoody.com
└──┬──┘ └────┬────┘
Your Your Server
Choice (where container runs)

Alias names are unique per physical server, across every tenant hosted on it — and additionally unique within your own account across all servers. The {serverName} component reflects where the container runs, so a name taken on one server can still be created on a different server by a different account; your own account can hold a given name only once, wherever it lives.

Example:

  • Container on node-us → Alias becomes my-app.node-us.containers.hoody.com
  • The name my-app is now taken on node-us (for every tenant on that server) and cannot be claimed again there

An alias points at one program inside a container:

Terminal window
POST /api/v1/proxy/aliases
{
"container_id": "890abcdef12345678901cdef",
"alias": "my-api",
"program": "http", // Which program (use "http"/"https" for web servers)
"port": 3000, // Port your server listens on inside the container
"target_path": "/api/v1", // Optional: landing path for a root request
"allow_path_override": true
}

Common programs: http, https, exec, ssh, terminal, display, code

  • http / https - HTTP/HTTPS servers (use with port to route to a server running inside the container)
  • exec - Exec scripts as APIs
  • ssh - SSH access
  • terminal - Terminal interface
  • display - Desktop environment
  • code - Code editor interface

The program value must be a built-in Hoody program (such as those above) or a transport protocol (http, https, ssh); any other value is rejected.

A container can carry several aliases, pointing at different programs or at the same program with different configurations.


Terminal window
# Create a basic proxy alias for your container
hoody proxy aliases create --container-id $CONTAINER_ID --alias my-app --program http --port 3000
POST Create a basic proxy alias for your container
/api/v1/proxy/aliases
Click "Run" to execute the request

The service is now reachable at:

https://my-app.node-us.containers.hoody.com

Omit the alias parameter and the API generates a name for you:

POST Create alias with auto-generated name (omit alias parameter)
/api/v1/proxy/aliases
Click "Run" to execute the request

The response carries a 48-character hexadecimal alias, auto-generated and unique, for example a3f9b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3.

Valid alias names:

  • 3-61 characters
  • Lowercase letters (a-z)
  • Numbers (0-9)
  • Hyphens (-)
  • Must start with letter or number
  • Must end with letter or number
  • Pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$
  • Reserved: containers (exact label), plus four service names, egress, workspaces, workspace and os, each rejected as the whole label or followed by a hyphen. So os, os-admin and workspace-2 are all refused, while a distinct label that merely shares the opening letters (egressmyapp, ostrich) is fine: the match is on a label boundary, not on any string that starts the same way.
  • Also rejected: names that would impersonate a container URL — anything starting with the {projectId}-{containerId} form (two 24-hex-char labels), or that shape with an egress-/workspaces-/proxy- service prefix.

Valid examples:

  • my-api
  • staging-frontend
  • app-v2
  • prod

Invalid examples:

  • -myapp (starts with hyphen)
  • my_api (underscore not allowed)
  • MY-APP (uppercase not allowed)

api, admin, system and internal are reserved by the reverse proxy on the same label-boundary rule: the bare word and anything starting api-, admin-, system- or internal- is dropped before the router looks the alias up. apiary and administer are distinct labels and route normally.

The create call does not enforce this. POST /api/v1/proxy/aliases with "alias": "api-v1" returns 201 Created with a url field, and that URL then resolves to nothing — no error, no warning, nothing in the response to tell you the hostname is dead. Treat those four words the way you treat egress: never as the whole name, never as the first segment.


Route requests to a specific base path in your container:

POST Create alias with target path routing to /api/v1
/api/v1/proxy/aliases
Click "Run" to execute the request

Routing behavior:

Incoming Request:
https://my-api.node-us.containers.hoody.com/
Routed To Container:
/api/v1
(a root request uses target_path; with allow_path_override true,
other request paths are used as sent, so /users arrives as /users)

allow_path_override decides which paths a visitor can reach through the alias. It applies the same way to the alias hostname and to a custom domain pointed at it.

true (the default) forwards every path as sent. A root request (/) lands on target_path, with the query written in target_path followed by the visitor’s own parameters. A request that carries its own path is forwarded from the container root; target_path is never a prefix.

# allow_path_override: true
https://my-api.node-us.containers.hoody.com/ → /api/v1 (target_path)
https://my-api.node-us.containers.hoody.com/api/v1/users → /api/v1/users (forwarded as sent)
https://my-api.node-us.containers.hoody.com/admin → /admin (forwarded as sent)

false makes the alias serve only the root, or target_path itself. The proxy permissions are checked first; then:

  • a request to /, or to target_path itself, lands on target_path; one trailing slash is accepted, so /api/v1/status and /api/v1/status/ are both served;
  • any other path, sub-paths and assets included, is refused with 404, the error code ALIAS_PATH_PINNED and the message “This alias serves only its root and its target path”;
  • a query parameter written in target_path keeps its value: a visitor’s parameter with the same name is dropped;
  • the instance selectors the proxy sets itself (such as terminal_id, display or id) stay as the proxy set them;
  • the visitor’s method, request body, other query parameters, WebSocket upgrade and Range header are passed on, so a pinned alias can front one API endpoint that takes a POST with a JSON body.
# allow_path_override: false, target_path "/api/v1/status?format=json"
https://status.node-us.containers.hoody.com/ → /api/v1/status?format=json
https://status.node-us.containers.hoody.com/?format=xml → /api/v1/status?format=json (target_path's value wins)
https://status.node-us.containers.hoody.com/?verbose=1 → /api/v1/status?format=json&verbose=1
https://status.node-us.containers.hoody.com/api/v1/status → /api/v1/status?format=json (target_path itself)
https://status.node-us.containers.hoody.com/api/v1/status/ → /api/v1/status?format=json (one trailing slash)
https://status.node-us.containers.hoody.com/api/v1/status/x → 404 ALIAS_PATH_PINNED (sub-path)
https://status.node-us.containers.hoody.com/users → 404 ALIAS_PATH_PINNED

Use false for a link to one fixed page or one fixed API endpoint. An interactive kit (terminal, code, browser, files), an app that loads further assets (CSS, JS, images) and an API with several routes need true: under false every request other than / and target_path answers 404.

The flag limits where the link goes, not who may use it: anyone who has the link can open it. Restrict who may with proxy permissions. Permissions authenticate per program and port and carry no request-path selector, so per-route rules such as /admin/* need a proxy hook or authorization inside your application.

Example: land the bare alias root on your API base path (/api/v1) instead of /, and keep every other route of the API reachable:

Terminal window
POST /api/v1/proxy/aliases
{
"container_id": "890abcdef12345678901cdef",
"alias": "public-api",
"program": "http",
"port": 3000,
"target_path": "/api/v1",
"allow_path_override": true
}

A web app on an http service (http-<port>, or plain http/https) reached through an alias receives the host the visitor typed in Host: the alias hostname, or a custom domain pointed at it. An app that checks Host against an allow-list must list the alias address and every custom domain pointed at it, for example allowedHosts in the Vite or webpack dev server, ALLOWED_HOSTS in Django, an nginx server_name, or a Caddy site address; otherwise it refuses the request. Hoody’s own kits receive their container URL in Host; X-Forwarded-Host always carries the host the visitor typed. See Which Host header does my app receive?.


One container can carry several aliases, one per service:

POST Create alias for HTTP service
/api/v1/proxy/aliases
Click "Run" to execute the request

Result:

https://my-api.node-us.containers.hoody.com → HTTP service
https://my-scripts.node-us.containers.hoody.com → Exec scripts
https://my-terminal.node-us.containers.hoody.com → Terminal

Each hostname reaches a different program in the same container.


Terminal window
# List all aliases
hoody proxy aliases list
# Filter by project
hoody proxy aliases list --project-id $PROJECT_ID
# Filter by container
hoody proxy aliases list --container-id $CONTAINER_ID
# Find expired aliases
hoody proxy aliases list --expired true
GET List all your aliases
/api/v1/proxy/aliases
Click "Run" to execute the request
Terminal window
# Change alias target service
hoody proxy aliases update $ALIAS_ID --program exec --index 2 --target-path /v2
# Update expiration
hoody proxy aliases update $ALIAS_ID --expires-at "2026-12-31T23:59:59Z"
PATCH Change alias target service (replace {id} with actual alias ID)
/api/v1/proxy/aliases/{id}
Click "Run" to execute the request

Disable an alias without deleting its configuration. Disable, enable, update and delete are not instant: they usually reach the alias URL within about 30 seconds and can take longer, and until then the alias keeps its previous behavior.

Terminal window
# Re-enable alias
hoody proxy aliases enable $ALIAS_ID
# Disable alias
hoody proxy aliases disable $ALIAS_ID
PATCH Disable alias (stops routing, keeps configuration)
/api/v1/proxy/aliases/{id}/state
Click "Run" to execute the request

This takes an API offline temporarily for maintenance, without losing the alias configuration.

Terminal window
# Permanently remove alias
hoody proxy aliases delete $ALIAS_ID
DELETE Permanently remove alias (replace {id} with actual alias ID)
/api/v1/proxy/aliases/{id}
Click "Run" to execute the request

The alias name frees up once the deletion reaches the alias URL, usually within about 30 seconds; until then a recreate of the same name can return 409 Conflict, so retry after a short wait. Deletion itself is refused with 409 Conflict while the alias’s container is finalizing a claim — retry once the claim completes.

After you delete an alias, the same name can be claimed by another account. Do not rely on long-lived cookies or credentials on an alias address.


An alias can expire on its own:

POST Create alias with automatic expiration (ISO 8601 timestamp)
/api/v1/proxy/aliases
Click "Run" to execute the request

After expiration:

  • Alias stops routing traffic automatically
  • Returns 404 for all requests
  • Configuration is preserved; clear expires_at and set enabled: true to restore routing.

Expiration formats:

On create (POST), expires_at must be an ISO 8601 string, or null for no expiration. On update (PATCH), the route schema also accepts a numeric Unix timestamp in seconds or milliseconds alongside the ISO string and null. Prefer ISO 8601 everywhere.

{ "expires_at": "2027-07-12T00:00:00.000Z" }
{ "expires_at": "2026-12-31T23:59:59.000Z" }

Use cases:

  • Demo environments - Auto-expire after customer trial
  • Temporary access - Event-specific URLs
  • Staged rollouts - Beta URLs that expire when moving to prod

A permanent alias for an API service:

POST Create permanent production API alias whose root request lands on /api/v1
/api/v1/proxy/aliases
Click "Run" to execute the request

Access:

https://prod-api.node-us.containers.hoody.com/
→ Routes to container's /api/v1
https://prod-api.node-us.containers.hoody.com/users
→ Forwarded as /users (allow_path_override true forwards other paths as sent)

Three aliases on one container, each pointing at a different program:

POST Production HTTP service
/api/v1/proxy/aliases
Click "Run" to execute the request

Result:

https://app.node-us.containers.hoody.com → Web service
https://app-terminal.node-us.containers.hoody.com → Terminal
https://app-scripts.node-us.containers.hoody.com → Exec scripts

Aliases can carry API versions:

POST Current production version
/api/v1/proxy/aliases
Click "Run" to execute the request

Clients can choose:

https://v1-api.node-us.containers.hoody.com → Old version
https://v2-api.node-us.containers.hoody.com → New version
https://beta-api.node-us.containers.hoody.com → Beta (same as v2)

When ready: Delete v1-api, rename v2-api → v1-api, or update client references.

A typical deployment workflow:

Terminal window
# 1. Develop in container with cryptographic URL
https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com
# 2. Create staging alias when ready for testing
POST /api/v1/proxy/aliases
{ "alias": "staging-app", "container_id": "890abcdef12345678901cdef", "program": "http", "port": 3000 }
# → https://staging-app.node-us.containers.hoody.com
# 3. Test with team, clients, QA
# 4. Snapshot tested container
POST /api/v1/containers/890abcdef12345678901cdef/snapshots
{ "alias": "pre-prod-2025-11-09" }
# 5. Create production alias
POST /api/v1/proxy/aliases
{ "alias": "prod-app", "container_id": "890abcdef12345678901cdef", "program": "http", "port": 3000 }
# → https://prod-app.node-us.containers.hoody.com
# 6. If issues, instant rollback via snapshot
# Use data.snapshot.name returned by POST
PUT /api/v1/containers/890abcdef12345678901cdef/snapshots/$SNAPSHOT_NAME

GET Find all aliases for a specific project (replace project_id)
/api/v1/proxy/aliases?project_id=67e89abc123def456789abcd
Click "Run" to execute the request

Update many aliases programmatically:

// Example: Update all staging aliases to a new landing path
const stagingAliases = await fetch(
'https://api.hoody.com/api/v1/proxy/aliases?project_id=67e89abc123def456789abcd',
{ headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` } }
).then(r => r.json());
for (const alias of stagingAliases.data.aliases) {
await fetch(`https://api.hoody.com/api/v1/proxy/aliases/${alias.id}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.HOODY_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
target_path: '/v2'
})
});
}

An alias for program: "exec" hands the whole script tree a short hostname. The path you request is the route:

POST Create exec alias for path-based script routing
/api/v1/proxy/aliases
Click "Run" to execute the request

Scripts in the container:

api/users.ts
api/posts.ts
webhooks/stripe.ts

Access by path:

https://my-scripts.node-us.containers.hoody.com/api/users
→ Executes api/users.ts
https://my-scripts.node-us.containers.hoody.com/webhooks/stripe
→ Executes webhooks/stripe.ts

The alias replaces the hostname; everything after it is the route, exactly as on the generated -exec-1 URL. Combine it with target_path if you want the alias to land somewhere other than the script root.

See: Hoody Exec → for complete script routing documentation.

Target different instances of the same program:

POST Alias to first HTTP service instance
/api/v1/proxy/aliases
Click "Run" to execute the request

Result:

https://frontend.node-us.containers.hoody.com → HTTP service on port 3000
https://backend.node-us.containers.hoody.com → HTTP service on port 8080

An alias is the CNAME target for a custom domain.

Step 1: Create alias

POST Create alias for custom domain CNAME target
/api/v1/proxy/aliases
Click "Run" to execute the request

Step 2: Point your domain to the alias

# DNS configuration at your domain provider
api.mycompany.com CNAME myapp-prod.node-us.containers.hoody.com

Step 3: Automatic SSL

Hoody provisions a Let’s Encrypt certificate for api.mycompany.com automatically. The custom domain serves HTTPS within minutes.

Result:

https://api.mycompany.com
→ CNAME →
https://myapp-prod.node-us.containers.hoody.com
→ Routes to →
Container's HTTP service

See: Connect a Domain → for complete custom domain setup.


Aliases must be unique per physical server, across every tenant hosted on it — and unique within your own account across all servers.

If anyone, including another tenant, has claimed my-app on the same physical server, you cannot use it there. The API returns a 409 Conflict response (Alias is already in use.). On a different server the name is available again to other accounts, but not to yours if you still hold it elsewhere.

Solution: Choose descriptive, unique aliases:

  • Add your company name: acme-api
  • Add identifier: my-app-prod
  • Use generated names when uniqueness is uncertain

Cryptographic URLs (Default)

https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com

Security:

  • Unguessable (2^96 combinations)
  • Share URL = grant access
  • Don’t share = private
  • Suited to development and collaboration

Usability:

  • Impossible to remember
  • Can’t type manually
  • Not brandable

Aliases (Production)

https://my-api.node-us.
containers.hoody.com

Security:

  • Guessable (if known pattern)
  • Discoverable (enumeration possible)
  • IP whitelist recommended
  • Add authentication via permissions

Usability:

  • Memorable
  • Typeable
  • Brandable
  • Professional

Best practice:

  • Development: Use cryptographic URLs (secure by obscurity)
  • Production: Use aliases + permissions (secure by authentication)

Aliases work with proxy permissions:

POST Create public API alias (then configure permissions separately)
/api/v1/proxy/aliases
Click "Run" to execute the request

Then configure permissions on a separate endpoint:

Terminal window
PUT /api/v1/containers/{id}/proxy/permissions
{
"project": "67e89abc123def456789abcd",
"container": "890abcdef12345678901cdef",
"groups": {
"authenticated": {
"type": "jwt",
"secret": "a-long-random-signing-key-with-32-plus-chars",
"algorithm": "HS256",
"sources": ["header:Authorization"]
}
},
"permissions": {
"authenticated": { "http": [3000] }
},
"default": "deny"
}

Both URLs now require authentication:

https://67e89abc123def456789abcd-890abcdef12345678901cdef-http-3000.node-us.containers.hoody.com → Requires JWT
https://public-api.node-us.containers.hoody.com → Requires JWT

The alias and the cryptographic URL apply the same permissions.


A complete workflow from development to production.

1. Develop in container (use the cryptographic URL)

https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com

2. Create staging alias for team testing

POST Create staging alias for team testing
/api/v1/proxy/aliases
Click "Run" to execute the request

Result: https://staging-myapp.node-us.containers.hoody.com

3. Configure staging with IP whitelist (office only)

Terminal window
# Fetch the current permissions document and save its etag
# (the server returns 428 if If-Match is omitted, 412 if it is stale)
CURRENT_ETAG=$(curl -s "https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/permissions" \
-H "Authorization: Bearer $HOODY_TOKEN" | jq -r '.data.etag')
curl -X PUT "https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/permissions" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "If-Match: $CURRENT_ETAG" \
-H "Content-Type: application/json" \
-d '{
"project": "67e89abc123def456789abcd",
"container": "890abcdef12345678901cdef",
"groups": {
"office": { "type": "ip", "range": "203.0.113.0/24" }
},
"permissions": {
"office": { "http": [3000] }
},
"default": "deny"
}'

4. Team tests on staging-myapp.node-us.containers.hoody.com

5. Snapshot when ready

POST Create snapshot before production deployment
/api/v1/containers/{container_id}/snapshots
Click "Run" to execute the request

6. Create production alias

POST Create production alias
/api/v1/proxy/aliases
Click "Run" to execute the request

Result: https://myapp.node-us.containers.hoody.com

7. Point custom domain

DNS: api.mycompany.com CNAME myapp.node-us.containers.hoody.com

Result: https://api.mycompany.com (automatic SSL)

8. Configure production permissions (JWT auth)

Terminal window
# Fetch the current permissions document and save its etag
# (the server returns 428 if If-Match is omitted, 412 if it is stale)
CURRENT_ETAG=$(curl -s "https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/permissions" \
-H "Authorization: Bearer $HOODY_TOKEN" | jq -r '.data.etag')
curl -X PUT "https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/permissions" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "If-Match: $CURRENT_ETAG" \
-H "Content-Type: application/json" \
-d '{
"project": "67e89abc123def456789abcd",
"container": "890abcdef12345678901cdef",
"groups": {
"customers": {
"type": "jwt",
"secret": "production-jwt-secret",
"sources": ["header:Authorization"]
}
},
"permissions": {
"customers": { "http": [3000] }
},
"default": "deny"
}'

9. Production is live

Development: https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com (crypto URL)
Staging: https://staging-myapp.node-us.containers.hoody.com (IP-restricted)
Production: https://api.mycompany.com (JWT auth, custom domain)

After step 8, the full-replacement PUT removes the office group and installs the customers JWT group. Both HTTP aliases require JWT, and the exec URL is denied by the default policy. Use separate containers or different program/port rules when staging and production need different policies.


Can I use the same alias name on different servers?

Section titled “Can I use the same alias name on different servers?”

Not with the same account. Alias names are unique per physical server (across all tenants on it) and unique within your account across all servers — so a different account can reuse a name on a different server, but your own second claim of the same name returns 409 Conflict wherever it is. On the same server a name taken by anyone fails the same way; pick a variant like my-app-eu.

What happens if I delete a container that has aliases?

Section titled “What happens if I delete a container that has aliases?”

Deleting a container also deletes its aliases; their URLs stop resolving shortly after. You do not need to delete aliases first. The names become free again, but an alias cannot be moved to another container: the target is fixed at create time, so reuse means creating a new alias with the same name against the new container.

Yes. Create several aliases with different names, all pointing to the same container_id and program. This is useful for versioning (v1-api and v2-api both pointing to the same container initially) or for multi-brand domains.

Yes. When you configure proxy permissions for a container, they apply to both the cryptographic URL and every alias pointing to that container. One permission configuration covers all entry points.

Can I create an alias before the container is running?

Section titled “Can I create an alias before the container is running?”

Yes. You can create aliases for stopped containers. The alias exists, but requests will fail until you start the container. Useful for pre-configuring production URLs before deployment.

How do target_path and allow_path_override differ?

Section titled “How do target_path and allow_path_override differ?”

target_path supplies the destination for a root request (/), including any query written in it; it is never used as a prefix for other paths. allow_path_override decides what happens to every other path: true (the default) forwards it as sent, false refuses it with 404 ALIAS_PATH_PINNED (apart from target_path itself, which lands on target_path like /) and keeps the parameters written in target_path from being overridden. See Path override. Neither field controls who can open the alias: anyone with the link can. To control who can reach the container, use proxy permissions.

How do I prevent someone from guessing my alias names?

Section titled “How do I prevent someone from guessing my alias names?”

Use long, specific aliases (acme-prod-api-v2-us-2025) instead of generic ones (api, app). Better still, combine the alias with proxy permissions for authentication, so that guessing the name does not grant access.

Can I have an alias without specifying program or index?

Section titled “Can I have an alias without specifying program or index?”

The program is required. For built-in programs, index is optional and defaults to 1, so {"container_id": "…", "program": "terminal"} is a valid alias. For http/https, always supply port (which index is also read as) with the backend’s listening port; omitting it routes to port 1, not port 80 or 443. The program is mandatory because one container runs several services and the alias has to name the one it routes to.

Aliases are stored separately, not in the container. If you snapshot container A with alias my-app, then restore to container B, the alias still points to container A. To route to container B, delete the alias and create a new one targeting container B’s ID (the target container cannot be changed on an existing alias).

Can I see which custom domains point to my aliases?

Section titled “Can I see which custom domains point to my aliases?”

The GET /api/v1/proxy/aliases/{id} endpoint shows alias configuration, but not which custom domains CNAME to it (that’s in your DNS provider). Best practice: document your CNAME mappings externally (spreadsheet, wiki, infrastructure-as-code).


Error:

{
"statusCode": 409,
"error": "Conflict",
"message": "Alias is already in use.",
"data": { "field": "alias", "value": "my-app", "scope": "server" }
}

A scope of "server" means another account already holds the name on this physical server; "account" means your own account already holds it — on any server, including this one, because the check against your own aliases runs first. For an "account" conflict, delete or rename your existing alias to reuse the name.

Solutions:

  1. Choose a different alias name
  2. Use a suffix: my-app-v2, my-app-prod
  3. Check existing aliases across your whole account — the conflict can be your own alias on another project or server: GET /api/v1/proxy/aliases (unfiltered)

Check:

  1. Enabled status: GET /api/v1/proxy/aliases/{id} → Check enabled: true
  2. Container running: GET /api/v1/containers/{id} → Check status: "running"
  3. Service running: Check container’s service is actually started
  4. Permissions: Verify you can access via cryptographic URL first

For custom domains:

  • CNAME changes take 5-60 minutes to propagate globally
  • Test from multiple locations or wait before troubleshooting
  • Use dig api.mycompany.com to verify DNS points to alias

When you create an alias, the original cryptographic URL still works:

Alias:
https://my-api.node-us.containers.hoody.com
Original (still works):
https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.com

Both route to the same container service, under the same permissions.

Use case:

  • Share aliases publicly (clean URLs)
  • Keep cryptographic URLs for internal tools (unguessable security)

  1. Connect a Domain → - Point your custom domain to an alias
  2. Set Permissions → - Add authentication to protect aliases

Summary of this page:

  • Aliases create short URLs of the form my-app.{serverName}.containers.hoody.com
  • They map to specific container programs (http, exec, terminal, and the rest)
  • They support path routing and access control
  • They serve as CNAME targets for custom domains
  • They can be temporary (expiration) or permanent