# Dispatch: a MAJR Agent Service > Turns a raw development log (commit subjects + merged PR titles) into customer-facing > release-notes Markdown. Drafting only: distribution and human approval stay with the caller. > Privacy: request/response bodies are never persisted — the service logs counts, not content. Auth: every `/v1/*` call needs `Authorization: Bearer ` (keys are per product, under your account). Errors: RFC 7807 `application/problem+json`; your request content is never echoed back. A `401` means the key is wrong. A `403` with `code: insufficient_service_scope` means the key is VALID but not scoped for `dispatch` — do not rotate it and do not retry here: use a key whose scopes include `dispatch`. The body's `granted_scopes` lists where that key does work, `required_scope` names this service, and `WWW-Authenticate: Bearer error="insufficient_scope", scope="dispatch"` carries the same signal. ## Contract - `POST /v1/draft-dispatch` — `{changes, product?, voice?, model?, render_target?}` -> `{markdown, no_news}` - `no_news: true` with `markdown: ""` means nothing user-facing shipped; the sentinel is collapsed server-side so never string-match for it yourself. - `voice`: persona/tone only — your account's brand-voice floor is composed beneath it server-side; you style on top of the floor, you can't replace it. - `render_target`: `embedded_fragment` (default — no headings; you own the page chrome) or `standalone_document` (headings allowed — the notes are the whole document). - `model`: optional override; must be on the service allowlist or the call is rejected (400). - `GET /v1/voice` — your account's brand-voice floor (+ its sha), for drafting other copy that should sound like your account. - `GET /v1/usage` — your metered usage: month-to-date + lifetime drafts and token counts. - `GET /healthz` — liveness, unauthenticated. - Machine-readable spec: `GET /openapi.json` (interactive: `/docs`). ## MCP (Model Context Protocol) Standard MCP over Streamable HTTP at `https://dispatch.majr.app/mcp` — any MCP client works; same bearer key as `/v1`. Tools: `draft_dispatch`, `get_usage`, `get_voice`. Connect — example, Claude Code's CLI; the registration command is your client's, not ours: claude mcp add --transport http dispatch https://dispatch.majr.app/mcp \ --header "Authorization: Bearer $KEY" ## Quickstart curl -X POST https://dispatch.majr.app/v1/draft-dispatch \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"changes": "- add CSV export\n- fix crash when login token expires"}' ## Fleet This is one of the MAJR Agent Services. Machine-readable service catalog: https://dispatch.majr.app/catalog.json