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

# Objects and records API

> Discover your schema and create, update, archive, or restore records.

Objects define the structure of your workspace data. Records hold values for an object, such as a client or project. Discover your workspace's schema before constructing write requests.

## Endpoints

Paths below are relative to `https://api.getkato.io/v1`.

| Method | Path                      | Scope            | Result                                 |
| ------ | ------------------------- | ---------------- | -------------------------------------- |
| GET    | `/objects`                | `objects:read`   | All objects                            |
| GET    | `/objects/:object/fields` | `objects:read`   | Field definitions                      |
| GET    | `/records`                | `records:read`   | Paginated records                      |
| GET    | `/records/:id`            | `records:read`   | One record, including archived records |
| POST   | `/records`                | `records:write`  | Create a record                        |
| PUT    | `/records/:id`            | `records:write`  | Upsert with a caller-supplied UUID     |
| PATCH  | `/records/:id`            | `records:write`  | Merge supplied field values            |
| DELETE | `/records/:id`            | `records:write`  | Archive a record                       |
| POST   | `/records/:id/restore`    | `records:write`  | Restore an archived record             |
| POST   | `/records/:id/comments`   | `comments:write` | Add an activity comment                |

## Discover objects and fields

List objects using `GET /objects`. Each entry includes `id`, `slug`, `singularName`, `pluralName`, and `createdAt`. Both object IDs and slugs work in field discovery and record creation.

Set `KATO_OBJECT` to an object ID or slug returned by your workspace:

```bash theme={null}
curl --fail-with-body --silent --show-error \
  "https://api.getkato.io/v1/objects/$KATO_OBJECT/fields" \
  -H "Authorization: Bearer $KATO_API_KEY"
```

Each field includes `id`, `slug`, `name`, `type`, `required`, `primary`, `readOnly`, and `options`. Check the field type and options when forming a value. Read-only fields, including enriched fields and the system record ID, are ignored on writes.

Write requests accept field IDs or slugs in `values`. Unknown fields are rejected. If a slug is ambiguous, use its field ID; supply each field only once.

## List and retrieve

```bash theme={null}
curl --fail-with-body --silent --show-error --get \
  https://api.getkato.io/v1/records \
  -H "Authorization: Bearer $KATO_API_KEY" \
  --data-urlencode "object=$KATO_OBJECT" \
  --data-urlencode "limit=25"
```

The `object` filter is optional. Add `include_archived=true` to include archived records. Continue with `next_cursor` as described in [pagination](/api-reference/authentication#pagination).

A record contains `id`, `objectTypeId`, `title`, `avatarUrl`, `values`, `archived`, `createdBy`, `createdAt`, and `updatedAt`. **Response `values` are keyed by field ID**, even when you wrote them using slugs. Keep the field definitions available to map IDs to names.

## Record response

Single-record operations return `{ "data": record }`; listing returns the same record model in a `data` array with pagination metadata.

| Field                    | Type           | Meaning                                                                  |
| ------------------------ | -------------- | ------------------------------------------------------------------------ |
| `id`                     | string         | Record ID; UUID-based upsert uses your supplied UUID.                    |
| `objectTypeId`           | string         | Object this record belongs to.                                           |
| `title`                  | string         | Display title derived from the record's primary field.                   |
| `avatarUrl`              | string or null | Display avatar when available.                                           |
| `values`                 | object         | Values keyed by field ID; use field definitions to interpret each value. |
| `archived`               | boolean        | Whether the record is archived.                                          |
| `createdBy`              | string         | Creator's auth-user ID.                                                  |
| `createdAt`, `updatedAt` | string         | ISO 8601 creation and last-update date-times.                            |

Do not write `title`, `archived`, or timestamps directly. Update the appropriate field through `values`, and use the archive or restore endpoints for lifecycle changes.

## Create a record

The following example assumes your workspace has a `clients` object with a writable text field whose slug is `name`. Replace both with values from your schema.

```bash theme={null}
curl --fail-with-body --silent --show-error \
  https://api.getkato.io/v1/records \
  -H "Authorization: Bearer $KATO_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "object": "clients",
    "values": {
      "name": "Northlane"
    }
  }'
```

Supply exactly one of `object` (ID or slug) or the backwards-compatible `object_type_id`. Supply any values required by the object. The API returns the created record under `data` with status `201`.

## Update field values

Set `KATO_RECORD_ID` to the ID of an active record. This example uses the same `name` field assumption as creation.

```bash theme={null}
curl --fail-with-body --silent --show-error \
  -X PATCH "https://api.getkato.io/v1/records/$KATO_RECORD_ID" \
  -H "Authorization: Bearer $KATO_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"values":{"name":"Northlane Studio"}}'
```

Only supplied fields are merged into the record; omitted fields retain their values. Archived records must be restored before patching.

## Upsert with a stable ID

For an external sync, generate and persist a UUID for each external record, then call `PUT /records/:id` with that same UUID on subsequent syncs.

```bash theme={null}
curl --fail-with-body --silent --show-error \
  -X PUT "https://api.getkato.io/v1/records/$KATO_RECORD_UUID" \
  -H "Authorization: Bearer $KATO_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"object":"clients","values":{"name":"Northlane"}}'
```

`KATO_RECORD_UUID` must be a valid UUID that you manage for this record. A new ID creates a record (`201`); an existing record in the same workspace and object merges supplied values (`200`). A conflicting ID belonging to another workspace or object returns `409`. Upsert does not automatically restore an archived record.

This pattern avoids creating a new record ID on every sync. It does not provide a general exactly-once guarantee for downstream automation or webhook processing.

## Archive and restore

`DELETE` archives the record rather than permanently erasing it:

```bash theme={null}
curl --fail-with-body --silent --show-error \
  -X DELETE "https://api.getkato.io/v1/records/$KATO_RECORD_ID" \
  -H "Authorization: Bearer $KATO_API_KEY"
```

To restore:

```bash theme={null}
curl --fail-with-body --silent --show-error \
  -X POST "https://api.getkato.io/v1/records/$KATO_RECORD_ID/restore" \
  -H "Authorization: Bearer $KATO_API_KEY"
```

Both operations return the record under `data`. Repeatedly archiving an already archived record is supported. Subscribe to [record webhooks](/api-reference/webhooks/events) to respond to future changes.


## Related topics

- [Bring your data into Kato](/documentation/importing-data.md)
- [Developer quickstart](/api-reference/quickstart.md)
- [Browse object records](/api-reference/raycast/object-records.md)
- [List objects](/api-reference/objects/list.md)
- [List object fields](/api-reference/objects/fields.md)
