> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rootkey.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Records

> Anchor and manage structured, row-level data inside a ROOTKey table. Every write is hashed, integrity-tracked, and versioned by primary key.

## Overview

The **Records API** is the structured-data counterpart to [Files](/api-reference/platform/endpoint/files/get-files). Where a file anchors an opaque binary blob, a record anchors a **row of typed key/value data** — a partner logo entry, an inventory item, a testimonial, an audit event — inside a **table**.

Every record write produces a cryptographic integrity hash and a tamper-evident, per-entity version history, giving you row-level auditability for compliance, forensic, and operational use cases.

<Info>
  Records live in a **table** — a schema-defined container for structured rows. A table is **not** a vault: vaults are folders that store **files** (Files API), whereas tables store **records**. A table's schema defines its columns and — critically — its **primary key**, which drives versioning (see [Versioning](#versioning)).
</Info>

***

## Before you start: the two-place setup

Getting records working is a **two-place setup** — you configure the table in the ROOTKey platform UI first, then use its address + an API key from your application. This is the single most common onboarding snag, so follow it in order.

<Steps>
  <Step title="Create a table and define its schema (platform UI)">
    In the [ROOTKey platform](https://app.rootkey.ai), create a **table** and configure its schema: add each column and pick its type.

    <Warning>
      The **first column is automatically the primary key**. It is what groups a record's versions together (see [Versioning](#versioning)). There is currently no way to designate a different column as the key after creation, so choose your first column deliberately — it should be a stable, unique identifier (e.g. `id`, `slug`, `sku`).
    </Warning>
  </Step>

  <Step title="Copy the table address">
    Copy the table's **address** (`0x…`). You pass this on every API call — as `ownerVault` when writing and as `vaultAddress` when reading.
  </Step>

  <Step title="Create an API key (platform UI)">
    Go to **Developer Tools → API Keys**, create a key, and copy it. The key is shown **only once**. See [API Keys](/pages/api-keys) for details.
  </Step>

  <Step title="Wire it into your app">
    Put the **table address** and the **API key** into your application config/environment. You are now ready to `POST` and `GET` records against `/platform/records`.
  </Step>
</Steps>

***

## Authentication

All record endpoints authenticate with your API key in the `x-api-key` header and are scoped to the organization that owns the key.

```bash theme={null}
curl https://api.rootkey.ai/api-v1/platform/records?vaultAddress=0xYourTableAddress \
  -H "x-api-key: YOUR_API_KEY"
```

Test-mode keys operate on an isolated test dataset; see [Environments](/pages/environments).

***

## Versioning

Records use a **primary-key versioning model** — you don't need to track version numbers yourself.

* The table's **primary key** is its schema's key column (until one is explicitly designated, this is the **first field**, by convention an `id`).
* When you `POST` a record, ROOTKey hashes the value of that key field.
* If **no record with that key exists yet**, the record is stored as a new **root** entity.
* If a **record with the same key already exists**, the new write is automatically stored as a **new version** of that entity — a database-style update. The version's `parentId` points to the entity's root record.

So the simplest — and only — way to create a version is to **`POST` the same primary key again** to [`POST /platform/records`](/api-reference/platform/endpoint/records/create-record). There is **no separate version-creation endpoint**; versioning is a built-in behaviour of the create route, driven entirely by the primary key.

<Note>
  Versioning only kicks in when the table has a schema **and** the payload is a keyed object with a non-empty key value. A payload with no key value (or a table with no schema) is stored as a standalone root record.
</Note>

### Working with record IDs

`POST /platform/records` returns `{ "chainId": … }` and **does not** return the new record's `id`. To obtain a record's `id` — which you need for [versions](/api-reference/platform/endpoint/records/get-record-versions), [history](/api-reference/platform/endpoint/records/get-record-history), [validations](/api-reference/platform/endpoint/records/get-record-validations), and [delete](/api-reference/platform/endpoint/records/delete-record) — read it from [List Records](/api-reference/platform/endpoint/records/list-records): every item carries a reserved `__meta` object:

```json theme={null}
{
  "id": "prod-001",
  "name": "ACME Corp",
  "logoUrl": "https://…",
  "__meta": {
    "id": "0f3c1e77-…",
    "parentId": null,
    "status": "REGISTERED",
    "versionsNumber": 2,
    "createdAt": "2026-07-18T10:12:04.000Z"
  }
}
```

Use `__meta.id` as the `parentId` for versions, and as the `recordId` for history / validations / delete.

***

## Record data

* `recordData` is a JSON object of the columns you want to store. Values are **primitives** (`string`, `number`, `boolean`, ISO `date`, `null`) or nested objects / arrays within the limits below.
* Limits per record: **1 MB** total, **64 KB** per string value, **100 properties**, **10 levels** of nesting, **1,000 elements** per array.
* Keys beginning with `__` (and prototype-polluting keys such as `__proto__`, `constructor`, `prototype`) are stripped on ingest — `__meta` is reserved for ROOTKey.

***

## Endpoints

| Method   | Endpoint                                                                                                      | Description                                                           |
| -------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `GET`    | [`/platform/records`](/api-reference/platform/endpoint/records/list-records)                                  | List records in a table (each item includes its data + `__meta`)      |
| `POST`   | [`/platform/records`](/api-reference/platform/endpoint/records/create-record)                                 | Create a record — or a new version, if its primary key already exists |
| `GET`    | [`/platform/records/{parentId}/versions`](/api-reference/platform/endpoint/records/get-record-versions)       | List the version history of a record                                  |
| `GET`    | [`/platform/records/{recordId}/history`](/api-reference/platform/endpoint/records/get-record-history)         | Activity/audit log for a record (created, versioned, deleted…)        |
| `GET`    | [`/platform/records/{recordId}/validations`](/api-reference/platform/endpoint/records/get-record-validations) | Integrity validation history for a record                             |
| `DELETE` | [`/platform/records/{recordId}`](/api-reference/platform/endpoint/records/delete-record)                      | Soft-delete a record                                                  |

<Note>
  Deletes a record. Provide the `recordId` (path) and the table's `ownerAddress` (query). Once deleted, the record no longer appears in list or fetch responses.
</Note>

***

## Key capabilities

* Anchor structured, schema-defined rows with row-level integrity hashing.
* Automatic primary-key versioning — re-writing the same key creates a new version.
* Full version history, activity/audit history, and validation history per record.
* Cursor-based pagination and filtering (name, date range, status) on listings.
* Delete records you no longer need.

***

## Related

* [Files](/api-reference/platform/endpoint/files/get-files) — anchor unstructured documents instead of structured rows.
* [Vaults](/api-reference/platform/endpoint/vaults/create-vault) — a separate concept: vaults store **files**, tables store **records**.
* [API Keys](/pages/api-keys) — create and scope the key used for the `x-api-key` header.
* [Protocols](/pages/protocols/overview) — how anchoring behaves under the configured protocol.
