MIDL Write API — manual (MID-77)

The authenticated, headless write API for managing MIDL pages (frames) over HTTP. Pairs with the read/agent surface (MID-52: /.well-known/agent.json, /api/agents/openapi.json, the midl+json alternate, the Facts API). The machine spec is GET /api/agents/openapi.json (OpenAPI 3.1).

Authentication

All write methods require a Bearer API key:

Authorization: Bearer <key>
  • Mint a key in the admin UI (/admin/keys) or POST /api/admin/keys (admin-gated). The plaintext key is shown once — store it; only its hash is kept server-side (MID-75).
  • Rotate = revoke + mint. Revoke via /admin/keys or DELETE /api/admin/keys/:id.
  • The bootstrap ADMIN_TOKEN also authorizes (header x-admin-token, Bearer, or ?token=).
  • Reads (GET /api/frames, /render/<slug>.midl.json, POST /api/validate) are public.

Endpoints

POST /api/frames — create

Body: { content: <MIDL doc>, slug?, description?, is_active? }. The content is validated (validateStudioMIDL) before persisting. → 201 { id, slug }.

curl -X POST https://<site>/api/frames \
  -H "Authorization: Bearer $MIDL_KEY" -H 'Content-Type: application/json' \
  -d '{"slug":"pricing","content":{"midl":"0.1","ns":{"ui":"https://midl.ai/ui#"},"frames":[{"id":"p","type":"ui:Page","children":[]}]}}'

PATCH /api/frames/:id — update

Body: any of { content?, slug?, description?, is_active? } (≥1 field). Supplied content is re-validated. → 200.

DELETE /api/frames/:id — delete

200.

Slugs (MID-76)

Lowercase, url-safe (a-z, 0-9, hyphens), not a reserved word (home, admin, api, render, login, …), and unique. Omit slug to get a generated page-<ts> default.

Errors (sanitized — no raw DB text)

Status Meaning
400 Malformed body, or invalid/reserved slug
401 Missing/invalid API key
404 Frame id not found (PATCH/DELETE)
409 Slug already in use
422 Invalid MIDL document — not persisted

Notes

  • Per-tenant scoping (a key → its own pages) is P2 (MID-78/79); today a valid key is full-admin.
  • Migration 010_api_keys.sql must be applied to the target D1 before keys work there.