Requests & responses
Preview Every managed.dev endpoint speaks JSON
over HTTPS and returns the same predictable envelope. Learn the envelope once and
every resource in the API reads the same way: a data payload, a request_id you
can quote to support, and — for lists — a pagination block.
Base URL
Section titled “Base URL”Every endpoint lives under a single versioned base:
https://api.managed.dev/v1The /v1 prefix is the URL-major version. It only ever changes for a breaking change
to the shape of a request or response; additive changes are pinned with a dated header
instead. See versioning for the full policy.
JSON over HTTPS
Section titled “JSON over HTTPS”The API accepts and returns application/json, exclusively over TLS — plain HTTP
requests are refused, not redirected. Send your credentials in the Authorization
header on every call:
GET /v1/sites HTTP/1.1Host: api.managed.devAuthorization: Bearer mfk_live_9aF2…Accept: application/jsonForge-Version: 2026-06-23Authorization: Bearer …— your API key. See API keys.Accept: application/json— optional; JSON is the only representation.Content-Type: application/json— required on any request with a body (POST,PATCH,PUT).
The Forge-Version header
Section titled “The Forge-Version header”Pin your integration to a dated behavior snapshot by sending the Forge-Version
header with every request:
Forge-Version: 2026-06-23Omit it and you get the latest behavior, which can shift additively under your feet. Pinning is strongly recommended for anything beyond exploration — it is how you keep CI and Terraform runs deterministic. The full model is described in versioning.
The response envelope
Section titled “The response envelope”Every successful response is wrapped in one of two shapes. There is no bare array and
no top-level resource object — data always holds the payload.
Single resource
Section titled “Single resource”A request that addresses one object returns it under data, alongside the
request_id:
{ "data": { "id": "site_01J7…", "name": "acme-marketing", "runtime": "wordpress", "created_at": "2026-06-20T14:02:55.901Z" }, "request_id": "req_01J9…"}Collection
Section titled “Collection”A list endpoint returns an array under data plus a pagination block:
{ "data": [ { "id": "site_01J7…", "name": "acme-marketing", "runtime": "wordpress" }, { "id": "site_01J7…", "name": "acme-docs", "runtime": "static" } ], "pagination": { "next_cursor": "eyJ0…", "has_more": true }, "request_id": "req_01J9…"}next_cursor and has_more drive cursor pagination — the only pagination style the
API uses. See pagination for the loop.
request_id — your support handle
Section titled “request_id — your support handle”Every response, success or error, carries a request_id like req_01J9…. It uniquely
identifies that single call in our logs. Capture it (the SDKs expose it on every
response object) and quote it in any support ticket — it lets us find exactly what
happened without you having to reconstruct the request.
What an error looks like
Section titled “What an error looks like”Errors share the envelope but replace data with an error object:
{ "error": { "type": "not_found", "code": "site.not_found", "message": "site not found", "param": "site_id", "doc_url": "https://docs.managed.dev/reference/error-codes/#site.not_found" }, "request_id": "req_01J9…"}The type maps to the HTTP status; the code is stable and machine-readable. Full
catalog and handling guidance live in errors.