# Sources

An answer cites the provisions it rests on. `sources[]` on the response holds one record for each source the answer cites, numbered by first citation, and nothing else. The research the run read along the way is never listed. A citation that does not resolve to a link shows as its label with no number.

## The source record

```json
{
  "number": 1,
  "kind": "provision",
  "unit_id": "hu:njt:2007-127-00-00:part-3.ch-viii.h1.s142.p1.ptb",
  "title": "Áfa tv. 142. § (1) b)",
  "act": { "title": "2007. évi CXXVII. törvény az általános forgalmi adóról", "short_title": "Áfa tv.", "identifier": "2007. évi CXXVII. törvény" },
  "section": "142. § (1) b)",
  "country": "hu",
  "version": { "id": "...", "effective_from": "2026-01-01", "effective_to": null, "is_current": true },
  "url": "https://njt.hu/jogszabaly/2007-127-00-00",
  "url_kind": "official",
  "excerpt": "..."
}
```

| Field      | Type                            | Meaning                                                                                                                                                                                       |
| ---------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `number`   | integer                         | 1-based; the `source_number` of the annotations that cite it                                                                                                                                  |
| `kind`     | `provision`, `passage` or `web` | What was cited                                                                                                                                                                                |
| `unit_id`  | string or null                  | A provision's id, the same across versions and re-ingestion. Pass it to [`POST /v1/provisions/fetch`](/guides/lookups). Null for a passage, a web page and a provision whose id is not stable |
| `title`    | string                          | A display label: the act's short title, then the section                                                                                                                                      |
| `act`      | object or null                  | `title`, `short_title`, `identifier`                                                                                                                                                          |
| `section`  | string or null                  | The provision's label                                                                                                                                                                         |
| `country`  | string or null                  | A lower-case country code                                                                                                                                                                     |
| `version`  | object or null                  | `id`, `effective_from`, `effective_to`, `is_current`; dates are `YYYY-MM-DD`. The `id` is per version and not stable, so never store it as a key                                              |
| `url`      | string                          | An absolute https URL, always present                                                                                                                                                         |
| `url_kind` | `official`, `viewer` or `web`   | Where `url` points                                                                                                                                                                            |
| `excerpt`  | string or null                  | At most 300 characters, whitespace collapsed                                                                                                                                                  |

A Hungarian `unit_id` is `hu:njt:<njt id>:<path>`. Treat it as an opaque string and pass it back as is.

## Which url you get

`url` is the first of these that applies:

1. The cited version's official URL (`url_kind: "official"`).
2. The provision viewer, when the source has a `unit_id` (`url_kind: "viewer"`).
3. The document viewer, when the act has a published identifier that is unique in its country (`url_kind: "viewer"`). It is never used for countries whose provision ids are not yet stable.
4. Otherwise the citation shows as its label with no number and no record.

A passage (`kind: "passage"`) gets the passage viewer, on the API and on MCP alike. A web result keeps its own URL (`url_kind: "web"`).

Viewer URLs open on `platform.azta.ai` and need an Azta sign-in. They never carry an internal id that changes when a law is re-ingested, so a stored link keeps working.

## Annotations

The answer text is plain text. Each citation is an annotation over the label's span, in OpenAI's `url_citation` shape plus `source_number`:

```json
{
  "type": "url_citation",
  "start_index": 120,
  "end_index": 141,
  "url": "https://...",
  "title": "Áfa tv. 142. § (1) b)",
  "source_number": 1
}
```

`source_number` matches the `number` of a record in `sources[]`.

`start_index` and `end_index` count Unicode code points of the returned `text`, so `text[start:end]` is exactly the label. A UTF-16 count, which JavaScript's `String.length` and `slice` use, differs after astral characters such as an emoji or a mathematical letter, and a base letter followed by a combining mark counts as two code points. In JavaScript, split the text with `Array.from(text)` before you slice. In Python a `str` already indexes code points.

## Render the citations

Insert ` [n]` after each annotated span, then list the sources. Walk the annotations from the highest `end_index` down, so the offsets of earlier spans stay valid while you insert.

```ts tab="TypeScript"
// Render an Azta answer with [n] after each cited span, then a Sources list.
// Annotation offsets are Unicode code points, so slice a code point array.
type SourceRecord = { number: number; title: string; url: string };
type Annotation = {
  start_index: number;
  end_index: number;
  source_number?: number;
};
type OutputText = { type?: string; text: string; annotations?: Annotation[] };
type Item = { content?: OutputText[] };

const renderText = (part: OutputText): string => {
  const points = Array.from(part.text);
  const annotations = [...(part.annotations ?? [])]
    .filter((a) => a.source_number !== undefined)
    .sort((a, b) => b.end_index - a.end_index);
  // Highest end_index first, so the offsets of earlier spans stay valid.
  for (const a of annotations) {
    points.splice(a.end_index, 0, ` [${a.source_number}]`);
  }
  return points.join('');
};

export const renderWithCitations = (response: {
  output: unknown[];
  sources: SourceRecord[];
}): string => {
  const parts = (response.output as Item[])
    .flatMap((item) => item.content ?? [])
    .filter((part) => typeof part.text === 'string');
  const text = parts.map(renderText).join('\n');
  const lines = response.sources.map(
    (s) => `[${s.number}] ${s.title} ${s.url}`,
  );
  return `${text}\n\nSources:\n${lines.join('\n')}`;
};

if (process.argv[1]?.endsWith('render.ts')) {
  const chunks: Buffer[] = [];
  for await (const chunk of process.stdin) {
    chunks.push(chunk as Buffer);
  }
  console.log(
    renderWithCitations(JSON.parse(Buffer.concat(chunks).toString())),
  );
}
```

```python tab="Python"
"""Render an Azta answer with [n] after each cited span, then a Sources list.

Reads the response JSON on stdin. Annotation offsets are Unicode code points,
and a Python str indexes code points, so the offsets slice it directly.
"""

import json
import sys


def render_text(part: dict) -> str:
    text = part["text"]
    annotations = [
        a for a in part.get("annotations", []) if a.get("source_number") is not None
    ]
    # Highest end_index first, so the offsets of earlier spans stay valid.
    for a in sorted(annotations, key=lambda a: a["end_index"], reverse=True):
        end = a["end_index"]
        text = f"{text[:end]} [{a['source_number']}]{text[end:]}"
    return text


def render_with_citations(response: dict) -> str:
    parts = [
        part
        for item in response["output"]
        for part in item.get("content", [])
        if isinstance(part.get("text"), str)
    ]
    text = "\n".join(render_text(part) for part in parts)
    lines = [f"[{s['number']}] {s['title']} {s['url']}" for s in response["sources"]]
    return text + "\n\nSources:\n" + "\n".join(lines)


if __name__ == "__main__":
    print(render_with_citations(json.load(sys.stdin)))
```

The output is the text with `[n]` after each cited label, a blank line, `Sources:`, then one `[n] title url` line per source, as in the [quickstart](/quickstart).
