API surfaces#
Midnight exposes several interfaces. This page says what each is for and which one to build against.
The canonical REST contract#
/api/v1alpha/* is the canonical REST contract. Human dashboard and CLI login
use durable sessions at /api/v1alpha/auth/sessions.
Build against this surface unless you have a specific reason not to.
GraphQL v2#
/graphql/v2 with a GraphiQL playground. Useful for exploration and for
clients that prefer a graph query over several REST calls.
Streams#
Operation event and log streams are delivered over server-sent events. The
dashboard and the CLI --follow commands consume the same feed, so what you
see in one matches the other.
MCP#
A standards-compliant Model Context Protocol server over JSON-RPC 2.0,
protocol revision 2025-06-18, with:
| Property | Detail |
|---|---|
| Manifest | /.well-known/mcp |
| Authentication | Bearer token |
| Rate limiting | Per session |
| Mutation gate | Disallowed mutations are refused |
The MCP server bridges the same tool registry the embedded agent uses. See The embedded agent.
Operator-compatibility OAuth#
A legacy operator-recovery OAuth authorise and token shim exists for compatibility. It is not the path for human dashboard or CLI login, which use durable sessions instead.
Do not build new integrations against the compatibility shim.
Tenant scoping#
Human sessions use tenant-scoped nested routes. The server derives
workspace and project ownership from the session, which is why the CLI refuses
--workspace-id and --project-id on human variable commands.
An integration that wants to pass ownership explicitly is describing a recovery-credential shape, not a human-session shape.
Endpoints that return planning artefacts#
Some _demo and enterprise plan endpoints return planning
artefacts rather than performing a live action. A 200 from one of those is
not evidence that anything was done.
Confirm which shape an endpoint has before treating its response as an effect.
Concurrency and retries#
Mutating endpoints use compare-and-swap with an explicit expected version, and accept an idempotency key. Together these give you a safe retry story: a stale write is refused, and an uncertain retry with the same key does not duplicate.
Error codes#
The project maintains an error-code reference. Use the code rather than the message when branching in a client — messages are for people.
Verify#
curl -sS https://api.example.test/.well-known/mcp
The manifest responds. The GraphiQL playground loads at /graphql/v2.
If it does not work#
| Symptom | Check | Recovery |
|---|---|---|
| A call is refused before any effect | Whether a non-human token was supplied on a human route | Use a human session or the stored recovery credential |
| A write is refused | The expected version | Re-read, then retry with the current version |
| An action appears to succeed but nothing changed | Whether the endpoint returns a planning artefact | Some plan endpoints do not act |
| MCP requests are throttled | Per-session rate limiting | Reduce concurrency |
| An integration breaks after an upgrade | Whether it used the compatibility OAuth shim | Move to durable sessions |