{"openapi":"3.1.0","info":{"title":"DocuMemory Capture API","description":"Turn a chat discussion into permanent, searchable engineering documentation. Call captureChat when a conversation reaches a real conclusion — a decision between alternatives, a working fix after debugging, or a setup procedure worth repeating. Call captureChat with doc_type MEMORY instead when the lasting value is standing context rather than an event: architecture rules, constraints, conventions, config facts, domain knowledge, or preferences the developer stated. A memory answers \"what is true about this system\" and comes back with a snippet built to paste into another model's system prompt. Call searchDocs to recall what has already been decided before proposing something new.","version":"1.0.0"},"servers":[{"url":"https://staging.documemory.dev"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/attachments":{"post":{"operationId":"uploadAttachment","summary":"Upload a private attachment","description":"Upload actual user-supplied bytes (base64, up to 3 MB). Supported: static images, PDF, UTF-8 text, Markdown, CSV, JSON, ZIP and Office files. Include the returned markdown in a document. Never invent file contents. For binary clients, send raw bytes with X-Filename instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filename","content_base64"],"properties":{"filename":{"type":"string","maxLength":180},"content_base64":{"type":"string","maxLength":4194304,"contentEncoding":"base64"}}}}}},"responses":{"201":{"description":"Private attachment with id, url and markdown"},"402":{"description":"Paid subscription required"},"413":{"description":"File or storage limit exceeded"}}},"get":{"operationId":"listAttachments","summary":"List private attachment metadata","responses":{"200":{"description":"Up to 100 recent uploads"}}}},"/api/v1/attachments/{id}":{"get":{"operationId":"readAttachment","summary":"Download an owned private attachment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File bytes"},"404":{"description":"Attachment not found"}}}},"/api/v1/actions/capture":{"post":{"operationId":"captureChat","summary":"Save a chat discussion as structured documentation","description":"Distils raw discussion text into a document with a problem statement, the decision reached, the final code, and tags — then saves it. Pass the discussion verbatim in `content`; do not summarise it first, because the server does its own extraction and needs the original text to tell final code from abandoned attempts.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureRequest"}}}},"responses":{"201":{"description":"Document created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureResponse"}}}},"401":{"description":"Missing or invalid API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/search":{"get":{"operationId":"searchDocs","summary":"Search existing documentation","description":"Hybrid semantic and keyword search over the workspace's documentation. Use this before recommending an approach, so prior decisions are reused rather than contradicted.","parameters":[{"name":"query","in":"query","required":true,"description":"What to recall, as a topic or question, e.g. 'how do we rotate auth tokens'.","schema":{"type":"string"}},{"name":"doc_type","in":"query","required":false,"description":"Restrict results to one document type.","schema":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":10}}],"responses":{"200":{"description":"Ranked search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"401":{"description":"Missing or invalid API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/documents":{"post":{"operationId":"createDoc","summary":"Write a document directly","description":"Store Markdown you compose yourself, with no distillation pass. Use this when asked to author a document ('write a setup guide for Docker'). Use captureChat instead when the material is an existing discussion to be distilled.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDocumentRequest"}}}},"responses":{"201":{"description":"Document created","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/Document"}}}}}},"401":{"description":"Missing or invalid API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listDocs","summary":"List documents, newest first","description":"Browse the workspace. Prefer searchDocs when looking for something specific.","parameters":[{"name":"doc_type","in":"query","required":false,"schema":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]}},{"name":"tag","in":"query","required":false,"description":"Only documents carrying this tag.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":20}}],"responses":{"200":{"description":"Documents","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}}}}}}}},"/api/v1/projects":{"get":{"operationId":"listProjects","summary":"List the projects you can access","description":"Projects in the token's workspace that you can read, each with your access level: VIEWER can read, EDITOR can also save documents, MANAGER can also change access. In an organization, call this before captureChat or createDoc to choose a project you can write to.","responses":{"200":{"description":"Projects and your access to each","content":{"application/json":{"schema":{"type":"object","properties":{"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["PERSONAL","TEAM"]}}},"projects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"documentCount":{"type":"integer"},"access":{"type":"string","enum":["VIEWER","EDITOR","MANAGER"]}}}}}}}}}}}},"/api/v1/documents/enhance":{"post":{"operationId":"enhanceDoc","summary":"Format rough notes as clean Markdown","description":"Reformats notes into tidy Markdown for the given document type. Formatting only - it never adds, removes, or changes technical meaning, and it writes nothing to the workspace. Pair it with createDoc when the source material is messy.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["raw_text"],"properties":{"raw_text":{"type":"string","description":"The rough notes or Markdown to format."},"doc_type":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"],"default":"GENERAL","description":"Which template's headings to organise the content under."}}}}}},"responses":{"200":{"description":"Formatted Markdown","content":{"application/json":{"schema":{"type":"object","properties":{"raw_markdown":{"type":"string"},"doc_type":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]},"model":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"No AI provider configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A DocuMemory personal access token (`dm_live_…`), created on the Settings page. Each token acts in one workspace: your personal one or an organization's."}},"schemas":{"CaptureRequest":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"The raw discussion text, verbatim. Include the full relevant exchange."},"title":{"type":"string","description":"Optional suggested title. Omit to let DocuMemory name the document."},"project_name":{"type":"string","description":"Project to file this under, matched or created by name. Defaults to 'Inbox'."},"hint":{"type":"string","description":"Optional extra instruction about what to emphasise in the document."},"doc_type":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"],"description":"Omit to let DocuMemory classify the document, which is usually right. Pass MEMORY to distil reusable standing context instead of a decision record: the result carries standalone key_facts plus an ai_context_snippet sized to paste into another model's system prompt. Choose MEMORY when the durable value is what is TRUE about a system (architecture rules, constraints, conventions, config, domain knowledge, stated preferences) rather than what was decided and why."}}},"CreateDocumentRequest":{"type":"object","required":["title","doc_type","raw_markdown"],"properties":{"title":{"type":"string","description":"The document title. It becomes the H1, so do not repeat it in the body."},"doc_type":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"],"default":"GENERAL","description":"GUIDE for a how-to, ADR for a decision record, SNIPPET for one piece of code, MEMORY for standing context, GENERAL otherwise."},"raw_markdown":{"type":"string","description":"The body as Markdown, without a top-level H1. Use `##` for sections and fenced blocks with a language tag for code. For a MEMORY, put facts as bullets under `### Key Facts` so they are indexed individually."},"project_id":{"type":"string","description":"Exact project id. Takes precedence over project_name."},"project_name":{"type":"string","description":"Project to file this under, matched or created by name. Defaults to 'Inbox'."},"tags":{"type":"array","items":{"type":"string"},"description":"Lowercase technical tags for indexing."},"ai_context_snippet":{"type":"string","description":"MEMORY only, and optional. Omit it and the body is parsed for a `### Project Memory:` block; supply it to set the injectable snippet explicitly."}}},"CaptureResponse":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"},"title":{"type":"string"},"doc_type":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]},"tags":{"type":"array","items":{"type":"string"}},"project":{"type":"string"},"url":{"type":"string","description":"Link to the document in the DocuMemory dashboard."},"key_facts":{"type":"array","items":{"type":"string"},"description":"MEMORY captures only. The standalone facts that were extracted."},"ai_context_snippet":{"type":"string","nullable":true,"description":"MEMORY captures only. Ready to inject into another model's system prompt; relay it verbatim if the user asked for portable context."},"message":{"type":"string","description":"A short confirmation to relay to the user."}}},"SearchResponse":{"type":"object","properties":{"mode":{"type":"string","enum":["hybrid","keyword"],"description":"'keyword' means embeddings were unavailable and results are keyword-only."},"count":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"docType":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]},"tags":{"type":"array","items":{"type":"string"}},"excerpt":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"score":{"type":"number"}}}}}},"Document":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"docType":{"type":"string","enum":["ADR","GUIDE","SNIPPET","GENERAL","MEMORY"]},"summary":{"type":"string","nullable":true,"description":"One-line overview, present for every document type."},"problemStatement":{"type":"string","nullable":true},"decisionTaken":{"type":"string","nullable":true},"keyFacts":{"type":"array","items":{"type":"string"},"description":"MEMORY documents only. Standalone facts, each readable with no surrounding context."},"aiContextSnippet":{"type":"string","nullable":true,"description":"MEMORY documents only. A Markdown block ready to inject into another model's system prompt."},"rawMarkdown":{"type":"string","description":"The full document, Markdown with YAML frontmatter."},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}}