A reference is a [generated section](/concepts/generated-sections): a source
names an artefact and the type that reads it, and the pages follow.

```ts
export default defineAppConfig({
  duxt: {
    sources: [
      {
        path: 'docs',
        generated: [
          {
            type: 'openapi',
            path: 'openapi.yaml',
            label: 'API'
          }
        ]
      }
    ]
  }
})
```

The fields a declaration takes are the same for every type and are in
[Sources](/reference/sources). `openapi` names no option of
its own; what it does answer is below.

## What it builds

```
/api                      the overview, from `info`
/api/<tag>                one page per tag
/api/<tag>/<operation>    one page per operation, with the client
```

An operation with no tag lands under a default group, and 3.1 webhooks land under
one of their own — a webhook is the same object under a name instead of a URL, so
it renders through the same page and says which it is.

## Versioning

**Per version.** An API description belongs to the release it describes: `v1` and
`v2` have different endpoints, and a reader on `v1` asking what a field means must
not be shown `v2`'s answer. Each version collection carries the document at its
own ref, and the version switcher works on the reference exactly as it works on
the prose.

This is the opposite of what [the `changelog` type](/reference/changelog/section)
answers, which is why versioning is a policy of the type rather than a rule of
the layer.

## Localisation

**Per locale, where a locale ships a document of its own.** A description is
written prose as much as it is structure — summaries, field descriptions, response
meanings — so a translated one is a real artefact rather than the same file
relabelled.

```ts
{
  type: 'openapi',
  path: 'openapi.yaml',
  label: 'API',
  locales: { de: 'openapi.de.yaml' }
}
```

A locale absent from the map builds no collection, and the existing fallback chain
serves it the default language's reference with the translation
banner saying so — see [Localisation](/concepts/localisation). What stays translated either way are **the layer's own labels** — the
table headers, "Request", "Response", the status names — because those belong to
the theme and not to the document.

## When the document cannot be read

The build fails, and says which section and why. That is deliberate: a reference
that silently became an empty section is a reference nobody notices is gone.