MidnightDocumentation

HTTP API

Build automation against explicit contracts.

Midnight's control plane is rooted at /api/v1alpha. Use the OpenAPI document served by the installation you call, authenticate with one declared credential class, and treat asynchronous operations as the source of progress truth.

v1alphaOpenAPI 3.1RFC 9457SSE
On this page

SOURCE OF TRUTH

Generate from the installation, not this website.

Download the current contractbash
curl --fail-with-body   https://your-midnight.example/api/v1alpha/openapi.yaml   --output midnight-openapi.yaml

The marketing site describes the product, while the served contract reflects the exact build installed on your host. Midnight is Railway-inspired, but it is not Railway API-compatible or a drop-in replacement.

AUTHORITY

Use one credential class for its intended routes.

Human session · midn_user_
Dashboard, CLI, and tenant APIs admitted by the user's current workspace and project grants.
Project automation · midn_sa_
Narrow CI deploy/source intake and same-project deployment or operation reads. It cannot manage installation settings.
Runtime agent
A secret bound to one agent ID and only its registration, heartbeat, desired-state, and status routes.
Installation recovery
Explicit break-glass compatibility for installation-wide operator routes; never a substitute for tenant access.

Send accepted bearer credentials as Authorization: Bearer <token>. A token never widens itself or falls back to a different authority class.

FIRST MUTATION

Create a project with a stable retry identity.

Create projectbash
export MIDNIGHT_URL=https://your-midnight.example
export MIDNIGHT_TOKEN=midn_user_...
export REQUEST_KEY=project-payments-v1

curl --fail-with-body   -X POST "$MIDNIGHT_URL/api/v1alpha/projects"   -H "Authorization: Bearer $MIDNIGHT_TOKEN"   -H 'Content-Type: application/json'   -H "Idempotency-Key: $REQUEST_KEY"   --data '{
    "workspace_id": "wrk_example",
    "slug": "payments",
    "display_name": "Payments"
  }'

RETRIES AND CONCURRENCY

Make ambiguous outcomes safe.

Idempotency-Key
A stable opaque identity for one logical mutation. Retry only the same concrete route and exact body with that key.
ETag
The strong version returned by a resource read.
If-Match
Required by compare-and-swap mutations. A stale value returns 412 rather than overwriting newer state.
202 Accepted
Durable asynchronous intake. Follow the returned operation; do not report the action as complete yet.
Compare-and-swap updatebash
# A prior GET returned: ETag: "3"
VARIABLE_REQUEST_KEY=variable-rotation-v4
curl --fail-with-body   -X PATCH "$MIDNIGHT_URL/api/v1alpha/services/$SERVICE_ID/environments/$ENVIRONMENT_ID/variables/$VARIABLE_ID"   -H "Authorization: Bearer $MIDNIGHT_TOKEN"   -H 'Content-Type: application/json'   -H 'If-Match: "3"'   -H "Idempotency-Key: $VARIABLE_REQUEST_KEY"   --data '{"expected_version":3,"value":"<new-value>"}'

ASYNC WORK

Poll or resume the operation stream.

Operation state and SSEbash
curl --fail-with-body   "$MIDNIGHT_URL/api/v1alpha/operations/$OPERATION_ID"   -H "Authorization: Bearer $MIDNIGHT_TOKEN"

curl -N   "$MIDNIGHT_URL/api/v1alpha/operations/$OPERATION_ID/events?after=0&stream=sse"   -H "Authorization: Bearer $MIDNIGHT_TOKEN"
  1. 1

    Persist the operation ID

    It is the stable handle for status, events, logs, cancellation, and support evidence.

  2. 2

    Advance the cursor

    Store the last event sequence and reconnect with after so a dropped stream can resume without pretending the gap did not occur.

  3. 3

    Wait for terminal state

    Only SUCCEEDED proves the operation completed. Then verify the deployment, health, and route resources relevant to the action.

HIGH-VALUE ROUTES

Start with the core resource path.

Featured Midnight API endpoints
MethodPathPurpose
POST/api/v1alpha/auth/sessionsCreate a human session
GET/api/v1alpha/auth/meRead the verified human principal
GET · POST/api/v1alpha/projectsList or create projects
GET · POST/api/v1alpha/environmentsList or create environments
GET · POST/api/v1alpha/servicesList or create services
GET · PUT/api/v1alpha/services/{service_id}/environments/{environment_id}/configRead or replace service configuration
GET · POST/api/v1alpha/services/{service_id}/environments/{environment_id}/variablesList metadata or create a write-only variable
POST/api/v1alpha/services/{id}/deploymentsQueue a digest-pinned image deployment
POST/api/v1alpha/services/{id}/upUpload source and queue a build
GET/api/v1alpha/operations/{id}Read authoritative operation state
GET/api/v1alpha/operations/{id}/eventsRead or stream operation events
GET/api/v1alpha/operations/{id}/logsRead backed operation logs

PROBLEM DETAILS

Branch on code, preserve request_id.

Errors use application/problem+json with a stable machine-readable code, HTTP status, human detail, and request_id. Branch on the code rather than parsing message text.

Precondition failurejson
{
  "type": "https://midnight.dev/docs/errors#PRECONDITION_FAILED",
  "title": "Precondition failed",
  "status": 412,
  "detail": "If-Match does not match the current resource version.",
  "code": "PRECONDITION_FAILED",
  "request_id": "req_example"
}