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

# Context Contract

> The structured retrieval envelope returned by /v1/context.

`/v1/context` returns a **Context Contract** — a richer envelope than `/v1/search` that documents not just *what* was retrieved but also *what was excluded and why*. It's designed for agents that need to reason about their own context window honestly.

## Why a contract instead of just hits

A bare hit list looks the same whether retrieval found everything relevant or got blocked by a scope. An honest agent needs to know the difference. The contract makes it explicit:

* What did you ask for?
* What did Repo retrieve?
* What did Repo exclude, and why?
* What are the freshness + access caveats?

## Shape

```json theme={null}
{
  "contract": {
    "version": "1.0",
    "requestId": "uuid",
    "endpoint": "/v1/context",
    "issuedAt": "2026-05-30T20:14:00Z",
    "callerActorType": "agent",
    "callerApiKeyId": "uuid"
  },
  "query": {
    "raw": "What did we decide about the brand color?",
    "limit": 8
  },
  "hits": [
    {
      "sourceItemId": "uuid",
      "title": "Brand decisions",
      "content": "We're keeping the lime-green accent...",
      "url": "https://www.notion.so/...",
      "provider": "notion",
      "score": 0.8432,
      "freshness": { "syncedAt": "2026-05-30T20:00:00Z", "ageHours": 0.2 },
      "accessPolicy": { "provider": "notion", "mode": "provider_scope", "workspaceId": "..." }
    }
  ],
  "citations": [
    { "index": 1, "sourceItemId": "uuid", "title": "Brand decisions" }
  ],
  "exclusions": [
    {
      "type": "provider_scope",
      "provider": "gmail",
      "reason": "The authenticating API key is not allowed to retrieve this provider."
    },
    {
      "type": "no_results",
      "provider": "slack",
      "reason": "The provider was allowed for this key, but no matching context was returned."
    }
  ],
  "limitations": [
    {
      "code": "provider_scope_applied",
      "message": "Only notion, slack memory was eligible for retrieval."
    }
  ]
}
```

## Field reference

### `contract`

| Field             | Meaning                                                        |
| ----------------- | -------------------------------------------------------------- |
| `version`         | Schema version. Current: `"1.0"`.                              |
| `requestId`       | UUID for this exact retrieval — match it against audit events. |
| `endpoint`        | Which Repo endpoint produced the contract.                     |
| `issuedAt`        | UTC timestamp the contract was generated.                      |
| `callerActorType` | `agent` / `application` / `admin` — from the key's metadata.   |
| `callerApiKeyId`  | The API key that authenticated the call.                       |

### `hits`

Array of retrieved source items, ordered by `score` descending.

| Field                | Meaning                                                                            |
| -------------------- | ---------------------------------------------------------------------------------- |
| `sourceItemId`       | Stable Repo ID. Use this for follow-up `/v1/source-items/:id` calls (coming soon). |
| `title`              | Source-provided title (Slack message text, Notion page title, Drive filename).     |
| `content`            | The chunk text that matched.                                                       |
| `url`                | Deep-link back to the original source.                                             |
| `provider`           | `slack` / `notion` / `google_drive` / `gmail`.                                     |
| `score`              | Cosine similarity to the query embedding, 0.0 — 1.0.                               |
| `freshness.syncedAt` | When this source was last synced by Repo.                                          |
| `freshness.ageHours` | How stale the data is, rounded to 0.1h.                                            |
| `accessPolicy`       | Per-provider access metadata preserved at ingest.                                  |

### `citations`

A numbered citation list ready to inject into your LLM prompt. Each citation references a `sourceItemId` so your agent can resolve `[1]` → "Brand decisions" → the actual Notion URL.

### `exclusions`

The most important field for honest agents. Each entry explains a piece of context the agent did **not** receive.

| `type`           | Meaning                                                                   |
| ---------------- | ------------------------------------------------------------------------- |
| `provider_scope` | The key's `allowedProviders` excluded this provider entirely.             |
| `no_results`     | The provider was allowed but the vector search returned nothing relevant. |

### `limitations`

Higher-level caveats about the retrieval, e.g.:

* `no_context` — Repo found nothing matching this query within the caller's scope.
* `provider_scope_applied` — Note that scope filtering was active.
* `missing_sync_timestamp` — One or more sources lack freshness metadata.
* `missing_source_access_policy` — One or more sources don't yet have preserved ACL data (Drive specifically).

## Why this shape

Repo treats the agent as a participant in a structured exchange, not a black-box consumer of search hits. The contract makes it possible to:

* Cite sources precisely in answers (`[1]` → real URL)
* Tell the user "I have additional context I'm not allowed to share" instead of hallucinating
* Surface freshness so the agent can hedge ("This is from 6 hours ago — let me check the latest")
* Audit retrieval after the fact via `requestId`

## Use the simpler endpoint if you don't need this

`/v1/search` returns just the `hits` array — same retrieval, no envelope. Use it when you're prototyping or your agent doesn't care about exclusions.
