# OpenAPI

Source: https://modulify.ai/docs/api/openapi

The machine readable description of every method, for Postman, Insomnia and client generators.

`https://api.modulify.ai/v1/openapi.json` describes the whole API in OpenAPI 3.1. Tools that read OpenAPI can turn it into a collection of ready-made requests, documentation or a typed client in the language you use.

```bash
curl https://api.modulify.ai/v1/openapi.json -o modulify-openapi.json
```

It needs no token to read, because it describes the methods without exposing anything of yours.

## What it contains

| Part | What it holds |
| --- | --- |
| `servers` | `https://api.modulify.ai/v1`, so every path is a method name |
| `security` | A bearer token in the `Authorization` header, for every operation |
| `paths` | One `post` operation per method, plus `get` operations for `/tools` and `/token` |
| `tags` | The area each method belongs to, such as `sites` or `chat`, so tools can group them |
| `components` | The response envelope, a schema for the method list, and the shared answers for each error status |

Every method's operation carries:

| Field | What it holds |
| --- | --- |
| `operationId` | The method name, such as `list_sites` |
| `summary` | The method's title |
| `description` | What it does, the same text `GET /v1/tools` returns |
| `requestBody` | Its arguments as a JSON Schema, with the required ones marked |
| `parameters` | The optional `Idempotency-Key` header |
| `responses` | The envelope for success, and each error status it can answer with |
| `x-modulify-scope` | The scope a token needs to call it |
| `x-modulify-read-only` | `true` when it only reads |
| `x-modulify-destructive` | `true` when it deletes or overwrites something that cannot be brought back |

The `x-modulify-` fields are extensions: tools that do not know them ignore them, and your own code can use them, for example to refuse destructive methods unless a person confirmed.

## Caching

The description changes only when the methods do, which is when Modulify itself is updated. It is served with `Cache-Control: public, max-age=300` and an `ETag`. Send the `ETag` back in `If-None-Match` and an unchanged description answers `304 Not Modified` with no body.

```bash
curl -i https://api.modulify.ai/v1/openapi.json -H 'If-None-Match: "ETAG_VALUE"'
```

`info.version` is the version of the Modulify server that built it, the same value as `version` in every response.

## Generate a client

Any OpenAPI 3.1 generator works. Give it the address or the downloaded file, then set the bearer token once on the generated client. Generated code names each call after its `operationId`, so `list_sites` becomes a `list_sites` function or method.

Because every method is a `POST` with a JSON body, a generator is optional. A ten-line helper that posts to `https://api.modulify.ai/v1/` plus a name works for every method. See [Requests and responses](https://modulify.ai/docs/api/requests-and-responses).

## The method list as JSON

`GET /v1/tools` returns the same methods without the OpenAPI wrapping, limited to the ones the token's scopes allow, each with its `name`, `title`, `description`, `scope`, `readOnly`, `destructive`, `method`, `path` and `inputSchema`. Use it to check at run time what a particular token can do.

## Next

- [Testing](https://modulify.ai/docs/api/testing) for importing the description into Postman or Insomnia.
- [Versioning](https://modulify.ai/docs/api/versioning) for what can change in it over time.