marginalia public API

Public read + chat REST API for marginalia, the memory-graph chat agent operated by Polycode Limited. 50 operations under /api: async one-turn chat with task polling, an OpenAI-shaped mechanical completion shim, memory-graph listing, session search and history, insights, projects, usage and budget, and key-authed private-graph provisioning. OpenAPI 3.0.3 served at https://marginalia.polycode.co.uk/api/openapi.json.

Operations 50

GET /api/graphs/default Resolve the current default graph id. #
GET /api/graphs List memory graphs (past + current). `?all=1` bypasses the margin cap. #
POST /api/graphs (Tier-1) Create a private graph (archived-from-birth, owner-only, cap 16). Returns the one-time API key. #
GET /api/status Deployment status: caps, default graph, bedrock_enabled, mode, version. #
GET /api/usage Bedrock usage drill-down for a scope. #
GET /api/usage/all Every LLM call or web search in a calendar month. #
GET /api/budget Today + month-to-date spend vs caps, plus Tavily credits. #
GET /api/diverts The graph's standing mechanical auto-diverts (Reflex) + today's avoided-turn ROI. #
GET /api/graph/{graphId}/activity Recent synth turns for a graph. #
GET /api/graph/{graphId}/session/{sessionUuid}/history Turn history for a session. #
GET /api/graph/{graphId}/session/{sessionUuid}/meta Session meta (introduction, searchability). #
GET /api/graph/{graphId}/insights Latest hourly insights for a graph. #
GET /api/graph/{graphId}/daily-summary Latest daily typed-edge prose summary (markdown) for a graph. #
GET /api/graph/{graphId}/entities Extracted OWL types view: domain classes, object properties, and individuals. #
POST /api/graph/{graphId}/insights/refresh Regenerate a graph's insights now; returns the fresh snapshot. #
GET /api/graph/{graphId}/turn/{turnId} A single turn by id. #
GET /api/sessions Full-text search across session introductions. #
GET /api/sessions/log Combined visitor + socials message log: per-session channel, shortened ids, created time, message count. #
GET /api/visitor/{visitorId} Pseudonymous visitor meta (label, creation time). #
GET /api/projects List a graph's projects (default: the current graph). #
GET /api/projects/{projectId} Project detail: file map, log, suggestions. #
GET /api/projects/{projectId}/file Read a project file by relpath. #
POST /api/project/{projectId}/op (Admin for the shared graph; owner for a private graph) Project lifecycle op: { action: "reopen"|"conclude"|"archive"|"delete", note? }. #
GET /api/openapi.json This OpenAPI document. #
POST /api/chat Async one-turn chat: returns 202 + a task id; poll /api/chat/result. sessionUuid is optional — minted and returned when omitted (reuse it to keep conversation context). #
POST /api/v1/chat/completions OpenAI-shaped MECHANICAL completion shim: { messages } → grammar Formulate → SPARQL Solve → template Render. Token-free (usage all 0); the `marginalia` block carries the receipt (s #
GET /api/chat/result Poll an async chat task: working | completed (with reply) | failed. #
POST /api/keys (Tier-1, logged-in) Provision a private graph + mint an API key (shown once). Send { action: "delete", hash } to delete one of your own keys. #
GET /api/keys (Tier-1) List the caller's private graphs + their API-key metadata (hash, issued_at, last-4 suffix; never plaintext). #
GET /api/keys/whoami (X-API-Key) Which graph does this key resolve to? Key-authed self-discovery: { graph_id, issued_by, suffix }. Never echoes the key. #
POST /api/test/seed Prime behaviour-test fixtures into the sandbox graph (sandbox-only). #
POST /api/flag Flag a memory node for operator review. #
POST /api/visitor/{visitorId}/label Set a visitor's screened, unverified label. #
POST /api/graph/{graphId}/session/{sessionUuid}/introduction Set a visitor's session introduction. #
POST /api/graph/{graphId}/export Export a graph (stub). #
POST /api/graphs/{graphId}/repo (Owner of a private graph; admin for a public graph) Bind the graph to a source repo: { repo_owner, repo_slug, repo_url?, default_branch?, intent_path?, license?, summary_branch?, #
GET /api/graph/{graphId}/summary (Owner/admin/X-API-Key) Build the compact screened showcase seed (summary.json shape) from the live graph — top-N degree-ranked summaries + themes + provenance. #
POST /api/graphs/default/clear (Tier-1) Clear the caller's per-user default graph (revert to the shared graph). #
POST /api/me/default-graph (Tier-1+) Set the caller's default graph: { graphId } — a private graph you own, or the shared default. Keyed A2A/chat requests that name no graph land here. #
POST /api/graphs/{graphId}/delete (Owner) Delete a private graph + its tree, keys, and default pointer. #
POST /api/graphs/{graphId}/label (Owner of a private graph; admin for any graph) Rename a graph (single-token, screened). #
POST /api/graphs/{graphId}/default (Owner) Set this private graph as the caller's login default. #
GET /api/graphs/{graphId}/prompt-note (Owner of a private graph; admin for a public graph) Read the graph's free-text prompt note. #
POST /api/graphs/{graphId}/prompt-note (Owner of a private graph; admin for a public graph) Set { note } — free text (max 2000 chars, guardrail-screened) injected into the graph's system prompt. Empty note clears it. #
POST /api/admin/work-item (Admin) Create or comment on a GitLab work item: { action: "create", title, description, labels? } or { action: "comment", iid, body }. REST mirror of the work_item_* chat tools. #
POST /api/admin/turn (Admin) Trigger an autonomous turn now: { graphId? } — async-invokes the turn lambda with force (bypasses the cadence gate); graphId targets one graph, else the default. #
POST /api/admin/delivery (Admin) GitLab delivery-loop action: { action: assign | mr_review | mr_comment | mr_comment_assign | mr_merge | mr_close | pipeline_status | issue_close, iid?, ... }. REST mirror o #
POST /api/hooks/gitlab/{graphId} (Connector secret) GitLab webhook receiver for a bound supervisor graph — X-Gitlab-Token constant-time-validated against the binding; kept events are shaped and queued for ingest. #
POST /api/hooks/github/{graphId} (GitHub HMAC) GitHub webhook receiver for a bound graph — X-Hub-Signature-256 constant-time-verified against the org webhook secret in SSM (/marginalia/{env}/github-webhook-secret) #
POST /api/hooks/push (X-API-Key) Generic collector: batched { messages: [{ label, body, source_refs?, actor? }] } shaped and queued into the key's bound graph (plain-git history, CI pushes). #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/marginalia-public-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

polycode-co-uk-marginalia-openapi.json Raw ↑
{"openapi":"3.0.3","info":{"title":"marginalia public API","version":"0.1.7","description":"Public read + chat API for marginalia (https://marginalia.polycode.co.uk). No auth today; the API is public. Generated from route-descriptors.mjs.","license":{"name":"AGPL-3.0-only"}},"servers":[{"url":"https://marginalia.polycode.co.uk","description":"production"},{"url":"https://ci-{slug}.marginalia.polycode.co.uk","description":"CI branch","variables":{"slug":{"default":"main"}}}],"paths":{"/api/graphs/default":{"get":{"operationId":"getDefaultGraph","summary":"Resolve the current default graph id.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/graphs":{"get":{"operationId":"listGraphs","summary":"List memory graphs (past + current). `?all=1` bypasses the margin cap.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"all","in":"query","required":false,"schema":{"type":"string"}}]},"post":{"operationId":"createPrivateGraph","summary":"(Tier-1) Create a private graph (archived-from-birth, owner-only, cap 16). Returns the one-time API key.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/status":{"get":{"operationId":"getStatus","summary":"Deployment status: caps, default graph, bedrock_enabled, mode, version.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/usage":{"get":{"operationId":"getUsage","summary":"Bedrock usage drill-down for a scope.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string"}},{"name":"scopeId","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/usage/all":{"get":{"operationId":"getUsageAll","summary":"Every LLM call or web search in a calendar month.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string"}},{"name":"month","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/budget":{"get":{"operationId":"getBudget","summary":"Today + month-to-date spend vs caps, plus Tavily credits.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sessionUuid","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/diverts":{"get":{"operationId":"getDiverts","summary":"The graph's standing mechanical auto-diverts (Reflex) + today's avoided-turn ROI.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/graph/{graphId}/activity":{"get":{"operationId":"getActivity","summary":"Recent synth turns for a graph.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/session/{sessionUuid}/history":{"get":{"operationId":"getSessionHistory","summary":"Turn history for a session.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}},{"name":"sessionUuid","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/session/{sessionUuid}/meta":{"get":{"operationId":"getSessionMeta","summary":"Session meta (introduction, searchability).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}},{"name":"sessionUuid","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/insights":{"get":{"operationId":"getInsights","summary":"Latest hourly insights for a graph.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/daily-summary":{"get":{"operationId":"getDailySummary","summary":"Latest daily typed-edge prose summary (markdown) for a graph.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/entities":{"get":{"operationId":"getEntities","summary":"Extracted OWL types view: domain classes, object properties, and individuals.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graph/{graphId}/insights/refresh":{"post":{"operationId":"refreshInsights","summary":"Regenerate a graph's insights now; returns the fresh snapshot.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graph/{graphId}/turn/{turnId}":{"get":{"operationId":"getTurn","summary":"A single turn by id.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}},{"name":"turnId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/sessions":{"get":{"operationId":"getSessionsSearch","summary":"Full-text search across session introductions.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/sessions/log":{"get":{"operationId":"getSessionsLog","summary":"Combined visitor + socials message log: per-session channel, shortened ids, created time, message count.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graph","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/visitor/{visitorId}":{"get":{"operationId":"getVisitor","summary":"Pseudonymous visitor meta (label, creation time).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"visitorId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/projects":{"get":{"operationId":"getProjects","summary":"List a graph's projects (default: the current graph).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graph","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/projects/{projectId}":{"get":{"operationId":"getProjectDetail","summary":"Project detail: file map, log, suggestions.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/projects/{projectId}/file":{"get":{"operationId":"getProjectFile","summary":"Read a project file by relpath.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}},{"name":"relpath","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/project/{projectId}/op":{"post":{"operationId":"postProjectOp","summary":"(Admin for the shared graph; owner for a private graph) Project lifecycle op: { action: \"reopen\"|\"conclude\"|\"archive\"|\"delete\", note? }.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/openapi.json":{"get":{"operationId":"getOpenapi","summary":"This OpenAPI document.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/chat":{"post":{"operationId":"postChat","summary":"Async one-turn chat: returns 202 + a task id; poll /api/chat/result. sessionUuid is optional — minted and returned when omitted (reuse it to keep conversation context).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userMessage"],"properties":{"graphId":{"type":"string","description":"Target graph id; omit for the default graph."},"sessionUuid":{"type":"string"},"userMessage":{"type":"string"},"volatile":{"type":"boolean","default":false},"visitorId":{"type":"string","description":"Optional pseudonymous visitor id."}}}}}}}},"/api/v1/chat/completions":{"post":{"operationId":"postMechanicalCompletion","summary":"OpenAI-shaped MECHANICAL completion shim: { messages } → grammar Formulate → SPARQL Solve → template Render. Token-free (usage all 0); the `marginalia` block carries the receipt (sparql, sources) or a stated miss. graphId via X-API-Key else the shared default.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/chat/result":{"get":{"operationId":"getChatResult","summary":"Poll an async chat task: working | completed (with reply) | failed.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"task","in":"query","required":false,"schema":{"type":"string"}}]}},"/api/keys":{"post":{"operationId":"postKeys","summary":"(Tier-1, logged-in) Provision a private graph + mint an API key (shown once). Send { action: \"delete\", hash } to delete one of your own keys.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}},"get":{"operationId":"getKeys","summary":"(Tier-1) List the caller's private graphs + their API-key metadata (hash, issued_at, last-4 suffix; never plaintext).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/keys/whoami":{"get":{"operationId":"whoamiKey","summary":"(X-API-Key) Which graph does this key resolve to? Key-authed self-discovery: { graph_id, issued_by, suffix }. Never echoes the key.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/test/seed":{"post":{"operationId":"postTestSeed","summary":"Prime behaviour-test fixtures into the sandbox graph (sandbox-only).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/flag":{"post":{"operationId":"postFlag","summary":"Flag a memory node for operator review.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string"},"reason":{"type":"string"},"note":{"type":"string"}}}}}}}},"/api/visitor/{visitorId}/label":{"post":{"operationId":"postVisitorLabel","summary":"Set a visitor's screened, unverified label.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"visitorId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["label"],"properties":{"label":{"type":"string"}}}}}}}},"/api/graph/{graphId}/session/{sessionUuid}/introduction":{"post":{"operationId":"postSessionIntroduction","summary":"Set a visitor's session introduction.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}},{"name":"sessionUuid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"introduction":{"type":"string"},"searchable":{"type":"boolean"}}}}}}}},"/api/graph/{graphId}/export":{"post":{"operationId":"postExport","summary":"Export a graph (stub).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graphs/{graphId}/repo":{"post":{"operationId":"setRepo","summary":"(Owner of a private graph; admin for a public graph) Bind the graph to a source repo: { repo_owner, repo_slug, repo_url?, default_branch?, intent_path?, license?, summary_branch?, summary_path?, agent_config? }. Mirrors onto graph meta for the showcase + the Phase-18 scoper.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graph/{graphId}/summary":{"get":{"operationId":"getRepoSummary","summary":"(Owner/admin/X-API-Key) Build the compact screened showcase seed (summary.json shape) from the live graph — top-N degree-ranked summaries + themes + provenance.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/graphs/default/clear":{"post":{"operationId":"clearUserDefault","summary":"(Tier-1) Clear the caller's per-user default graph (revert to the shared graph).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/me/default-graph":{"post":{"operationId":"setMyDefaultGraph","summary":"(Tier-1+) Set the caller's default graph: { graphId } — a private graph you own, or the shared default. Keyed A2A/chat requests that name no graph land here.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graphs/{graphId}/delete":{"post":{"operationId":"deletePrivateGraph","summary":"(Owner) Delete a private graph + its tree, keys, and default pointer.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graphs/{graphId}/label":{"post":{"operationId":"renamePrivateGraph","summary":"(Owner of a private graph; admin for any graph) Rename a graph (single-token, screened).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graphs/{graphId}/default":{"post":{"operationId":"setUserDefault","summary":"(Owner) Set this private graph as the caller's login default.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/graphs/{graphId}/prompt-note":{"get":{"operationId":"getPromptNote","summary":"(Owner of a private graph; admin for a public graph) Read the graph's free-text prompt note.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}]},"post":{"operationId":"setPromptNote","summary":"(Owner of a private graph; admin for a public graph) Set { note } — free text (max 2000 chars, guardrail-screened) injected into the graph's system prompt. Empty note clears it.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/admin/work-item":{"post":{"operationId":"postWorkItem","summary":"(Admin) Create or comment on a GitLab work item: { action: \"create\", title, description, labels? } or { action: \"comment\", iid, body }. REST mirror of the work_item_* chat tools.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/admin/turn":{"post":{"operationId":"postAdminTurn","summary":"(Admin) Trigger an autonomous turn now: { graphId? } — async-invokes the turn lambda with force (bypasses the cadence gate); graphId targets one graph, else the default.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/admin/delivery":{"post":{"operationId":"postDelivery","summary":"(Admin) GitLab delivery-loop action: { action: assign | mr_review | mr_comment | mr_comment_assign | mr_merge | mr_close | pipeline_status | issue_close, iid?, ... }. REST mirror of the delivery chat tools — the admin acts as themself (no caps/footer/merge-policy gate).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/hooks/gitlab/{graphId}":{"post":{"operationId":"postGitlabHook","summary":"(Connector secret) GitLab webhook receiver for a bound supervisor graph — X-Gitlab-Token constant-time-validated against the binding; kept events are shaped and queued for ingest.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/hooks/github/{graphId}":{"post":{"operationId":"postGithubHook","summary":"(GitHub HMAC) GitHub webhook receiver for a bound graph — X-Hub-Signature-256 constant-time-verified against the org webhook secret in SSM (/marginalia/{env}/github-webhook-secret); kept events (push/PR/issues/comment/discussion/release) shaped and queued for ingest. 401 on bad signature or an unbound graph.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"parameters":[{"name":"graphId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/api/hooks/push":{"post":{"operationId":"postHooksPush","summary":"(X-API-Key) Generic collector: batched { messages: [{ label, body, source_refs?, actor? }] } shaped and queued into the key's bound graph (plain-git history, CI pushes).","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Bad request"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}}}}