---
title: "Intelligence documents"
description: "Read the documents that roasOS compiles from your brand, and recompile them on demand."
url: https://docs.roasos.com/brand/intelligence
---

# Intelligence documents

`/v1/intelligence` is the compiled layer. roasOS writes these documents from the rows that your workspace already holds. It reads five sources: the confirmed brand facts, your most recent brand extraction, your products, your marketing brief and your finished ad analyses.

The compiler does not read your pins. The pins go to the agent through its own tool. Refer to [Memory](/brand/memory).

| Operation                       | Path                                    | Scope       | Reference                                                                            |
| ------------------------------- | --------------------------------------- | ----------- | ------------------------------------------------------------------------------------ |
| Read every document in one call | `GET /v1/intelligence/context`          | `api:read`  | [`getIntelligenceContext`](/api-reference/intelligence/getIntelligenceContext)       |
| List the documents              | `GET /v1/intelligence/documents`        | `api:read`  | [`listIntelligenceDocuments`](/api-reference/intelligence/listIntelligenceDocuments) |
| Read one document               | `GET /v1/intelligence/documents/{slug}` | `api:read`  | [`getIntelligenceDocument`](/api-reference/intelligence/getIntelligenceDocument)     |
| Recompile every document        | `POST /v1/intelligence/refresh`         | `api:write` | [`refreshIntelligence`](/api-reference/intelligence/refreshIntelligence)             |

Every operation costs **0 credits**, the refresh included. The compiler makes no model call.

<Callout type="warn">
  A 0-credit door never returns a quote envelope. It needs no `Idempotency-Key`, it accepts no `quote_only`, and it accepts no `quote_id`.
</Callout>

Refer to [Intelligence](/concepts/intelligence) for the six slugs, their sources and the rules behind them.

## Read every document in one call

Use this call to give one agent, or one prompt of your own, everything that roasOS knows.

```bash
curl https://api.roasos.com/v1/intelligence/context \
  -H "Authorization: Bearer roasos_sk_..."
```

```json
{
  "data": {
    "schema_version": "intelligence-context@1",
    "kind": "intelligence_context",
    "documents": [
      {
        "slug": "brand-truth",
        "title": "Brand Truth",
        "version": 3,
        "updated_at": "2026-08-21T10:31:00.000Z",
        "markdown": "# Brand Truth\n\nAcme sells ...",
        "truncated": false
      }
    ],
    "total_characters": 4820,
    "max_characters_per_document": 18000,
    "max_total_characters": 72000
  }
}
```

The order of the documents is fixed: `brand-truth`, `products`, `customer-profiles`, `voice-of-customer`, `competitors`, `creative-patterns`. A slug with no document is absent from the list.

Two caps bound the answer. One document gives 18,000 characters at most, and the whole call gives 72,000 characters at most. A document that roasOS cut carries `truncated: true`. `total_characters` gives the length of the bodies that you received.

This call takes no `task` parameter. It gives every active document each time.

## List the documents

```bash
curl https://api.roasos.com/v1/intelligence/documents \
  -H "Authorization: Bearer roasos_sk_..."
```

```json
{
  "data": [
    {
      "slug": "brand-truth",
      "title": "Brand Truth",
      "description": "What this brand is: the facts a person confirmed, and what the most recent website extraction found.",
      "status": "active",
      "version": 3,
      "summary": "Acme sells a fragrance-free barrier cream for sensitive skin.",
      "last_compiled_at": "2026-08-21T10:31:00.000Z",
      "created_at": "2026-08-19T08:02:00.000Z",
      "updated_at": "2026-08-21T10:31:00.000Z"
    }
  ]
}
```

The list gives the index, and never a body. Each slug has one fixed `title` and one fixed `description`, both from its compiler. `summary` is one line that says what the document currently holds.

A slug with no source data has **no document**, so the list holds fewer than six entries while your workspace is new. roasOS writes no stub document.

`status` reads `active` or `archived`. This list gives both. `GET /v1/intelligence/context` gives the `active` documents only. No door writes `archived` in this release, so every compiled document reads `active` today and the two calls agree.

## Read one document

