API guide

Document Analyser exposes graph, search, and ask endpoints over REST. This page describes authentication, the request/response shapes, and shows worked examples using curl and TypeScript fetch.

Note

These graph API endpoints (/api/graph, /api/search, /api/ask) are not yet part of the typed proto/OpenAPI surface and may change as the API stabilises.

Authentication

All graph API endpoints require a Firebase ID token passed as a Bearer token in the Authorization header:

Authorization: Bearer <firebase-id-token>

You can obtain your ID token from the Firebase SDK after sign-in, or from a server-side session. For long-running scripts, mint a graph API token instead (see below) — it does not expire with a short-lived Firebase session.

Graph API tokens

Mint a persistent token at /api/tokens. This endpoint proxies to the docgraph API and returns tokens scoped to your account.

List your tokens:

curl -H "Authorization: Bearer $TOKEN" \
  "https://document-analyser.com/api/tokens"

Create a named token:

curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-script"}' \
  "https://document-analyser.com/api/tokens"

Use the returned token value as the Authorization: Bearer credential for subsequent /api/graph, /api/search, and /api/ask requests.


Graph — GET /api/graph

Returns the full knowledge graph for the authenticated user as nodes, edges, and grouped clusters.

Response shape:

{
  "configured": true,
  "nodes": [/* ... */],
  "edges": [/* ... */],
  "groups": [/* ... */]
}

curl:

curl -H "Authorization: Bearer $TOKEN" \
  "https://document-analyser.com/api/graph"

TypeScript:

const res = await fetch('/api/graph', {
  headers: { Authorization: `Bearer ${token}` },
});
const { nodes, edges, groups } = await res.json();

Search — GET /api/search

Semantic search over your embedded document chunks. Returns ranked results with source citations.

Query parameters:

ParameterRequiredDescription
qYesThe search query (natural language or keyword)
limitNoMaximum results to return (default: 12)
typeNoFilter by result type
mimeNoFilter by MIME type
source_idNoRestrict to a specific source document
afterNoDate filter (ISO 8601)
beforeNoDate filter (ISO 8601)

curl:

curl -H "Authorization: Bearer $TOKEN" \
  "https://document-analyser.com/api/search?q=rate+limits+promised+to+acme&limit=6"

TypeScript:

const params = new URLSearchParams({ q: 'rate limits promised to acme', limit: '6' });
const res = await fetch(`/api/search?${params}`, {
  headers: { Authorization: `Bearer ${token}` },
});
const { results } = await res.json();

Ask — POST /api/ask

Ask a natural-language question against your knowledge graph. The API answers with citations back to the source chunks it drew on.

Request body:

{ "question": "What rate limits did we promise Acme?" }

Streaming (SSE)

Pass Accept: text/event-stream to receive the answer as a Server-Sent Events stream. The server pipes deltas from the underlying model as they arrive:

curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"question": "What rate limits did we promise Acme?"}' \
  "https://document-analyser.com/api/ask"

Non-streaming (JSON)

Omit the Accept header (or set it to application/json) to receive a single JSON response once the answer is complete:

curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"question": "What rate limits did we promise Acme?"}' \
  "https://document-analyser.com/api/ask"

TypeScript (streaming):

const res = await fetch('/api/ask', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
    Accept: 'text/event-stream',
  },
  body: JSON.stringify({ question: 'What rate limits did we promise Acme?' }),
});

// Read SSE deltas
const reader = res.body!.getReader();
const decoder = new TextDecoder();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  process.stdout.write(decoder.decode(value));
}

Error responses

All endpoints return standard HTTP status codes. A 401 means the Bearer token is missing or invalid. A 502 means the docgraph backend was unreachable. Error bodies carry an "error" field with a short description.

{ "error": "unauthorized" }