# Overview

Define a custom data schema, publish it as a version, and store records against it.

A collection is a custom data schema — the structured-data store behind
[forms](/forms/overview), and usable on its own for anything you would
otherwise add a table for.

Three levels, and the middle one is the part worth understanding:

| Level          | What it is                                 |
| -------------- | ------------------------------------------ |
| **Collection** | The named thing, with a slug. Long-lived   |
| **Version**    | One immutable set of field definitions     |
| **Record**     | One row, stored against a specific version |

```bash
curl https://api.console.buildbase.app/api/collections \
  -H "Authorization: $BUILDBASE_TOKEN"
```

> **Note:**
  Build collections in the BuildBase console under **Collections**. Every
  endpoint here is token-authenticated — there is no public read path, so a
  collection is not a substitute for a public CMS API.


## Versions are the schema

Fields do not live on the collection. They live on a version, so changing the
schema means publishing a new version rather than editing the old one — and
records stay readable against the version they were written under.

A version is created with `live: false`. Setting `live: true` publishes it.

> **Note:**
  **A live version cannot be edited.** `PATCH` on one returns `400` with
  "Cannot update live version". This is deliberate — records already point at
  it, so editing its fields would change the meaning of stored data.

To change a schema, create a new version and publish that.



## Field types

Eight types, defined per field on a version:

| Type        | Notes                         |
| ----------- | ----------------------------- |
| `text`      | Default                       |
| `rich-text` | Long-form content             |
| `number`    |                               |
| `bool`      | Note the name — not `boolean` |
| `date`      |                               |
| `color`     |                               |
| `link`      |                               |
| `email`     |                               |

Each field carries `slug`, `title`, `helpText`, `type`, `required`, and
`defaultValue`. The `slug` is the key records are stored under.

## Endpoints

| Method   | Path                                                 | Purpose                      |
| -------- | ---------------------------------------------------- | ---------------------------- |
| `GET`    | `/api/collections`                                   | List collections             |
| `GET`    | `/api/collections/:id`                               | One collection               |
| `POST`   | `/api/collections`                                   | Create                       |
| `PATCH`  | `/api/collections/:id`                               | Update name or slug          |
| `DELETE` | `/api/collections/:id`                               | Delete                       |
| `GET`    | `/api/collections/:collectionId/versions`            | List versions                |
| `GET`    | `/api/collections/:collectionId/versions/:versionId` | One version, with its fields |
| `POST`   | `/api/collections/:collectionId/versions`            | Create a draft version       |
| `PATCH`  | `/api/collections/:collectionId/versions/:id`        | Edit a non-live version      |
| `DELETE` | `/api/collections/:collectionId/versions/:id`        | Delete a version             |
| `GET`    | `/api/collections/chart`                             | Record counts over time      |

Reading and deleting records is covered in
[the records API](/collections/records-api).

## How forms use this

A form is a collection plus a published version plus a public endpoint. Every
submission becomes a record carrying `collectionId`, `versionId`, `formId`, and
the submitted `data`.

That is why a form cannot exist without a published version, and why changing a
form's fields means publishing a new collection version.

The one difference: form submissions arrive through the **public** endpoint,
which needs no token. Everything on this page does.

## Next Steps

- [Records API](/collections/records-api) — read and delete stored records.
- [Forms](/forms/overview) — collect records from a public endpoint.
