> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphorlm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat API

> Ask questions about your documents using natural language

## Overview

The Document Chat API allows you to ask questions about your ingested documents and receive answers grounded in your content. The API supports conversational memory, enabling follow-up questions that maintain context.

## Endpoint

```
POST https://sources.graphorlm.com/ask-sources
```

## Authentication

Include your API token in the Authorization header:

```
Authorization: Bearer YOUR_API_TOKEN
```

## Request

### Headers

| Header          | Value                   | Required |
| --------------- | ----------------------- | -------- |
| `Authorization` | `Bearer YOUR_API_TOKEN` | Yes      |
| `Content-Type`  | `application/json`      | Yes      |

### Body Parameters

| Parameter                 | Type                 | Required | Description                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `question`                | string               | Yes      | The question to ask about your documents                                                                                                                                                                                                                                                                                                                          |
| `conversation_id`         | string               | No       | Conversation identifier to maintain memory context across questions                                                                                                                                                                                                                                                                                               |
| `reset`                   | boolean              | No       | When `true`, starts a new conversation and ignores previous history. Default: `false`                                                                                                                                                                                                                                                                             |
| `file_ids`                | string\[]            | No       | Restrict search to specific documents by file ID (preferred)                                                                                                                                                                                                                                                                                                      |
| `file_names`              | string\[]            | No       | Restrict search to specific documents by file name (deprecated, use `file_ids`)                                                                                                                                                                                                                                                                                   |
| `output_schema`           | object (JSON Schema) | No       | Optional JSON Schema to request a structured output. When provided, the API returns validated structured data in `structured_output` and the raw JSON-text candidate in `raw_json`.                                                                                                                                                                               |
| `thinking_level`          | string               | No       | Controls model and thinking configuration. Values: `"fast"`, `"balanced"`, `"accurate"` (default). See [Thinking Level](#thinking-level) for details.                                                                                                                                                                                                             |
| `include_citation_images` | boolean              | No       | When `true`, populates `image_base64` (base64-encoded PNG of the cited page) inside each entry of `citations`. Default: `false`. See [Citations](#citations) for guidance.                                                                                                                                                                                        |
| `include_citation_markup` | boolean              | No       | When `true`, the `answer` field keeps the raw structured citation markup `[N](file_id\|pX\|sY\|eZ\|fNAME)` emitted by the agent instead of stripping it down to plain `[N]` markers. Default: `false`. The structured markup format is an implementation detail and may change — prefer parsing the `citations` array. Has no effect when `output_schema` is set. |

### Thinking Level

The `thinking_level` parameter controls the model and thinking configuration used for answering questions:

| Value        | Description                                                                                                 |
| ------------ | ----------------------------------------------------------------------------------------------------------- |
| `"fast"`     | Uses a faster model without extended thinking. Best for simple questions where speed is prioritized.        |
| `"balanced"` | Uses a more capable model with low thinking. Good balance between quality and speed.                        |
| `"accurate"` | Default. Uses a more capable model with high thinking. Best for complex questions requiring deep reasoning. |

### Example Request

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What are the main findings in this report?"
  }'
```

### Example with Conversation Memory

```bash theme={null}
# First question
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What products are mentioned in the catalog?"
  }'

# Response: { "answer": "...", "conversation_id": "conv_abc123" }

# Follow-up question using conversation_id
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Which one is the most expensive?",
    "conversation_id": "conv_abc123"
  }'
```

### Example with Specific Documents (using file\_ids)

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What is the total amount due?",
    "file_ids": ["file_abc123", "file_def456"]
  }'
```

### Example with Specific Documents (using file\_names - deprecated)

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What is the total amount due?",
    "file_names": ["invoice-2024.pdf", "invoice-2023.pdf"]
  }'
```

### Example with Thinking Level

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Analyze the legal implications of the termination clause",
    "file_names": ["contract.pdf"],
    "thinking_level": "accurate"
  }'
```

### Example with Citations and Inline Images

Set `include_citation_images: true` to get base64 screenshots of every cited page in the same response. **Use sparingly** — see [Should I use `include_citation_images`?](#should-i-use-include_citation_images).

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What was the revenue in 2025?",
    "file_ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
    "include_citation_images": true
  }'
```

For most cases, leave the flag off and fetch screenshots on demand:

```bash theme={null}
# 1. Ask the question
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "question": "What was the revenue in 2025?" }'

