# Machine-Readable Specs

Source: https://www.potatoannotator.com/docs/measurement/machine-readable-specs

**Potato publishes two generated, machine-checkable contracts alongside the prose documentation.** Both are produced from the running code rather than maintained by hand, so they describe what Potato actually does rather than what someone remembered when they last edited a page.

If you are pointing a coding agent at Potato, these plus `llms.txt` are the highest-value things to give it.

| Artifact | What it describes |
|---|---|
| [Config JSON Schema](https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json) | Every valid key, annotation type and display type in a task `config.yaml` |
| [OpenAPI 3.1 spec](https://github.com/davidjurgens/potato/blob/main/docs/api-reference/openapi.json) | Every HTTP endpoint the server registers |

## The config schema

Version 2.8.0 covers **159 top-level config keys, 61 annotation types and 24 display types**, plus per-type conditionals, so a `constant_sum` scheme is told it needs `labels` before the server rejects it.

Add the modeline as the first line of any config and your editor validates as you type, in VS Code, JetBrains, Zed and Helix:

```yaml
# yaml-language-server: $schema=https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json
```

Every config shipped in the Potato repository carries it, and the [playground](/playground) emits it on every download.

In CI:

```bash
check-jsonschema --schemafile \
  https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json \
  path/to/config.yaml
```

Or with the local validator, which additionally reports unknown keys:

```bash
python -m potato.validate_cli --strict config.yaml
```

## The API spec

**419 paths and 456 operations**, walked off the live Flask route map rather than written by hand. Config-gated blueprints are registered onto scratch apps so they are not silently omitted, and per-endpoint auth is recovered by an AST scan.

For scale: the previous hand-written reference covered 84 endpoints against 400-plus registered routes.

## CI fails on drift

Both artifacts are regenerated and compared in CI. A schema that can drift from the code is worse than no schema, because it will be trusted.

## Why this matters now

The most common failure when an LLM writes a Potato config is inventing an `annotation_type` that does not exist. Shipping a JSON Schema that editors and agents resolve offline fixes that at the source.

This site's own config builder is built on the same idea: the [playground](/playground) reads Potato's registries and can only emit keys they contain, with a harness that puts every generated config through `validate_cli --strict`.

## Related

- [Playground](/playground) — build a config in the browser
- [Guide: configs your coding agent can check](/docs/guides/configs-your-coding-agent-can-check)
- [Source documentation](https://github.com/davidjurgens/potato/blob/main/docs/api-reference/machine_readable.md)
