# Control API reference

> Where the generated OpenAPI reference lives, how API groups are versioned, which license tier each group needs, and how errors are shaped.

The Control API's actual endpoints, request/response schemas, and error shapes are generated directly from the running system, not maintained by hand here: this page is a map to that generated reference, plus the handful of things worth knowing before you go read it. Where the reference actually lives Interactive docs: /control/docs : a browsable reference (unauthenticated, so you can read it without a key), rendered from the live OpenAPI spec. Raw OpenAPI spec: /control/api/openapi.json : the same spec as plain JSON, useful for generating a client or importing into your own API tooling. Both reflect exactly what this running instance of Buttons actually supports: always check them directly for the current endpoint list, parameters, and schemas rather than relying on a separate written copy that can drift out of date. How versioning works Each API group (Cuelists, Connections, Positions, Surfaces, Workflows, Tags, Backups, Routing) is versioned independently. When a group needs a breaking change, Buttons introduces a new version path alongside the existing one (for example, /control/cuelist/v2 next to /control/cuelist/v1 ) rather than changing v1 's behavior out from under existing integrations. Older versions keep working after an upgrade, but will eventually be deprecated and removed, so prefer the latest version documented for a group when starting new work. Each endpoint's entry in the generated docs notes the Buttons version it was introduced in, so you can tell whether a given capability is available on the version you're running. License tier required per group API group Minimum license tier Backups Individual Connections Individual Cuelists Individual Positions Individual Surfaces Individual Tags Individual Workflows Individual Routing Pro A key's own permissions (see Get started with the Control API ) still control exactly what it can do within a group: the license tier above is a separate, prerequisite gate on the group as a whole. How errors are shaped Every response uses one of a small, shared set of error shapes ( { message, code } ) rather than each endpoint inventing its own. A handful of these apply across the whole API regardless of which endpoint you call: Forbidden , Too Many Requests , and two license-related errors for an under-licensed group or an exhausted license. Beyond those, each endpoint's own documented errors (for example, Not Found or Conflict ) are listed specifically for that endpoint in the generated reference: don't assume every endpoint can return every error code; check the specific endpoint's entry. A separately-shaped validation error ( { message, errors: [{ path, message }] } ) can also appear when a request itself doesn't match the expected schema: this is distinct from the tagged error codes above and reflects a request that failed input validation before reaching your endpoint's own logic. If you get stuck What you see What to try You're not sure if an endpoint exists on your version. Check /control/docs on your own running instance: it always reflects what's actually available, and each endpoint notes its introduction version. A response's error doesn't match what you expected. Check whether it's one of the whole-API errors (Forbidden, Too Many Requests, license-related) or an endpoint-specific one documented on that particular endpoint. You're building against v1 of a group and heard v2 exists. Both keep working: there's no forced cutover, but prefer v2 for anything new. You need a machine-readable spec for codegen. Use /control/api/openapi.json directly rather than the interactive docs page. Where to go next Get started with the Control API Secure and monitor the Control API
