# Records endpoints

Upload a record, run AI extraction, review and confirm the result, link or unlink people, and move records to the Trash.

Paths are relative to https://kleiobase.com/api/v1. Request and response schemas are in the OpenAPI document at https://kleiobase.com/api/v1/openapi.json.

## List records

`GET /workspaces/{workspace_id}/records`

Each record carries folder_id and tag_ids. Use ids to poll a batch of records in one read.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `limit` (query, optional): Page size. Default 25, max 100.
- `cursor` (query, optional): The next_cursor of the previous page. Opaque.
- `status` (query, optional): Filter by status.
- `folder_id` (query, optional): Only records in this folder.
- `tag_id` (query, optional): Only records with this tag.
- `ids` (query, optional): Only these records: 1 to 50 comma-separated record ids. Ids not in the workspace are left out.

Responses:

- `200`: A page of records.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan.
- `404`: The workspace does not exist or is not visible to this key's owner. Also: folder_id or tag_id is not in this workspace.
- `422`: Invalid limit, cursor, status, folder_id, tag_id or ids, or folder_id is a folder of people.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Upload a record

`POST /workspaces/{workspace_id}/records`

Multipart upload of a JPG or PNG. The record is created as pending; call POST .../process next. Uploads are NOT idempotent: a retry creates another record, and Idempotency-Key is ignored. Counts against both the request and the upload rate limits.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `201`: The created record, in pending.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner.
- `409`: The workspace is archived (writes are refused).
- `422`: Not multipart, no valid file, wrong type or size, or other upload checks failed.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After. Also: the upload burst limit was hit.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Get a record

`GET /workspaces/{workspace_id}/records/{record_id}`

Poll this after POST .../process until status is review or failed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.

Responses:

- `200`: The record.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan.
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Edit a record's title or type

`PATCH /workspaces/{workspace_id}/records/{record_id}`

At least one of title and record_type. There is no date field: dates live in the extraction. Changing record_type returns 409 while the record is processing. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `200`: The updated record.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The record type cannot change while the record is processing.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Move a record to Trash

`DELETE /workspaces/{workspace_id}/records/{record_id}`

No body. The record can be restored with POST .../trash/restore. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Responses:

- `200`: Moved to Trash.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The record is still being processed.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Move many records to Trash

`POST /workspaces/{workspace_id}/records/delete`

All or nothing: every id must be a live record in this workspace and none may be processing, or nothing is moved. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `200`: Moved to Trash.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: A record does not exist, is not visible, or is already in Trash.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: A record is still being processed.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422. Also: Invalid body: 1 to 100 UUIDs.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Get a signed image URL

`GET /workspaces/{workspace_id}/records/{record_id}/image`

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `variant` (query, optional): original (default): the uploaded file. thumbnail: the stored 1000 px WebP preview.

Responses:

- `200`: A signed URL valid for 5 minutes.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan.
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible, or (variant=thumbnail) it has no stored thumbnail.
- `422`: Invalid variant.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Start AI extraction

`POST /workspaces/{workspace_id}/records/{record_id}/process`

Asynchronous. Returns 202 once credits are charged; the extraction then runs in the background. Poll GET .../records/{record_id} until status is review or failed. A 409 'already being processed' can last up to about 35 minutes after a crashed run, until the cleanup sweep recovers it. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `202`: Processing started.
- `401`: Missing, malformed, unknown or revoked API key.
- `402`: Not enough credits. details has used, limit, credits_remaining and shortfall.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The record is not in a processable state, or it is already being processed.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After. Also: too many records are processing at once.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Get the extraction

`GET /workspaces/{workspace_id}/records/{record_id}/extraction`

For review before confirm, and still readable after it.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.

Responses:

- `200`: The stored extraction.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan.
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The record has no extraction yet (pending, processing or failed).
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Replace the extraction

`PATCH /workspaces/{workspace_id}/records/{record_id}/extraction`

Send the whole edited extraction. Nothing is created until you confirm. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `200`: The stored extraction.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The record is not in review.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Confirm a reviewed record

`POST /workspaces/{workspace_id}/records/{record_id}/confirm`

Creates people, links and families from the stored extraction. Without an Idempotency-Key, a retry after success returns 409 because the record is already confirmed. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Responses:

- `200`: Confirmed. Returns the linked people.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required). Also: confirming would exceed the plan's person limit (details has used, limit, attempted).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The record is not in review, or it has no extraction.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Link a person to a record

`POST /workspaces/{workspace_id}/records/{record_id}/people`

Matching is queued, never run inline. Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `201`: Linked.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record or person does not exist or is not visible.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress. Also: The person is already linked to this record.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

## Unlink a person from a record

`DELETE /workspaces/{workspace_id}/records/{record_id}/people`

Replays of an Idempotency-Key return the original body and request_id; headers are not replayed.

Parameters:

- `workspace_id` (path, required): The workspace (project) id.
- `record_id` (path, required): The record id.
- `Idempotency-Key` (header, optional): Makes the write safe to retry (1-255 characters, kept 24 hours). Same key and same request replays the original response; a different request with the same key is a 409.

Takes a request body; see the OpenAPI document for its schema.

Responses:

- `200`: Unlinked.
- `401`: Missing, malformed, unknown or revoked API key.
- `403`: The account has no paid plan, or the key is read-only (a read_write key is required).
- `404`: The workspace does not exist or is not visible to this key's owner. Also: The record or person does not exist, or they are not linked.
- `409`: The workspace is archived (writes are refused). Also: Idempotency-Key was reused with a different request, or a request with it is still in progress.
- `422`: Validation failed. A bad Idempotency-Key (1-255 characters) is also a 422.
- `429`: Rate limit exceeded. Wait the number of seconds in Retry-After.
- `500`: Unexpected error. Retry later and quote request_id if it persists.

Canonical: https://kleiobase.com/developers/docs/reference/records