# 2. For each citation the user actually inspects, fetch the page image
curl "https://sources.graphorlm.com/{file_id}/pages/{page_number}/screenshot" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Example with Structured Output (JSON Schema)

When you pass `output_schema`, the API will attempt to return a schema-conformant JSON object/array in `structured_output`.

Notes/constraints:

* Supported schemas must be **simplified JSON Schema**
* Unions must be only with `null` (e.g. `["string", "null"]`)
* Complex constructs like `oneOf`/`anyOf`/`allOf`/`$ref` are not supported

```bash theme={null}
curl -X POST "https://sources.graphorlm.com/ask-sources" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Extract the invoice number and total amount due.",
    "file_names": ["invoice-2024.pdf"],
    "output_schema": {
      "type": "object",
      "properties": {
        "invoice_number": { "type": ["string", "null"] },
        "total_amount_due": { "type": ["number", "null"] },
        "currency": { "type": ["string", "null"] }
      }
    }
  }'
```

## Response

### Success Response (200 OK)

| Field               | Type      | Description                                                                                                                                                                                                                                  |
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `answer`            | string    | The answer to your question, with inline `[N]` markers pointing to entries in `citations`. When `output_schema` is provided, this is a short status message and the structured data is in `structured_output` (raw JSON-text in `raw_json`). |
| `structured_output` | any       | Optional structured output validated against the requested `output_schema`. Present only when `output_schema` is provided.                                                                                                                   |
| `raw_json`          | string    | Optional raw JSON-text produced by the model before validation/correction. Present only when `output_schema` is provided.                                                                                                                    |
| `conversation_id`   | string    | Conversation identifier for follow-up questions                                                                                                                                                                                              |
| `citations`         | object\[] | Structured citations resolving each `[N]` marker in `answer`. See [Citations](#citations). May be `null`/empty when the agent did not ground its answer (e.g. small-talk follow-ups).                                                        |
| `usage`             | object    | Token usage breakdown for the request                                                                                                                                                                                                        |
| `elapsed_s`         | number    | Wall-clock time in seconds                                                                                                                                                                                                                   |

### Citations

Each entry in `citations` corresponds to one `[N]` marker that appears in the `answer` text. Use `index` to map markers to citation entries.

| Field            | Type    | Description                                                                                                                                                                              |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `index`          | integer | The 1-based citation number that appears as `[N]` in `answer`                                                                                                                            |
| `file_id`        | string  | Unique identifier of the source file                                                                                                                                                     |
| `file_name`      | string  | Display name of the source file                                                                                                                                                          |
| `page_number`    | integer | 1-based page number where the cited content appears                                                                                                                                      |
| `section_number` | integer | Optional section number within the page                                                                                                                                                  |
| `element_id`     | string  | Optional element identifier (e.g. specific paragraph or table)                                                                                                                           |
| `text_preview`   | string  | Short text excerpt around the cited content                                                                                                                                              |
| `image_base64`   | string  | Base64-encoded PNG screenshot of the cited page. Populated only when the request used `include_citation_images=true`. May be `null` if the source is not visualizable (e.g. plain text). |

#### Should I use `include_citation_images`?

The flag is convenient for quick prototyping or one-off requests where the client wants the answer **and** the visual previews in a single round-trip.

For real applications — especially when answers commonly cite many pages — **prefer `include_citation_images=false` (the default) and lazy-load the screenshots on demand** via the dedicated endpoint described in [Get Page Screenshot](/api-reference/sources/page-screenshot). Reasons:

* **Payload size**: each base64 PNG is typically 100-400 KB. Five citations can push the JSON response above a megabyte and slow down clients.
* **Latency**: rendering screenshots is parallel but still adds seconds to the response — every page render is I/O + image processing. With the default flag off, the answer comes back as soon as the model finishes.
* **Cache locality**: the screenshot endpoint sets `Cache-Control: public, max-age=3600` and is keyed by `(file_id, page_number)`. Lazy-loading lets browsers and CDNs cache the bytes; inlining base64 prevents that.

A good rule of thumb: enable `include_citation_images=true` only when you control both ends and know the answer will cite at most 1-2 pages (e.g. a confirmation step in a workflow). Otherwise, ship the answer with structured `citations` and fetch images on hover/click.

### Example Response

```json theme={null}
{
  "answer": "Revenue grew 23% year-over-year, reaching $4.2B [1]. The strongest segment was digital services, which contributed 38% of total revenue [2].",
  "conversation_id": "conv_abc123",
  "citations": [
    {
      "index": 1,
      "file_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "file_name": "annual-report-2025.pdf",
      "page_number": 12,
      "section_number": 2,
      "element_id": "p-7",
      "text_preview": "Revenue grew by 23% year-over-year, reaching $4.2 billion…",
      "image_base64": null
    },
    {
      "index": 2,
      "file_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "file_name": "annual-report-2025.pdf",
      "page_number": 18,
      "section_number": null,
      "element_id": null,
      "text_preview": "Digital services contributed 38% of total revenue…",
      "image_base64": null
    }
  ]
}
```

### Example Response (Structured Output)

```json theme={null}
{
  "answer": "Structured output generated.",
  "structured_output": {
    "invoice_number": "INV-2024-001",
    "total_amount_due": 1299.5,
    "currency": "USD"
  },
  "raw_json": "{\n  \"invoice_number\": \"INV-2024-001\",\n  \"total_amount_due\": 1299.50,\n  \"currency\": \"USD\"\n}",
  "conversation_id": "conv_abc123"
}
```

### Error Responses

| Status Code | Description                                                                           |
| ----------- | ------------------------------------------------------------------------------------- |
| 400         | Bad Request - Invalid parameters                                                      |
| 401         | Unauthorized - Invalid or missing API token                                           |
| 404         | Not Found - Specified file not found                                                  |
| 422         | Unprocessable Entity - Invalid `output_schema` or structured output validation failed |
| 500         | Internal Server Error                                                                 |

## Usage Examples

### Python

```python theme={null}
import requests

url = "https://sources.graphorlm.com/ask-sources"
headers = {
    "Authorization": "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json"
}

# Simple question
response = requests.post(url, headers=headers, json={
    "question": "What are the key terms in this contract?"
})

data = response.json()
print(data["answer"])

# Follow-up question
response = requests.post(url, headers=headers, json={
    "question": "When does it expire?",
    "conversation_id": data["conversation_id"]
})

print(response.json()["answer"])
```

### JavaScript

```javascript theme={null}
const API_URL = "https://sources.graphorlm.com/ask-sources";
const API_TOKEN = "YOUR_API_TOKEN";

async function askQuestion(
  question,
  conversationId = null,
  fileNames = null,
  outputSchema = null
) {
  const payload = {
    question,
    conversation_id: conversationId
  };

  if (fileNames && fileNames.length) {
    payload.file_names = fileNames;
  }

  if (outputSchema) {
    payload.output_schema = outputSchema;
  }

  const response = await fetch(API_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_TOKEN}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(payload)
  });
  
  return response.json();
}

// Usage
const result = await askQuestion("What products are available?");
console.log(result.answer);

// Follow-up
const followUp = await askQuestion(
  "Tell me more about the first one", 
  result.conversation_id
);
console.log(followUp.answer);
```

## Best Practices

1. **Use conversation memory** — Pass `conversation_id` for follow-up questions to maintain context
2. **Be specific** — Clear, specific questions get better answers
3. **Scope when needed** — Use `file_ids` to focus on specific documents
4. **Use structured output when integrating** — Provide `output_schema` to get JSON you can reliably parse in code
5. **Reset when changing topics** — Set `reset: true` when switching to unrelated questions
6. **Lazy-load citation images** — Keep `include_citation_images=false` (the default) and fetch page screenshots on demand via [Get Page Screenshot](/api-reference/sources/page-screenshot). Inlining base64 only makes sense for low-citation, low-frequency requests — for typical chat UIs it bloats the payload by hundreds of KB per cited page.
7. **Parse `citations`, not the markup** — Use the structured `citations` array to render references. The inline `[N](file_id|pX|...)` markup is hidden by default and is an implementation detail that may change.

## Related

<CardGroup cols={2}>
  <Card title="Get Page Screenshot" icon="image" href="/api-reference/sources/page-screenshot">
    Fetch base64 screenshots for citations on demand
  </Card>

  <Card title="Document Chat Guide" icon="comments" href="/guides/document-chat">
    Learn best practices for chatting with your documents
  </Card>

  <Card title="Data Ingestion" icon="file-import" href="/guides/data-ingestion">
    Improve parsing quality for better chat responses
  </Card>
</CardGroup>
