---
title: "Versioning"
description: "The API is versioned in its path and announces its contract version on every response. How deprecation works, and how page code is versioned."
canonical: "https://gtable.app/docs/api/versioning"
updated: "2026-10-05"
---

# Versioning

## The API

The version is in the path: `/v1`. Every response names the contract version that answered in
the `x-gtable-api-version` header, and the OpenAPI document carries the same number in
`info.version`.

- **Additive changes ship without a new path**: a new operation, a new optional parameter, a new
  key in a response. Write clients that ignore keys they do not know.
- **Operation names never change silently.** They are also the MCP tool names and the CLI
  commands, so renaming one would break agents and scripts without warning. An operation being
  retired is marked `deprecated` in the reference and answers with a `Deprecation` header and a
  `Link` to what replaces it. Once it has a date after which it may stop answering, a `Sunset`
  header says when. No operation is deprecated today.
- Renaming or removing a key in a body or a query goes through the same deprecation.
- A breaking change to many operations at once would be a new path, `/v2`.

## Pages

A page's code is stored as **immutable versions**. Every save builds a new version and keeps the
old ones; publishing points the page at one of them. So:

- rolling back is publishing an older version, with no rebuild;
- two people using a page during a publish each keep the version they loaded;
- `pages.versions` lists every version with who saved it, when, and whether it built.

```http
GET  /v1/apps/{appId}/pages/{pageId}/versions
POST /v1/apps/{appId}/pages/{pageId}/publish      { "version": 4 }
```

To keep editing from an older version, read its code with `GET …/code?version=4` and save it as a
new version.

## Records

Every write appends to the app's history: who, when, how it arrived, and the record before and
after. See [Undo and history](/docs/api/undo).
