# impartire API — Reference: Records

Every path is under `https://impartire.com/api/v1`. The machine-readable contract is https://impartire.com/api/v1/openapi.json (OpenAPI 3.1).

#### GET /api/v1/records

List one record type's records

`type_id` is required: records are listed one type at a time. Newest first unless `sort` says otherwise. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`); a deleted record leaves the list. Each record carries its `fields` and its `references` resolved to names. For an OAuth token, records its person may not read are left out (a page may be short and still have a next one) and the fields they may not read are stripped. All 404 when the org does not have custom records.

Scopes: `records:read`

Parameters:

- `type_id` (query, string (uuid), required) — Required: the record type whose records to list (GET /api/v1/record-types).
- `q` (query, string) — Case-insensitive substring of the record's title. Characters are matched literally.
- `project_id` (query, string (uuid)) — Only records filed under this project (GET /api/v1/projects).
- `updated_after` (query, string (date-time)) — Only records changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — pass the newest `updated_at` you have seen and that record is not returned again.
- `sort` (query, "created_at" | "-created_at" | "title" | "-title" | "updated_at" | "-updated_at") — Sort key; a leading `-` is descending. Default `-created_at` (newest first, as the app lists them). Ties break on id.
- `limit` (query, integer) — Page size, default 50. Values above 100 are treated as 100.
- `cursor` (query, string) — next_cursor from the previous page, with the other parameters unchanged.

Response 200 — `RecordList`

- `data` (array of Record, required)
  - `id` (string (uuid), required)
  - `type` (object, required) — Its record type (GET /api/v1/record-types).
    - `id` (string (uuid), required)
    - `name` (string, required)
  - `title` (string, required)
  - `fields` (object (any keys), required) — Field values keyed by field key, as defined by the record type. For an OAuth token, the fields its person may not read are left out.
  - `references` (array of RecordReference, required) — Every value of the reference fields in `fields`, resolved to a name, in the type's field order then value order.
    - `field_key` (string, required) — The reference field the value is stored under in `fields`.
    - `record` (object or null, required) — Set when the field points at a record.
      - `id` (string (uuid), required)
      - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
    - `asset` (object or null, required) — Set when the field points at an asset (by the id stored in `fields`).
      - `id` (string (uuid), required)
      - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
    - `project` (object or null, required) — Set when the field points at a project.
      - `id` (string (uuid), required)
      - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `project` (ProjectRef or null, required) — A project the record is filed under, or null. Informational: records are org-wide, and who may read one does not depend on it.
    - `id` (string (uuid), required)
    - `name` (string, required)
  - `edit_seq` (integer, required) — Increments on every change to title, fields, type or project. The first part of the ETag; If-Match on PATCH compares it.
  - `created_at` (string (date-time), required)
  - `updated_at` (string (date-time), required)
- `next_cursor` (string or null, required) — Pass as `cursor` to get the next page; null means this is the last page. For an OAuth token a page may hold fewer than `limit` records (those its person may not read are left out) and still have a next page.

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 422 (Problem) — validation — a missing or unknown `type_id` (an asset type's id included), an unknown `project_id`, or a bad `limit`, `updated_after`, `sort` or `cursor`.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.

#### POST /api/v1/records

Create a record

`fields` is validated against the record type (GET /record-types): a reference field holds the target's id (an array when `multiple`) — a live asset, a record of the declared type, or a project of the org. Its reference edges are written with the record. `project_id` files it under a project; it does not change who may read it (records are org-wide). An OAuth token's person needs create_asset in the org (the app's permission for records), and may not send a field they cannot read. All 404 when the org does not have custom records.

Scopes: `records:write`

Parameters:

- `Idempotency-Key` (header, string) — Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.

Request body — `CreateRecordRequest`

- `type_id` (string (uuid), required) — A record type from GET /api/v1/record-types.
- `title` (string, required) — Leading and trailing spaces are trimmed; it may not be blank.
- `fields` (object (any keys)) — Field values keyed by field key, validated against the record type (a reference: the target's id, or an array of ids when `multiple`).
- `project_id` (string (uuid)) — File the record under this project (GET /api/v1/projects). Informational: it does not change who may read it.

Response 201 — `Record`: An instance of a record type: a title, a field bag and resolved references.

- `id` (string (uuid), required)
- `type` (object, required) — Its record type (GET /api/v1/record-types).
  - `id` (string (uuid), required)
  - `name` (string, required)
- `title` (string, required)
- `fields` (object (any keys), required) — Field values keyed by field key, as defined by the record type. For an OAuth token, the fields its person may not read are left out.
- `references` (array of RecordReference, required) — Every value of the reference fields in `fields`, resolved to a name, in the type's field order then value order.
  - `field_key` (string, required) — The reference field the value is stored under in `fields`.
  - `record` (object or null, required) — Set when the field points at a record.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `asset` (object or null, required) — Set when the field points at an asset (by the id stored in `fields`).
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `project` (object or null, required) — Set when the field points at a project.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
- `project` (ProjectRef or null, required) — A project the record is filed under, or null. Informational: records are org-wide, and who may read one does not depend on it.
  - `id` (string (uuid), required)
  - `name` (string, required)
- `edit_seq` (integer, required) — Increments on every change to title, fields, type or project. The first part of the ETag; If-Match on PATCH compares it.
- `created_at` (string (date-time), required)
- `updated_at` (string (date-time), required)

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope, or insufficient-permission — an OAuth token's person may not create records, or sent a field they cannot read.
- 404 (Problem) — not-found.
- 409 (Problem) — idempotency-in-flight.
- 422 (Problem) — validation (type_id, title, project_id, or `fields.<key>` naming each invalid value), or idempotency-mismatch.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — authorization-write-failed — the record's permissions could not be written, so it was rolled back; or internal.

#### GET /api/v1/records/{id}

Get one record

Scopes: `records:read`

Parameters:

- `id` (path, string (uuid), required) — The record's id, from GET /api/v1/records?type_id=.
- `If-None-Match` (header, string) — An ETag from a previous response; 304 if unchanged.

Response 200 — `Record`: An instance of a record type: a title, a field bag and resolved references.

- `id` (string (uuid), required)
- `type` (object, required) — Its record type (GET /api/v1/record-types).
  - `id` (string (uuid), required)
  - `name` (string, required)
- `title` (string, required)
- `fields` (object (any keys), required) — Field values keyed by field key, as defined by the record type. For an OAuth token, the fields its person may not read are left out.
- `references` (array of RecordReference, required) — Every value of the reference fields in `fields`, resolved to a name, in the type's field order then value order.
  - `field_key` (string, required) — The reference field the value is stored under in `fields`.
  - `record` (object or null, required) — Set when the field points at a record.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `asset` (object or null, required) — Set when the field points at an asset (by the id stored in `fields`).
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `project` (object or null, required) — Set when the field points at a project.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
- `project` (ProjectRef or null, required) — A project the record is filed under, or null. Informational: records are org-wide, and who may read one does not depend on it.
  - `id` (string (uuid), required)
  - `name` (string, required)
- `edit_seq` (integer, required) — Increments on every change to title, fields, type or project. The first part of the ETag; If-Match on PATCH compares it.
- `created_at` (string (date-time), required)
- `updated_at` (string (date-time), required)

Other responses:

- 304 — Not modified — the ETag in If-None-Match is current.
- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.

#### PATCH /api/v1/records/{id}

Retitle a record or replace its fields

If-Match is required: the ETag from the last GET (or the create), or the bare `edit_seq`. `fields` replaces the whole bag (send back what GET returned, changed) and the reference edges follow it. An unknown field (`type_id`, `project_id`) is a 422. An OAuth token's person needs edit on the record; a field they cannot read is kept as it was and may not be sent. All 404 when the org does not have custom records.

Scopes: `records:write`

Parameters:

- `id` (path, string (uuid), required) — The record's id, from GET /api/v1/records?type_id=.
- `If-Match` (header, string, required) — The record's ETag, or its bare edit_seq.

Request body — `UpdateRecordRequest`: At least one of title, fields. Changing a record's type or project is not in v1; an unknown field is a 422.

- `title` (string) — Leading and trailing spaces are trimmed; it may not be blank.
- `fields` (object (any keys)) — The record's whole field bag, validated against its type: keys left out are removed (send back what GET returned, changed). Legacy `<key>__legacy` values are carried forward unless sent as null. For an OAuth token, a field its person may not read is kept as it was.

Response 200 — `Record`: An instance of a record type: a title, a field bag and resolved references.

- `id` (string (uuid), required)
- `type` (object, required) — Its record type (GET /api/v1/record-types).
  - `id` (string (uuid), required)
  - `name` (string, required)
- `title` (string, required)
- `fields` (object (any keys), required) — Field values keyed by field key, as defined by the record type. For an OAuth token, the fields its person may not read are left out.
- `references` (array of RecordReference, required) — Every value of the reference fields in `fields`, resolved to a name, in the type's field order then value order.
  - `field_key` (string, required) — The reference field the value is stored under in `fields`.
  - `record` (object or null, required) — Set when the field points at a record.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `asset` (object or null, required) — Set when the field points at an asset (by the id stored in `fields`).
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
  - `project` (object or null, required) — Set when the field points at a project.
    - `id` (string (uuid), required)
    - `name` (string or null, required) — The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.
- `project` (ProjectRef or null, required) — A project the record is filed under, or null. Informational: records are org-wide, and who may read one does not depend on it.
  - `id` (string (uuid), required)
  - `name` (string, required)
- `edit_seq` (integer, required) — Increments on every change to title, fields, type or project. The first part of the ETag; If-Match on PATCH compares it.
- `created_at` (string (date-time), required)
- `updated_at` (string (date-time), required)

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope, or insufficient-permission — an OAuth token's person may read the record but not edit it, or sent a field they cannot read.
- 404 (Problem) — not-found.
- 412 (Problem) — precondition-failed — If-Match is stale; `edit_seq` in the body is the current one.
- 422 (Problem) — validation (empty body, an unknown field, title, or `fields.<key>` naming each invalid value).
- 428 (Problem) — precondition-required — no If-Match.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.

#### DELETE /api/v1/records/{id}

Delete a record

Soft-deletes the record; it no longer appears in reads, lists or referenced-by. No If-Match: a second DELETE is a 404. An OAuth token's person needs delete on the record. All 404 when the org does not have custom records.

Scopes: `records:write`

Parameters:

- `id` (path, string (uuid), required) — The record's id, from GET /api/v1/records?type_id=.

Other responses:

- 204 — Deleted.
- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope, or insufficient-permission — an OAuth token's person may read the record but not delete it.
- 404 (Problem) — not-found.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.