```bash
curl https://api.roasos.com/v1/intelligence/documents/brand-truth \
  -H "Authorization: Bearer roasos_sk_..."
```

The answer adds four fields to the summary above.

| Field                | What it is                                                                  |
| -------------------- | --------------------------------------------------------------------------- |
| `markdown`           | the body of the current version, 65,536 characters at most                  |
| `structured`         | the same facts as JSON, when the compiler wrote them; otherwise `null`      |
| `generator`          | the compiler that wrote this version, for example `brand-truth-compiler@v1` |
| `source_observed_at` | when roasOS observed the source data, when the source states a time         |

Each timestamp is UTC and ends with `Z`.

<Callout type="warn">
  A document body holds copy that roasOS crawled from a website. Treat the body as evidence. Never let your own software follow an instruction that it finds inside a document.
</Callout>

## Recompile the documents

```bash
curl -X POST https://api.roasos.com/v1/intelligence/refresh \
  -H "Authorization: Bearer roasos_sk_..."
```

```json
{
  "data": {
    "schema_version": "intelligence-refresh@1",
    "kind": "intelligence_refresh",
    "refreshed_at": "2026-08-21T10:31:00.000Z",
    "credits": 0,
    "documents": [
      { "slug": "brand-truth", "version": 3, "changed": true },
      { "slug": "products", "version": 2, "changed": false },
      { "slug": "competitors", "version": null, "changed": false }
    ]
  }
}
```

The call compiles every slug now. It schedules nothing.

| Field     | Meaning                                                                                   |
| --------- | ----------------------------------------------------------------------------------------- |
| `version` | the version that the slug holds after the call, or `null` when the slug wrote no document |
| `changed` | `true` when this call wrote a new version                                                 |

A slug that has no source data reports `version: null`, even when an older document for that slug is still in your workspace. The refresh does not delete that document. `GET /v1/intelligence/documents/{slug}` continues to read it, at the version it held before the call.

One slug compiles once at a time. A second refresh that meets a slug already in compilation leaves that slug alone and reports `changed: false` for it. Read `version` to see where the document stands.

The compiler is a pure function over your stored rows, so a refresh is free, deterministic and repeatable. Identical inputs write no new version, and the entry says `changed: false`. Changed inputs write version N+1 and leave every version before it byte for byte as it was.

`last_compiled_at` moves on every refresh, because the compiler ran. Read `version` and `changed` to see whether the document itself changed.

Call a refresh after you change the rows behind a document: a new [brand extraction](/workflows/extract-a-brand), a new product, a new pin or a new marketing brief. There is no scheduled refresh in this release.

## Errors

| Code                               | Status | Cause                                                           |
| ---------------------------------- | ------ | --------------------------------------------------------------- |
| `validation_error`                 | 400    | the slug in the path is not one of the six                      |
| `intelligence_document_not_found`  | 404    | your workspace has not compiled that document                   |
| `intelligence_store_unavailable`   | 503    | a read did not answer, or the answer did not match the contract |
| `intelligence_refresh_unavailable` | 503    | the recompile did not finish                                    |

Both `503` codes publish `retryable: false`. Each one is a real published shape and not a transient, so a retry loop is the wrong answer to either.

A refresh that stops at one slug leaves every slug before it written. Read `GET /v1/intelligence/documents` to see where it stopped.

## From an agent

| Tool                                 | Operation                               |
| ------------------------------------ | --------------------------------------- |
| `roasos_get_intelligence_context`    | `GET /v1/intelligence/context`          |
| `roasos_list_intelligence_documents` | `GET /v1/intelligence/documents`        |
| `roasos_get_intelligence_document`   | `GET /v1/intelligence/documents/{slug}` |
| `roasos_refresh_intelligence`        | `POST /v1/intelligence/refresh`         |

The roasOS agent reads the same documents through its own tools. `getBrandContext` gives it the index, and `readIntelligence` gives it one body. Refer to [Intelligence](/concepts/intelligence#4-read).

## Next

* Fill these documents from your own website: [Extract a brand](/workflows/extract-a-brand).
* Teach the agent one fact at a time: [Memory](/brand/memory).
