# OpenAPI :badge[New in Clay 5]{tip}

Name an OpenAPI document in `clay.yaml`, and Clay makes a page for each of its operations, tags and schemas. They come below the docs in the navigation, under a line, and are searched, checked and read by agents like every other page. The [Petstore API](https://clay-doc.github.io/clay-example-repo/api/petstore.md) of this site is made that way, from Swagger's sample API.

```yaml [clay.yaml]
openapi:
  - spec: openapi/petstore.yaml
    title: Petstore API     # default: the document's title
    route: api/petstore     # default: api/ and the file's name
    icon: fa-solid fa-paw   # default: a plug
```

Clay reads OpenAPI 3.0 and 3.1, and Swagger 2.0, as YAML or JSON. References (`$ref`) may lead to other files of the project. `clay check` and `clay build --strict` report what the OpenAPI specification does not allow, with the place in the document.

> [!TIP]
> A document that lives elsewhere, e.g. one your API serves, is downloaded before every build with [`generate`](https://clay-doc.github.io/clay-example-repo/writing/generated-docs.md): `curl -o openapi/api.json https://api.example.com/openapi.json`.

## The pages

| Page | What it shows |
|------|---------------|
| Overview | Version and description, the servers, every way to authenticate, the operations by tag, and the document to download |
| Tag | Its description and its operations |
| Operation | A request cell to try it, the credentials it needs, its parameters, request body and responses (with headers, examples and links) and its callbacks |
| Webhook | The request the API sends to your server |
| Schema | Its properties, nested ones included, and an example |

Schemas with a name of their own are linked to their page wherever they appear, so a pet's `category` leads to the page of `Category`. Operations show their method in the navigation; deprecated ones are struck through. The interface texts of the pages are in the language of each edition; the document's own texts stay as written.

## Request cells

A request cell is a request to fill in and run on the page, like a cell of a notebook. Every operation's page has one. In your own pages, name the API and the operation, and the values to start with in YAML:

```md
[Finds Pets by status.](/api/petstore/pet/find-pets-by-status)

```sh
curl 'https://petstore3.swagger.io/api/v3/pet/findByStatus?status=available' \
  -H 'Authorization: Bearer <token>'
``````

::: request petstore findPetsByStatus
status: available
:::

The operation is named by its `operationId`, or by its method and path: `::: request petstore GET /pet/{petId}`. `body:` holds a request body to start with, `server:` picks one of the servers.

Without an API, a cell holds a request written out, like in an `.http` file: the method and address, the headers, an empty line and the body. Readers can change all of it.

```md
```sh
curl 'https://petstore3.swagger.io/api/v3/pet/10' \
  -H 'Accept: application/json'
``````

::: request
GET https://petstore3.swagger.io/api/v3/pet/10
Accept: application/json
:::

Like in a notebook, a click selects a cell, and <kbd>Ctrl</kbd> + <kbd>Enter</kbd> (<kbd>⌘</kbd> + <kbd>Enter</kbd> on a Mac) runs the selected one. A request body is colored as it is written, and each media type keeps its own: switching to `application/xml` shows an XML example. The answer comes below it: its status, how long it took, its headers, and its body, JSON in colors and pictures as pictures. Until then, the cell shows the example answer from the document. **curl**, **JavaScript** and **Python** show the request as code to copy.

### Credentials

Readers enter keys, passwords and tokens once per API, like with the *Authorize* button of Swagger UI: on the API's overview, under *Authentication*, or with **Authorize** in any cell, which shows the methods its operation takes, one tab each. Every cell of the API uses them. They stay in the browser tab unless the reader picks *Remember on this device*, and are only ever sent to the API itself. Code samples show placeholders instead.

| In the document | In the cell |
|-----------------|-------------|
| `apiKey` in a header or the query | The key |
| `http`: `basic`, `bearer` and others | User name and password, or the token |
| `oauth2` | Sign in with the authorization code flow (with PKCE), implicit, client credentials or password; or paste a token |
| `openIdConnect` | Sign in through the provider named by its discovery document |
| `mutualTLS` | The browser asks for the certificate |

Signing in through the provider's page comes back to `_clay/oauth-callback.html` of the site, e.g. `https://clay-doc.github.io/clay-example-repo/_clay/oauth-callback.html`; register that address as a redirect URL with the provider.

> [!NOTE]
> Requests go from the reader's browser straight to the API, so the API has to allow requests from your site ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS)); the Petstore allows all sites. When it does not, the cell says so. Browsers also do not let a page send cookies of its own choosing: an API key in a cookie is only in the code.

## Versions

When you save a version with [`clay version`](https://clay-doc.github.io/clay-example-repo/organizing/versions.md), it keeps its APIs as they are that day: Clay copies their documents, and the files these refer to, into `docs/<version>/_openapi/`, with their settings in `apis.yaml` next to them. The version's API pages and request cells use these copies, while the latest docs follow the document as it changes.

## Fields and endpoints

The API pages are written in Markdown with two components you can use in your own pages too: `::: fields` shows a list of names with their type and flags: the name in code, then the type, then **bold** for required, *italics* for other flags and ~~strikethrough~~ for deprecated. `::: endpoints` shows a list of operations with their method.

```md
::: fields
- `name` string **required**

  What the pet is called.
- `status` string *read-only*
:::

::: endpoints
- `GET /pet/{petId}` [Find pet by ID](/api/petstore/pet/get-pet-by-id)
:::
```

::: fields
- `name` string **required**

  What the pet is called.
- `status` string *read-only*
:::

::: endpoints
- `GET /pet/{petId}` [Find pet by ID](https://clay-doc.github.io/clay-example-repo/api/petstore/pet/get-pet-by-id.md)
:::

## For agents

In the [Markdown of a page](https://clay-doc.github.io/clay-example-repo/features/ai-and-agents.md), a request cell is a curl command with a link to its operation, and `llms.txt` lists the pages of every API.

---

All pages of these docs, as Markdown for language models: https://clay-doc.github.io/clay-example-repo/llms.txt
