Menu
Platform
AI
App store purchases
Database
Flags
Jobs and cron
Localization
Monitoring
Notifications
Payments
Queues
Sandboxes
Webhooks
Getting Started
Authentication
KV Store
Deploy & Infrastructure
Reference
Routes
The address a request arrives on, the backend it reaches, and how the two stay unambiguous
Today this runs on the management API
A hostname is attached to a service with POST /v1/projects/{id}/domains/{domain_id}/hostnames (hostname, serviceId); see the Network quickstart. The routes collection is not served at api.sylphx.com.
A Route sends one exact host and path prefix to one backend. It is the whole of the platform's request routing: there is no implicit fallback, no precedence between Routes, and no Route that covers a name you did not write down.
#The address is exact
host is one hostname. A wildcard grants no authority, so a Route for
shop.example.com says nothing about www.shop.example.com — every host that
serves traffic has its own Route, and its own line in the spec. The host must be
a verified Domain or a subdomain of one, which is what
keeps one project from claiming another's name.
path_prefix is the second half of the address, and it defaults to /. A
prefix of /api takes /api and everything under it; the rest of the host
needs its own Route or nothing at all.
| Field | Type | What it is |
|---|---|---|
host | stringrequired | The exact host: a verified Domain or a subdomain of one. |
path_prefix | string | The path prefix; default /. |
service | string | A Hosting Service. One of the backend group. |
redirect | RouteRedirect | A redirect, with a target_uri and a status code. The other member of the backend group. |
A Route carries exactly one backend: either a Service or a redirect, never both.
sylphx network routes create \
--parent orgs/acme/projects/shop/envs/production \
--spec.host shop.example.com \
--spec.service shopA redirect backend answers the same address without a workload behind it:
target_uri is the absolute URL to send the caller to, and status_code is
301, 302, 307 or 308, defaulting to 308.
#Overlap is refused
Two Routes may not claim the same host and path prefix. The refusal is at creation, not at request time: a Route that would overlap an existing one is rejected, so the address a request takes is never a matter of which Route was written first. That is also why a wildcard grants no authority — a wildcard is the one Route that would make every other Route's answer ambiguous.
#A Route belongs to an environment
A Route lives under an environment, at
orgs/{org}/projects/{project}/envs/{env}/routes/{route}. The same host in
production and in staging is two Routes, and pointing one at another Service is
a change in one environment only.
#What changing one does
Creating, updating or deleting a Route answers an Operation: the call returns before the change is everywhere, and the Operation settles when it is. The Route is your desired state, which means a change is a complete statement of what should be true — the previous backend is replaced, not merged.
The edge's own view is on the Route, in status.edge:
| Field | Type | What it is |
|---|---|---|
hostname_state | EdgeState | Whether the edge accepts the hostname. One of pending, active, error. |
tls_state | EdgeState | Whether the edge serves TLS for the hostname. One of pending, active, error. |
So the sequence for a hostname is visible rather than guessed: the Route exists,
the edge picks up the hostname, and TLS follows. A Route that is not yet live
reads pending there, and a hostname the edge cannot use reads error — both
while the Route's own spec stays exactly what you wrote.
Deleting a Route is destructive, so the CLI asks before it runs, and the API
takes an etag that must match the current one.