HTTP API

mdboard serve exposes the HTML board and a JSON API. The HTML board is the human review/consortium surface; the JSON API is useful for inspection, dashboards and integrations.

Reads are public by default. Writes require a local session and a CSRF token.

Start

mdboard serve --actor owner

The server prints:

mdboard serve: http://127.0.0.1:3000
mdboard auth token (actor `owner`): …
mdboard sign-in: http://127.0.0.1:3000/login.html

Without --actor, write endpoints are disabled and the server is read-only.

Authentication

  1. POST the one-time token to /api/auth/login.
  2. Receive a mdboard_session HttpOnly, SameSite=Strict cookie and a CSRF token.
  3. Send X-CSRF-Token on every write.
  4. The session lasts 8 hours in memory; restarting the server invalidates it.
curl -c cookies.txt -X POST http://127.0.0.1:3000/api/auth/login \
  -H 'content-type: application/json' \
  -d '{"token":"<printed-token>"}'

Response:

{"actor":"owner","role":"owner","roles":["owner"],"csrf":"…"}

The token is one-time. The origin of a write must match the server host.

Endpoints

Method Path Purpose
GET /api/board.json Board summary, roadmap and card list
GET /api/cards/<id> or /api/cards/<id>.json One card with tasks, reviews and cost
GET /api/meetings.json Meeting gates and statuses
GET /api/schema.json Kinds, states, transitions and authority
POST /api/ideas/<id>/accept Consortium accepts a pitch
POST /api/ideas/<id>/reject Consortium rejects a pitch
POST /api/batches/<id>/review Record a review artifact
POST /api/batches/<id>/request-changes Return a handover batch to doing
POST /api/batches/<id>/complete Owner accept and complete
POST /api/meetings/<id>/accept Accept a gate
POST /api/meetings/<id>/defer Defer a gate
POST /api/meetings/<id>/dismiss Dismiss a gate

Actions enforce the same authority as the CLI. Writes require the session cookie and X-CSRF-Token.

Board JSON

{
  "schema": 2,
  "upstream": {"iteration":7,"status":"open","base":"…","writer":"agent"},
  "roadmap":{"count":3,"limit":5,"estimated_cost_eur":0.42},
  "active_batch":"#0009",
  "pending_meetings":["M0009-01"],
  "cards":[
    {"id":"#0009","kind":"batch","state":"doing","title":"CSV export","intent_owner":"owner"}
  ]
}

Card JSON

{
  "card": {
    "id":"#0007",
    "kind":"batch",
    "state":"handover",
    "title":"CSV export",
    "intent_owner":"owner",
    "estimate":{"tokens":{"weighted":12667.0},"agent_hours":{"weighted":1.0}},
    "report":null,
    "blocked_from":null
  },
  "tasks":[{"id":"#0007-01","state":"done"}],
  "reviews":[{"id":"RV-0007-01-01","reviewer":"reviewer","verdict":"accepted"}],
  "estimated_cost_eur":0.0027
}

Meeting JSON

{
  "id":"M-0007-01",
  "kind":"handover-review",
  "status":"pending",
  "trigger":"Batch #0007 entered handover",
  "linked_cards":["#0007"],
  "due":null,
  "questions":[]
}

Static pages

  • / overview
  • /board.html
  • /roadmap.html
  • /cards/<id>.html
  • /meetings.html
  • /login.html
  • /assets/style.css, /assets/process.js

The HTML board is a view. Do not scrape it for automation; use the CLI or JSON API.

Security boundary

This is a local server. It is not a multi-tenant service, has no OIDC or trusted-proxy mode in the alpha, and must not be exposed directly to the internet. See Security.