Skip to content

REST API: Synthesis

Source-grounded synthesis from authorized memory. The synthesis endpoints turn the knowledge graph into structured, citation-backed artifacts.

Overview

Synthesis produces an artifact (documentation, report, briefing, roadmap, release notes, audit packet) where every section is grounded in cited sources from the knowledge graph. The REST surface mirrors the MCP synthesis tools.

Base URL: /api/synthesis

Authentication

All endpoints require authentication via:

  • JWT access token (cookie or Authorization header)
  • API key with api:read scope for /plan, api:write for /draft with remember

Role Requirements

OperationRequired Roles
Plan and draftOwner, Admin, Member, Viewer
Draft with remember: trueOwner, Admin, Member

Endpoints

Plan Synthesis

http
POST /api/synthesis/plan

Creates a deterministic, source-aware synthesis outline and materializes the source pack for each section. No artifact text is generated.

Request Body:

json
{
  "goal": "Document the Sibyl memory loop for new contributors",
  "output_type": "documentation",
  "audience": "engineers new to the codebase",
  "depth": "standard",
  "seed_query": null,
  "project": "proj_abc123",
  "domain": null,
  "entity_ids": [],
  "decision_ids": [],
  "task_ids": [],
  "artifact_ids": [],
  "required_sections": [],
  "constraints": [],
  "max_sections": 6,
  "include_neighborhoods": true
}

Request Schema:

FieldTypeRequiredDefaultDescription
goalstringYes-Synthesis goal (1-1000 chars)
output_typestringNodocumentationOutput type
audiencestringNo-Intended reader (max 500 chars)
depthstringNostandardbrief, standard, or deep
seed_querystringNo-Explicit retrieval query
projectstringNo-Project ID to scope sources
domainstringNo-Domain to scope sources
entity_idsstring[]No[]Pinned entity sources (max 100)
decision_idsstring[]No[]Pinned decision sources (max 100)
task_idsstring[]No[]Pinned task sources (max 100)
artifact_idsstring[]No[]Pinned artifact sources (max 100)
required_sectionsobject[]No[]Forced outline sections (max 12)
constraintsstring[]No[]Free-text output constraints (max 50)
max_sectionsintegerNo6Outline section cap (1-12)
include_neighborhoodsbooleanNotrueInclude one-hop related sources

A required_sections entry has the shape:

json
{
  "title": "Background",
  "prompt": "Summarize the prior approach",
  "required_source_ids": ["pattern_abc123"]
}

Output Types

documentation, report, briefing, roadmap, release_notes, audit_packet, custom

Response:

json
{
  "run_id": "synth_abc123",
  "status": "planned",
  "request": { "goal": "Document the Sibyl memory loop for new contributors" },
  "outline": {
    "title": "The Sibyl Memory Loop",
    "output_type": "documentation",
    "audience": "engineers new to the codebase",
    "sections": [
      {
        "section_id": "sec_1",
        "title": "Capture",
        "prompt": "How memory is captured",
        "source_query": "memory capture remember reflect",
        "source_ids": ["pattern_remember", "decision_raw_memory"],
        "gaps": []
      }
    ]
  },
  "source_packs": [
    {
      "section_id": "sec_1",
      "title": "Capture",
      "query": "memory capture remember reflect",
      "source_ids": ["pattern_remember", "decision_raw_memory"],
      "sources": [
        {
          "id": "pattern_remember",
          "type": "pattern",
          "name": "Raw memory capture",
          "content_preview": "Raw memory is stored verbatim before extraction...",
          "score": 0.91,
          "source": null,
          "origin": "graph",
          "relation": null,
          "metadata": {}
        }
      ],
      "hidden_count": 0,
      "redaction_count": 0,
      "freshness": {},
      "unresolved_claims": []
    }
  ],
  "verification": {
    "status": "pending",
    "source_count": 12,
    "gap_count": 0,
    "gaps": []
  }
}

hidden_count on a source pack reports relevant sources withheld because the caller's memory policy does not grant access.

Draft Synthesis

http
POST /api/synthesis/draft

Plans, materializes, drafts the artifact text, and applies verification. Optionally remembers the artifact as a memory record.

Request Body:

SynthesisDraftRequest extends the plan request with these additional fields:

json
{
  "goal": "Draft release notes for v0.9.0",
  "output_type": "release_notes",
  "project": "proj_abc123",
  "output_format": "markdown",
  "remember": true,
  "memory_scope": "project",
  "scope_key": "proj_abc123",
  "tags": ["release", "v0.9.0"]
}

Additional Request Schema:

FieldTypeRequiredDefaultDescription
output_formatstringNomarkdownmarkdown or json
rememberbooleanNofalsePersist the generated artifact as memory
memory_scopestringNoprivateprivate or project for the remembered artifact
scope_keystringNo-Project ID when memory_scope is project
tagsstring[]No[]Tags for the remembered artifact (max 50)

When remember is true with memory_scope: "project", scope_key is required (it defaults to project when omitted) and the write requires Member-or-higher role plus project access.

Response:

The draft response is a plan response plus an artifact field:

json
{
  "run_id": "synth_def456",
  "status": "verified",
  "request": { "goal": "Draft release notes for v0.9.0" },
  "outline": { "title": "Sibyl v0.9.0 Release Notes", "sections": [] },
  "source_packs": [],
  "verification": {
    "status": "pass",
    "source_count": 18,
    "gap_count": 0,
    "gaps": []
  },
  "artifact": {
    "artifact_id": "art_789",
    "format": "markdown",
    "title": "Sibyl v0.9.0 Release Notes",
    "markdown": "# Sibyl v0.9.0\n\n## Highlights\n...",
    "json_payload": {},
    "source_ids": ["pattern_remember", "decision_raw_memory"],
    "section_source_ids": {
      "sec_1": ["pattern_remember"]
    },
    "generated_text_hash": "sha256:...",
    "verification": {
      "status": "pass",
      "source_count": 18,
      "gap_count": 0,
      "gaps": []
    },
    "remembered_memory_id": "memory_abc",
    "remembered_source_id": "src_abc"
  }
}

When remember is false, remembered_memory_id and remembered_source_id are null.

Verification

Both endpoints attach a verification summary. The /draft endpoint applies verification before returning; /plan returns verification.status: "pending".

StatusMeaning
pendingVerification not yet applied (raw /plan response)
gapsOne or more sections lack sufficient grounding
passAll sections are adequately source-grounded

Each gap identifies the under-grounded section, the reason, the retrieval query that came up short, and any missing source IDs.

Error Responses

StatusCause
400Invalid request, or missing_scope_key on a project-scoped draft
401Missing or invalid authentication
403Insufficient role, insufficient_org_role, or project access denied
422Request body validation failed
500Synthesis planning or drafting failed

Released under the Apache-2.0 License.