# Open change feed

Upseam keeps every API change it tracks as a JSON file, one file per provider
version. The files are open: you can read them without an Upseam account and
use them in your own tools.

> **Note.** The files are published in the `upseam/upseam` repository. That
> publication is not live yet. Until it is, the schema below is available and
> the files are not.

## Where the data lives

The files are in the public [`upseam/upseam`](https://github.com/upseam/upseam)
repository, at `data/changes/<provider>/<version>.json`. For example,
`data/changes/stripe/2022-08-01.json` holds the changes of Stripe API version
`2022-08-01`. The provider ids are the ones in [Providers](providers.md).

Each file has `provider`, `version`, `date` and `events`. Each item of
`events` is one change record.

## The schema

One change record is described by a JSON Schema (draft 2020-12) at a stable
address:

```text
https://docs.upseam.dev/schemas/change-record.v0.json
```

A record has an `id`, a `title`, a `type`, a `breaking` flag, the affected
`products` and `symbols`, a `changelog` link and, when the provider names one,
`retires` and `replacement`. The schema is the full list.

These fields are optional and still proposed: `publisher` says who published
the record, `recipe` holds declarative migration steps, and `kind`, `dates`
and `surface` add a product-level class, dates and the affected endpoints,
models and SDK packages. Records without them are valid.

A `recipe` is data, never code: up to 20 `transforms` of five closed types
(`rename_symbol`, `rename_field`, `remove_field`, `replace_model_id`,
`bump_pin`), up to 5 `examples` and up to 5 `hints`. Every object is closed:
an unknown field or transform type makes the record invalid. Vendor ingest
checks each record against this schema and refuses an invalid one with the
path of the first fault. Upseam applies a recipe without a model, only at the
matched lines, and checks that the diff holds the declared edits and
nothing else. A recipe fix is a simple fix: it opens on its own only when
the user turned Simple fixes on.

Crawler records for model retirements with one named successor carry a
`replace_model_id` recipe. Model retirements list the retired and successor
models in `surface.models`, retired endpoints the page names in
`surface.http`, and `dates.effective` when the page gives an exact shutdown
date. A retirement with no successor, or several, has no recipe.

## Read it without an account

You need no key and no sign-up. Fetch a file from the repository:

```bash
curl -s https://raw.githubusercontent.com/upseam/upseam/main/data/changes/stripe/2022-08-01.json
```

Or clone the repository and read `data/changes/`. To check a record, validate
it against the schema with any JSON Schema 2020-12 validator.

## License

The repository is under the MIT license. You may copy, change and redistribute
the files under its terms.

## What v0 promises

The address above is the v0 schema and it does not move. Inside v0, Upseam
only adds optional fields; it does not remove or rename a field and does not
make an optional field required. A change that breaks readers gets a new
schema at a new address, `change-record.v1.json`, and v0 stays online.
