Networking

Preview — pending review

This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.

Create router

POST
/scopes/{scopeId}/network/routers

Creates a virtual router in the active scope. Inputs: name, region (defaults to the active scope's region), externalNetwork (omitted: the platform picks an allowed external network; null: an internal-only router with no gateway), snatEnabled (SNAT is always on for a gateway; false with a gateway is refused), ha (not available to projects, see the field) and routes (must be omitted or empty). On acceptance the router becomes discoverable in the scoped list in a transitional state, and attaching an external gateway enables north-south traffic for connected subnets. Validation: name must match ^[a-z0-9-]{1,63}$ (lowercase letters, numbers, hyphens, max 63 chars) and be unique within the project → 422 VALIDATION_FAILED on format violation; externalNetwork, when supplied, must reference an existing network flagged as external in the scope → 404 NOT_FOUND on unknown reference, 422 if the network is not external; routes must be omitted or empty (a new router has no interface a nexthop could be reached through) → 422 VALIDATION_FAILED otherwise; snatEnabled: false on a router that gets a gateway → 422 VALIDATION_FAILED; per-scope router quota is enforced → 409 QUOTA_EXCEEDED when exhausted. Async & state: Asynchronous — returns 202 with the Router resource in its initial BUILD state (status: BUILD); the control plane provisions the router (ha: true ends in ERROR with FORBIDDEN) and emits resource.updated SSE frames with kind: network.router patching status to terminal ACTIVE on success or ERROR on provisioning failure. Errors: 401 unauthenticated; 403 caller lacks contributor/owner/admin rights to create network resources; 404 referenced external network does not exist in scope; 409 QUOTA_EXCEEDED when the router quota for the scope is exhausted; 422 invalid name, malformed route CIDR/next-hop, or non-external gateway network; 500 internal provisioning fault. Idempotency/Concurrency: Idempotency-Key is required; replaying the same key returns the original 202 response with the same router id instead of provisioning a duplicate router.

Authorization

bearerToken
headerAuthorizationBearer <token>

An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.

Path Parameters

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

Header Parameters

Idempotency-Key*string

Required: this operation creates a new resource asynchronously, so a retry without the key would create a second one. Same key+body within 24h replays the original result; the same key with a different body is 409 CONFLICT. Keys are unique per tenant (the same key in two tenants is two different requests). An API token or service-account (bearer) caller MUST send it -- a request without it is refused with 400 IDEMPOTENCY_KEY_REQUIRED (ErrIdempotencyKeyRequired); reuse the same key on every retry of one logical request. A console session gets one from the edge.

Formatuuid

Request Body

application/json
  1. body

Payload for creating a router.

name*string

Router name. Lowercase letters, numbers and hyphens, up to 63 chars.

Match^[a-z0-9-]{1,63}$
region?string

Region of the router. Read-only in the UI; defaults to the active scope's region.

Match^[a-z][a-z0-9-]{1,39}$
ha?boolean

Not available to projects: a highly-available router needs cloud-administrator rights. true is accepted (202), then the create fails with FORBIDDEN and the router ends in ERROR. Leave it unset or false.

Defaultfalse
externalNetwork?|

Name of the external network to attach as gateway. Omitted (or blank): the platform picks an allowed external network for the scope. Explicit null: an internal-only router with no gateway and no internet egress.

snatEnabled?boolean

SNAT on the external gateway. Only true can be honoured (disabling SNAT is an admin-only Neutron policy): false together with a gateway is refused 422 VALIDATION_FAILED (field snatEnabled) -- use externalNetwork null for a router without egress. Ignored when no gateway is set.

Defaulttrue
routes?array<>

Must be omitted or empty. A static route's nexthop has to be reachable through a subnet attached to the router, and a router being created has no interfaces yet, so a non-empty list is rejected with 422 VALIDATION_FAILED before anything is created. Add routes with POST /network/routers/{routerId}/routes once an interface is attached.

Response Body

Router creation accepted; the resource is returned in its transitional BUILD state.

application/json
  1. response

Virtual router connecting subnets and reaching external networks.

origin?string

Where the resource was made -- portal for a create on the console, api for an object made straight against the OpenStack API (CLI, Terraform, the Kubernetes cloud provider) that discovery adopted. Informational; nothing behaves differently. Absent from a backend that predates it, which means portal.

Value in"portal""api""system""imported"
id*string

Router identifier.

name*string

Router name (lowercase letters, numbers, hyphens; max 63 chars).

status*NetworkStatus

Lifecycle status shared by networking resources.

Value in"ACTIVE""DOWN""BUILD""ERROR"
statusReason*|

Human-readable reason the last lifecycle command on this router failed (e.g. the Neutron message of a refused create or gateway attach); null once a later command settles the router healthy, or when nothing failed. Mirrors VirtualNetwork.statusReason. A router whose create failed after the Neutron router already existed shows the provider's real status, gateway, interfaces and routes, with the failure explained here.

statusReasonCode*|

Machine-readable companion to statusReason: a small, OPEN vocabulary of codes the console can branch on without parsing the human text, deliberately a plain string rather than a closed enum so a code the client does not recognize yet degrades to the generic failure message. Today the only value is cancelled: the resource is in its failure state because its create operation was CANCELLED; a provider object the create had already built may be left in place, and the resource's DELETE removes it. Reported only while the resource is in that failure state; null otherwise.

adminStateUp*boolean

Administrative state of the router.

ha*boolean

High availability (active/standby pair) enabled.

distributed*boolean

Distributed virtual router (DVR) mode.

externalGateway*|null

External gateway attachment, or null when the router is internal-only.

interfaces*array<>

Internal interfaces attached to the router.

routes*array<>

Static routes configured on the router.

createdAt*string

Creation timestamp (ISO 8601).

Formatdate-time
curl -X POST "https://example.com/scopes/string/network/routers" \  -H "Idempotency-Key: 497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Content-Type: application/json" \  -d '{    "name": "string"  }'
{  "origin": "portal",  "id": "string",  "name": "string",  "status": "ACTIVE",  "statusReason": "string",  "statusReasonCode": "string",  "adminStateUp": true,  "ha": true,  "distributed": true,  "externalGateway": {    "externalNetwork": "string",    "externalIp": "string",    "snatEnabled": true  },  "interfaces": [    {      "id": "string",      "subnet": "string",      "network": "string",      "fixedIp": "string",      "status": "ACTIVE",      "platformManaged": true    }  ],  "routes": [    {      "id": "string",      "destination": "string",      "nexthop": "string"    }  ],  "createdAt": "2019-08-24T14:15:22Z"}