Requests and responses
Base URLs, content types, identifiers, and why a 201 does not mean the machine is running.
Base URL
There is no single one. Every availability zone is its own deployment with its own host, shaped:
https://api.<zone>.interlaken.aiOne zone is live today, eu-par-1 in Paris, so every example here uses
https://api.eu-par-1.interlaken.ai. Substitute the zone you actually mean. The
authoritative list is interlaken.ai/zones.json,
which the console and every orchestrator read at boot; resolve it at runtime rather
than hard-coding a host, and a new zone costs you no release.
A resource lives in exactly one zone and is invisible from the others, so the base URL is part of a resource's identity, not a detail of transport. Availability zones covers what that means in practice.
Every documented route sits under /api/v1, except the OAuth endpoints and the
discovery documents, which live at the root because the standards put them there.
Content types
Send Content-Type: application/json on anything with a body, and expect JSON back.
The two exceptions are the OAuth token and revocation endpoints, which take
application/x-www-form-urlencoded as the specification requires, and the streaming
routes, which are WebSocket or server-sent events.
Identifiers
Resources are identified by UUID. Some also carry a human name, which is not unique
and is not an identifier: always round-trip the id you were given.
Creating something answers with the id:
{ "id": "0f7c1e1e-4f0a-4a9b-9f39-5b7d2c1a0e44" }Shapes
A collection is an envelope:
{ "items": [ … ], "total": 42 }A single resource is the object itself, not wrapped. items is always an array, so
an empty page is [] and never null.
Timestamps are RFC 3339 in UTC. Most resources carry created_at and updated_at.
Creation is intent, not completion
This is the one convention that will bite you if you skip it. The API is intent-based: a write records what you want, answers, and returns. A reconciler then drives the real hardware towards that intent, which takes seconds to minutes depending on what you asked for.
So a 201 from POST /api/v1/vms means the intent is durable, not that a machine is
booting. The resource's status moves through transitional values and settles. Two
ways to follow it:
Poll the resource and watch status. Simple, and fine for scripts.
Subscribe to GET /api/v1/events, a WebSocket stream of changes in your tenant.
Better for anything long-lived, and much better than polling at a second's interval.
The same applies to deletes. A 204 means the teardown is scheduled.
Idempotency
GET, PUT and DELETE are idempotent. POST is not: calling it twice creates two
resources. When a POST times out, look the resource up by name before retrying,
rather than assuming the first call failed.
Rate limits
The sign-in routes are rate limited per client. Everything else is limited generously
enough that normal use will not meet it. A 429 carries retry_after_seconds; wait
that long rather than retrying immediately.
Tags
Most resources accept a tags object of string keys and values, and list endpoints
can filter on it. Tags are the supported way to carry your own metadata, and are
preferable to encoding meaning into names.