# KolleK API reference Base URL: `https://getkollek.com/api` # Getting started ## Introduction `GET https://getkollek.com/api/health` The KolleK API gives you programmatic access to everything in your account: collections, collection types, custom fields and locations. The API is organized around REST, returns JSON on every endpoint, and loosely follows the JSON:API specification for response shapes. There is no test mode. Every request is processed against your production account, so be careful with destructive calls. The API does not support bulk updates. Work on one object per request. ### Example request ```bash curl https://getkollek.com/api/health \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "message": "ok", "services": { "database": "up" } } ``` ## Authentication `GET https://getkollek.com/api/me` Authenticate every request with a bearer token in the Authorization header. Get a token by registering or logging in through the API, or create one from your profile settings, under API keys. Tokens do not expire, but you can revoke them at any time from your profile or through the API keys endpoints. If two-factor authentication is enabled on your user, the login endpoint also requires a valid TOTP or recovery code. ### Example request ```bash curl https://getkollek.com/api/me \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "user", "id": "1", "attributes": { "first_name": "Monica", "last_name": "Geller", "nickname": "Mon", "email": "monica@example.com", "locale": "en", "time_format_24h": true }, "links": { "self": "https://getkollek.com/api/me" } } } ``` ## Rate limits `GET https://getkollek.com/api/collections` Authenticated endpoints are limited to 60 requests per minute per user. The register and login endpoints are limited to 6 requests per minute. Requests over the limit return 429 with a Retry-After header telling you how many seconds to wait. ### Example request ```bash curl https://getkollek.com/api/collections \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 429` ```json { "message": "Too Many Attempts." } ``` ## Pagination `GET https://getkollek.com/api/collections` Every list endpoint is paginated. Pass per_page to control the page size (between 1 and 100) and page to move through the results. Responses include links and meta objects to navigate between pages. ### Query parameters - `per_page` (integer, optional): The number of objects to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. ### Example request ```bash curl https://getkollek.com/api/collections?per_page=1&page=2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "collection", "id": "2", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "Vinyl", "description": null, "emoji": "๐Ÿ’ฟ", "visibility": "shared", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/2" } } ], "links": { "first": "https://getkollek.com/api/collections?page=1", "last": "https://getkollek.com/api/collections?page=2", "prev": "https://getkollek.com/api/collections?page=1", "next": null }, "meta": { "current_page": 2, "from": 2, "last_page": 2, "links": [ { "url": "https://getkollek.com/api/collections?page=1", "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collections?page=1", "label": "1", "active": false }, { "url": "https://getkollek.com/api/collections?page=2", "label": "2", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collections", "per_page": 1, "to": 2, "total": 2 } } ``` ## Errors `POST https://getkollek.com/api/collections` The API uses conventional HTTP status codes: 2xx for success, 4xx for request errors, 5xx for server errors. Requests for an object that does not exist in your account return 404, and so do write requests made with a role that does not allow them. Validation failures return 422 with a message and an errors object keyed by field name. Authentication failures return 401 with a message. ### Example request ```bash curl https://getkollek.com/api/collections \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "visibility": "private" }' ``` ### Example response `Status: 422` ```json { "message": "The name field is required.", "errors": { "name": [ "The name field is required." ] } } ``` # Health ## Check the API status `GET https://getkollek.com/api/health` Check that the API and its underlying services are up. This endpoint requires no authentication and is meant for monitoring, or as a first request when setting up a client. **Returns:** An object describing the state of each service, or a 500 status when a service is down. ### Example request ```bash curl https://getkollek.com/api/health \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "message": "ok", "services": { "database": "up" } } ``` # Authentication ## Register `POST https://getkollek.com/api/register` Create a new user with its own account, and receive an API token for it. The token is named after device_name when provided. This endpoint is limited to 6 requests per minute. ### Body parameters - `first_name` (string, required): The first name of the user. Maximum 100 characters. - `last_name` (string, required): The last name of the user. Maximum 100 characters. - `email` (string, required): The email address of the user. Must be lowercase, unique, and not from a disposable email provider. - `password` (string, required): Minimum 8 characters. The password is checked against known data leaks, and a compromised password is rejected. - `password_confirmation` (string, required): Must match password. - `device_name` (string, optional): A label for the API token that is created, such as the name of your app or device. **Returns:** A confirmation message and the API token to use on subsequent requests. ### Example request ```bash curl https://getkollek.com/api/register \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Monica", "last_name": "Geller", "email": "monica@example.com", "password": "a-very-strong-password", "password_confirmation": "a-very-strong-password", "device_name": "My integration" }' ``` ### Example response `Status: 201` ```json { "message": "Account created", "status": 201, "data": { "token": "1|f9aB2cD3eF4gH5iJ6kL7mN8oP9qR0sT1uV2wX3yZ" } } ``` ## Log in `POST https://getkollek.com/api/login` Exchange credentials for an API token. Invalid credentials return 401. When two-factor authentication is enabled on the user, a valid TOTP or recovery code must be passed in code, otherwise the endpoint returns 401. This endpoint is limited to 6 requests per minute. ### Body parameters - `email` (string, required): The email address of the user. - `password` (string, required): The password of the user. - `code` (string, optional): The TOTP or recovery code. Required when two-factor authentication is enabled on the user. - `device_name` (string, optional): A label for the API token that is created, such as the name of your app or device. **Returns:** A confirmation message and the API token to use on subsequent requests. ### Example request ```bash curl https://getkollek.com/api/login \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "email": "monica@example.com", "password": "a-very-strong-password", "device_name": "My integration" }' ``` ### Example response `Status: 200` ```json { "message": "Authenticated", "status": 200, "data": { "token": "2|aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5a" } } ``` ## Log out `DELETE https://getkollek.com/api/logout` Revoke the token used to make the request. Other tokens of the user stay valid. **Returns:** A confirmation message. ### Example request ```bash curl https://getkollek.com/api/logout \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "message": "Logged out successfully", "status": 200 } ``` # Your profile ## Get your profile `GET https://getkollek.com/api/me` Retrieve the user the token belongs to. **Returns:** A user object. ### Example request ```bash curl https://getkollek.com/api/me \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "user", "id": "1", "attributes": { "first_name": "Monica", "last_name": "Geller", "nickname": "Mon", "email": "monica@example.com", "locale": "en", "time_format_24h": true }, "links": { "self": "https://getkollek.com/api/me" } } } ``` ## Update your profile `PUT https://getkollek.com/api/me` Update the profile of the user the token belongs to. ### Body parameters - `first_name` (string, required): The first name of the user. Maximum 100 characters. - `last_name` (string, required): The last name of the user. Maximum 100 characters. - `nickname` (string, optional): An optional nickname, shown instead of the full name when set. - `email` (string, required): The email address of the user. Must be lowercase, unique, and not from a disposable email provider. - `locale` (string, required): The locale of the user. One of en, fr_FR, es_ES, de_DE, pt_BR, zh_CN or ja_JP. - `time_format_24h` (string, required): Whether the user prefers the 24-hour time format. The string true or false. **Returns:** The updated user object. ### Example request ```bash curl https://getkollek.com/api/me \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Monica", "last_name": "Geller", "nickname": "Mon", "email": "monica@example.com", "locale": "en", "time_format_24h": "true" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "user", "id": "1", "attributes": { "first_name": "Monica", "last_name": "Geller", "nickname": "Mon", "email": "monica@example.com", "locale": "en", "time_format_24h": true }, "links": { "self": "https://getkollek.com/api/me" } } } ``` # Collections ## List collections `GET https://getkollek.com/api/collections` Retrieve the collections of your account, most recently updated first. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of collections to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of collection objects. ### Example request ```bash curl https://getkollek.com/api/collections \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "collection", "id": "2", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "Vinyl", "description": null, "emoji": "๐Ÿ’ฟ", "visibility": "shared", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/2" } }, { "type": "collection", "id": "1", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1" } } ], "links": { "first": "https://getkollek.com/api/collections?page=1", "last": "https://getkollek.com/api/collections?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collections?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collections", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a collection `GET https://getkollek.com/api/collections/{collection}` Retrieve a single collection of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection. **Returns:** A collection object, or 404 when the collection does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collections/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "collection", "id": "1", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1" } } } ``` ## Create a collection `POST https://getkollek.com/api/collections` Create a collection: a named set of items being catalogued, such as My Comics or Vinyl. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the collection. Maximum 255 characters. - `description` (string, optional): A description of the collection. Maximum 2000 characters. - `emoji` (string, optional): The emoji shown next to the collection name. One of ๐Ÿ“ฆ, ๐Ÿ“š, ๐Ÿ’ฟ, ๐Ÿƒ, ๐Ÿท, ๐ŸŽฎ, ๐Ÿงธ, ๐Ÿช™, ๐Ÿ–ผ๏ธ, โŒš, ๐Ÿ‘Ÿ or ๐Ÿ“ท. - `visibility` (string, required): Who the collection is meant for. One of private (you alone), shared (everyone in the account) or public (anyone with the link, read only). The setting is recorded but not enforced yet: every member of the account can read every collection, and public collections have no link to hand out, so nothing is reachable from outside the account. - `currency` (string, optional): The three-letter currency code used for item values, such as USD or EUR. - `collection_type_ids` (array of integers, optional): The IDs of the collection types to link to the collection. IDs that do not belong to your account are ignored. **Returns:** The created collection object. ### Example request ```bash curl https://getkollek.com/api/collections \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD", "collection_type_ids": [ 1 ] }' ``` ### Example response `Status: 201` ```json { "data": { "type": "collection", "id": "1", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1" } } } ``` ## Update a collection `PUT https://getkollek.com/api/collections/{collection}` Update a collection. All the fields below are written on every call, so send the full object, not only the fields that changed. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection. ### Body parameters - `name` (string, required): The name of the collection. Maximum 255 characters. - `description` (string, optional): A description of the collection. Maximum 2000 characters. - `emoji` (string, optional): The emoji shown next to the collection name. One of ๐Ÿ“ฆ, ๐Ÿ“š, ๐Ÿ’ฟ, ๐Ÿƒ, ๐Ÿท, ๐ŸŽฎ, ๐Ÿงธ, ๐Ÿช™, ๐Ÿ–ผ๏ธ, โŒš, ๐Ÿ‘Ÿ or ๐Ÿ“ท. - `visibility` (string, required): Who the collection is meant for. One of private, shared or public. The setting is recorded but not enforced yet. - `currency` (string, optional): The three-letter currency code used for item values, such as USD or EUR. **Returns:** The updated collection object. ### Example request ```bash curl https://getkollek.com/api/collections/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "collection", "id": "1", "attributes": { "uuid": "9e2f6c1a-4b3d-4b6e-9a2f-0c1d2e3f4a5b", "name": "My Comics", "description": "Silver age Marvel issues.", "emoji": "๐Ÿ“š", "visibility": "private", "currency": "USD", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1" } } } ``` ## Delete a collection `DELETE https://getkollek.com/api/collections/{collection}` Delete a collection. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collections/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Collection types ## List collection types `GET https://getkollek.com/api/collection-types` Retrieve the collection types of your account, most recently updated first. A collection type is a user-defined category (Comics, Vinyl, Wine) that decides which custom fields apply to an item. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of collection types to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of collection_type objects. ### Example request ```bash curl https://getkollek.com/api/collection-types \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "collection_type", "id": "2", "attributes": { "name": "Wine", "color": "#8b5cf6", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/2" } }, { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } ], "links": { "first": "https://getkollek.com/api/collection-types?page=1", "last": "https://getkollek.com/api/collection-types?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collection-types?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collection-types", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a collection type `GET https://getkollek.com/api/collection-types/{collectionType}` Retrieve a single collection type of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `collectionType` (integer, required): The ID of the collection type. **Returns:** A collection_type object, or 404 when the type does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collection-types/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } } ``` ## Export a collection type `GET https://getkollek.com/api/collection-types/{collectionType}/export` Retrieve the full schema of a collection type as a portable JSON document: its name, its color, its field groups, and every custom field with its kind, its ordering and its select options. This is the same document the app hands out from the type's export screen. The document describes structure only. Your items, their copies and their photos are never part of it. Fields are ordered the way they render on an item, and a field only carries an options key when it has options. Groups are listed under groups, and fields that sit outside of any group under standaloneFields. The schemaVersion key tells you which shape of the document you are reading. It is bumped whenever the shape changes, so store it alongside the export. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type. **Returns:** A collection_type_export object whose schema attribute is the portable JSON document, or 404 when the type does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/export \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "collection_type_export", "id": "1", "attributes": { "schema": { "schemaVersion": 1, "type": { "name": "Comics", "color": "#fb923c", "groups": [ { "name": "Publishing info", "fields": [ { "name": "Issue #", "type": "number" }, { "name": "Publisher", "type": "select", "options": [ "Marvel", "DC", "Image" ] } ] } ], "standaloneFields": [ { "name": "Signed", "type": "boolean" } ] } } }, "links": { "self": "https://getkollek.com/api/collection-types/1/export", "collection_type": "https://getkollek.com/api/collection-types/1" } } } ``` ## Create a collection type `POST https://getkollek.com/api/collection-types` Create a collection type. Add custom fields to it with the custom fields endpoints, and link it to collections with the sync endpoint below. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the type. Maximum 255 characters. - `color` (string, optional): The color of the type as a six-digit hex code, such as #fb923c. Default: `#6B7280`. **Returns:** The created collection_type object. ### Example request ```bash curl https://getkollek.com/api/collection-types \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Comics", "color": "#fb923c" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } } ``` ## Update a collection type `PUT https://getkollek.com/api/collection-types/{collectionType}` Update the name and color of a collection type. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type. ### Body parameters - `name` (string, required): The name of the type. Maximum 255 characters. - `color` (string, required): The color of the type as a six-digit hex code, such as #fb923c. **Returns:** The updated collection_type object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Comics", "color": "#fb923c" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } } ``` ## Set the collections of a type `PUT https://getkollek.com/api/collection-types/{collectionType}/collections` Set which collections the type applies to. The list you send replaces the previous one entirely. IDs of collections that do not belong to your account are ignored. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type. ### Body parameters - `collection_ids` (array of integers, optional): The IDs of the collections the type applies to. Send an empty array to unlink the type from every collection. **Returns:** The collection_type object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/collections \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "collection_ids": [ 1, 2 ] }' ``` ### Example response `Status: 200` ```json { "data": { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } } ``` ## Delete a collection type `DELETE https://getkollek.com/api/collection-types/{collectionType}` Delete a collection type, together with its custom fields and its links to collections. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collection-types/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## Import a collection type `POST https://getkollek.com/api/collection-types/import` Rebuild a collection type from a JSON document, in the exact shape the export endpoint hands out. This creates a new type with its groups and fields. It never updates an existing one, so importing the same document twice gives you two types. The document is sent as a string in the json parameter, not as a nested object. A document that is not valid JSON, that is missing the type key, or that names a field type the app does not know is rejected with a 422 response. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `json` (string, required): The exported document, as a JSON encoded string. Maximum 100000 characters. **Returns:** The created collection_type object. ### Example request ```bash curl https://getkollek.com/api/collection-types/import \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "json": "{\"schemaVersion\":1,\"type\":{\"name\":\"Comics\",\"color\":\"#fb923c\",\"groups\":[],\"standaloneFields\":[]}}" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "collection_type", "id": "1", "attributes": { "name": "Comics", "color": "#fb923c", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1" } } } ``` # Custom field groups ## List custom field groups `GET https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups` Retrieve the custom field groups of a collection type, in position order. A group is a named section of custom fields within a type, such as Publishing info on Comics. Groups are optional: a type with no groups shows its fields as a flat list. Where a type has both, the fields with no group come first, followed by each group. **Permissions:** Any member of the account. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. ### Query parameters - `per_page` (integer, optional): The number of groups to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of custom_field_group objects. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "custom_field_group", "id": "1", "attributes": { "name": "Publishing info", "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/1" } }, { "type": "custom_field_group", "id": "2", "attributes": { "name": "Condition & grading", "position": 2, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/2" } } ], "links": { "first": "https://getkollek.com/api/collection-types/1/custom-field-groups?page=1", "last": "https://getkollek.com/api/collection-types/1/custom-field-groups?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collection-types/1/custom-field-groups?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collection-types/1/custom-field-groups", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a custom field group `GET https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups/{group}` Retrieve a single custom field group by its ID. The group must belong to the collection type in the URL. **Permissions:** Any member of the account. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. - `group` (integer, required): The ID of the custom field group. **Returns:** A custom_field_group object, or 404 when the group or the type does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field_group", "id": "1", "attributes": { "name": "Publishing info", "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/1" } } } ``` ## Create a custom field group `POST https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups` Create a custom field group on a collection type. The group is appended after the existing ones. To place a field inside it, pass its ID as group_id when creating the custom field. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. ### Body parameters - `name` (string, optional): The name of the group. Maximum 255 characters. **Returns:** The created custom_field_group object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Publishing info" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "custom_field_group", "id": "1", "attributes": { "name": "Publishing info", "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/1" } } } ``` ## Update a custom field group `PUT https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups/{group}` Rename a custom field group. The fields it holds are left alone. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. - `group` (integer, required): The ID of the custom field group. ### Body parameters - `name` (string, optional): The name of the group. Maximum 255 characters. **Returns:** The updated custom_field_group object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Publishing info" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field_group", "id": "1", "attributes": { "name": "Publishing info", "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/1" } } } ``` ## Delete a custom field group `DELETE https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups/{group}` Delete a custom field group. The fields it held are not deleted with it: their group_id becomes null and they become standalone fields on the type, so no value recorded against them is lost. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. - `group` (integer, required): The ID of the custom field group. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## Move a custom field group `PUT https://getkollek.com/api/collection-types/{collectionType}/custom-field-groups/{group}/order` Move a group one step up or down among the groups of its type. This is how the order of the sections on an item form is changed. Moving a group that is already first up, or already last down, leaves the order untouched and still returns a 200 response. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the group belongs to. - `group` (integer, required): The ID of the custom field group. ### Body parameters - `direction` (string, required): The direction to move the group in. One of up or down. **Returns:** The moved custom_field_group object, with its new position. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-field-groups/1/order \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "direction": "down" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field_group", "id": "1", "attributes": { "name": "Publishing info", "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-field-groups/1" } } } ``` # Custom fields ## List custom fields `GET https://getkollek.com/api/collection-types/{collectionType}/custom-fields` Retrieve the custom fields of a collection type, in position order. A custom field is a field definition on a type, such as Issue # on Comics or Vintage on Wine. Its group_id tells you the group it sits in, and is null when the field is standalone. **Permissions:** Any member of the account. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. ### Query parameters - `per_page` (integer, optional): The number of custom fields to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of custom_field objects. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "custom_field", "id": "1", "attributes": { "name": "Issue #", "field_type": "number", "options": null, "position": 1, "group_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/1" } }, { "type": "custom_field", "id": "2", "attributes": { "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 1, "group_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/2" } } ], "links": { "first": "https://getkollek.com/api/collection-types/1/custom-fields?page=1", "last": "https://getkollek.com/api/collection-types/1/custom-fields?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collection-types/1/custom-fields?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collection-types/1/custom-fields", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a custom field `GET https://getkollek.com/api/collection-types/{collectionType}/custom-fields/{customField}` Retrieve a single custom field by its ID. The field must belong to the collection type in the URL. **Permissions:** Any member of the account. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. - `customField` (integer, required): The ID of the custom field. **Returns:** A custom_field object, or 404 when the field or the type does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field", "id": "2", "attributes": { "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 2, "group_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/2" } } } ``` ## Create a custom field `POST https://getkollek.com/api/collection-types/{collectionType}/custom-fields` Create a custom field on a collection type. The field is appended after the existing ones. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. ### Body parameters - `name` (string, optional): The name of the field. Maximum 255 characters. - `field_type` (string, required): The kind of value the field holds. One of text, number, date, boolean, select or rating. A rating stores a whole number of stars from 1 to 5. - `options` (array of strings, optional): The choices of a select field. Blank entries are removed, and the parameter is ignored for the other field types. - `group_id` (integer, optional): The ID of the custom field group to place the field in. The group must belong to the same collection type. When omitted, the field is standalone and sits directly on the type. **Returns:** The created custom_field object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "group_id": 1 }' ``` ### Example response `Status: 201` ```json { "data": { "type": "custom_field", "id": "2", "attributes": { "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 2, "group_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/2" } } } ``` ## Update a custom field `PUT https://getkollek.com/api/collection-types/{collectionType}/custom-fields/{customField}` Update a custom field. Use position to reorder the fields: they are shown in ascending position order within their group, or within the type when the field is standalone. A field cannot be moved between groups. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. - `customField` (integer, required): The ID of the custom field. ### Body parameters - `name` (string, optional): The name of the field. Maximum 255 characters. - `field_type` (string, required): The kind of value the field holds. One of text, number, date, boolean, select or rating. A rating stores a whole number of stars from 1 to 5. - `options` (array of strings, optional): The choices of a select field. Blank entries are removed, and the parameter is ignored for the other field types. - `position` (integer, optional): The position of the field within its group, or within the type when the field is standalone, starting at 1. When omitted, the current position is kept. **Returns:** The updated custom_field object. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 2 }' ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field", "id": "2", "attributes": { "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 2, "group_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/2" } } } ``` ## Delete a custom field `DELETE https://getkollek.com/api/collection-types/{collectionType}/custom-fields/{customField}` Delete a custom field from a collection type. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. - `customField` (integer, required): The ID of the custom field. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields/2 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## Move a custom field `PUT https://getkollek.com/api/collection-types/{collectionType}/custom-fields/{customField}/order` Move a field one step up or down among the fields of its group, or among the standalone fields of the type when it has no group. Use the update endpoint instead to set a position directly. Moving a field that is already first up, or already last down, leaves the order untouched and still returns a 200 response. A field never crosses into another group this way. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collectionType` (integer, required): The ID of the collection type the field belongs to. - `customField` (integer, required): The ID of the custom field. ### Body parameters - `direction` (string, required): The direction to move the field in. One of up or down. **Returns:** The moved custom_field object, with its new position. ### Example request ```bash curl https://getkollek.com/api/collection-types/1/custom-fields/2/order \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "direction": "up" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "custom_field", "id": "2", "attributes": { "name": "Grade", "field_type": "select", "options": [ "NM", "VF", "FN" ], "position": 1, "group_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collection-types/1/custom-fields/2" } } } ``` # Locations ## List locations `GET https://getkollek.com/api/locations` Retrieve the storage locations of your account: the shelves, boxes and rooms where items are physically stored. Locations nest through parent_id; rebuild the tree client side from the flat list. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of locations to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of location objects. ### Example request ```bash curl https://getkollek.com/api/locations \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "location", "id": "1", "attributes": { "name": "Shelf A", "emoji": "๐Ÿ“š", "parent_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/locations/1" } }, { "type": "location", "id": "2", "attributes": { "name": "Box 1", "emoji": "๐Ÿ“ฆ", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/locations/2" } } ], "links": { "first": "https://getkollek.com/api/locations?page=1", "last": "https://getkollek.com/api/locations?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/locations?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/locations", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a location `GET https://getkollek.com/api/locations/{location}` Retrieve a single location of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `location` (integer, required): The ID of the location. **Returns:** A location object, or 404 when the location does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/locations/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "location", "id": "2", "attributes": { "name": "Box 1", "emoji": "๐Ÿ“ฆ", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/locations/2" } } } ``` ## Create a location `POST https://getkollek.com/api/locations` Create a location, optionally nested under another one. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the location. Maximum 255 characters. - `parent_id` (integer, optional): The ID of the parent location, for nesting. Must belong to your account. - `emoji` (string, optional): The emoji shown next to the location name. One of ๐Ÿ“ฆ, ๐Ÿ , ๐Ÿšช, ๐Ÿ›‹๏ธ, ๐Ÿ—„๏ธ, ๐Ÿ“š, ๐Ÿงฐ, ๐Ÿข, ๐Ÿš—, ๐Ÿ—ƒ๏ธ, ๐Ÿ–ผ๏ธ or ๐ŸŽ. **Returns:** The created location object. ### Example request ```bash curl https://getkollek.com/api/locations \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Box 1", "parent_id": 1, "emoji": "๐Ÿ“ฆ" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "location", "id": "2", "attributes": { "name": "Box 1", "emoji": "๐Ÿ“ฆ", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/locations/2" } } } ``` ## Update a location `PUT https://getkollek.com/api/locations/{location}` Update the name, parent and emoji of a location. Moves that would create a cycle are rejected with a 422 response: a location cannot be its own parent, or be nested under one of its own descendants. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `location` (integer, required): The ID of the location. ### Body parameters - `name` (string, required): The name of the location. Maximum 255 characters. - `parent_id` (integer, optional): The ID of the parent location. Omit it or send null to move the location to the top level. - `emoji` (string, optional): The emoji shown next to the location name. One of ๐Ÿ“ฆ, ๐Ÿ , ๐Ÿšช, ๐Ÿ›‹๏ธ, ๐Ÿ—„๏ธ, ๐Ÿ“š, ๐Ÿงฐ, ๐Ÿข, ๐Ÿš—, ๐Ÿ—ƒ๏ธ, ๐Ÿ–ผ๏ธ or ๐ŸŽ. **Returns:** The updated location object. ### Example request ```bash curl https://getkollek.com/api/locations/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Box 1", "parent_id": 1, "emoji": "๐Ÿ“ฆ" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "location", "id": "2", "attributes": { "name": "Box 1", "emoji": "๐Ÿ“ฆ", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/locations/2" } } } ``` ## Delete a location `DELETE https://getkollek.com/api/locations/{location}` Delete a location. Its nested child locations are deleted with it. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `location` (integer, required): The ID of the location. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/locations/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # API keys ## List API keys `GET https://getkollek.com/api/administration/api` Retrieve every API key of your user, including the ones created by logging in. The list is not paginated, and the token attribute is always null: the plain-text token is only shown once, when the key is created. **Returns:** A list of api_key objects. ### Example request ```bash curl https://getkollek.com/api/administration/api \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "api_key", "id": "1", "attributes": { "name": "GitHub Actions", "token": null, "last_used_at": 1752537600, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/api/1" } }, { "type": "api_key", "id": "2", "attributes": { "name": "Login from My integration", "token": null, "last_used_at": 1752537600, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/api/2" } } ] } ``` ## Get an API key `GET https://getkollek.com/api/administration/api/{id}` Retrieve a single API key of your user by its ID. ### Path parameters - `id` (integer, required): The ID of the API key. **Returns:** An api_key object, or 404 when the key belongs to another user. ### Example request ```bash curl https://getkollek.com/api/administration/api/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "api_key", "id": "1", "attributes": { "name": "GitHub Actions", "token": null, "last_used_at": 1752537600, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/api/1" } } } ``` ## Create an API key `POST https://getkollek.com/api/administration/api` Create a new API key for your user. The plain-text token is returned once in this response and cannot be retrieved later, so store it somewhere safe. ### Body parameters - `label` (string, required): A name identifying what the key is used for. Maximum 255 characters. **Returns:** The created api_key object. The plain-text token appears in the token attribute and at the top level of the response. ### Example request ```bash curl https://getkollek.com/api/administration/api \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "label": "GitHub Actions" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "api_key", "id": "1", "attributes": { "name": "GitHub Actions", "token": "3|aB4cD5eF6gH7iJ8kL9mN0oP1qR2sT3uV4wX5yZ6b", "last_used_at": 1752537600, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/api/1" } }, "token": "3|aB4cD5eF6gH7iJ8kL9mN0oP1qR2sT3uV4wX5yZ6b" } ``` ## Delete an API key `DELETE https://getkollek.com/api/administration/api/{id}` Revoke an API key. Requests made with the revoked token stop working immediately. ### Path parameters - `id` (integer, required): The ID of the API key. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/administration/api/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Logs ## List logs `GET https://getkollek.com/api/administration/logs` Retrieve the audit trail of actions performed by your user, most recent first. Logs are created automatically for every action; they cannot be created, changed or deleted through the API. ### Query parameters - `per_page` (integer, optional): The number of logs to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of log objects. ### Example request ```bash curl https://getkollek.com/api/administration/logs \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "log", "id": "2", "attributes": { "user_name": "Monica Geller", "action": "collection_creation", "parameters": { "name": "My Comics" }, "description": "Created the collection My Comics", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/logs/2" } }, { "type": "log", "id": "1", "attributes": { "user_name": "Monica Geller", "action": "account_creation", "parameters": [], "description": "Created the account", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/logs/1" } } ], "links": { "first": "https://getkollek.com/api/administration/logs?page=1", "last": "https://getkollek.com/api/administration/logs?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/administration/logs?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/administration/logs", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a log `GET https://getkollek.com/api/administration/logs/{log}` Retrieve a single log entry of your user by its ID. ### Path parameters - `log` (integer, required): The ID of the log entry. **Returns:** A log object, or 404 when the log belongs to another user. ### Example request ```bash curl https://getkollek.com/api/administration/logs/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "log", "id": "2", "attributes": { "user_name": "Monica Geller", "action": "collection_creation", "parameters": { "name": "My Comics" }, "description": "Created the collection My Comics", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/logs/2" } } } ``` # Emails ## List emails `GET https://getkollek.com/api/administration/emails` Retrieve every email the application sent to your user, most recently sent first, with delivery tracking. Emails cannot be sent, changed or deleted through the API. ### Query parameters - `per_page` (integer, optional): The number of emails to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of email objects. ### Example request ```bash curl https://getkollek.com/api/administration/emails \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "email", "id": "1", "attributes": { "email_type": "welcome", "email_address": "monica@example.com", "subject": "Welcome to Kollek", "body": "Thanks for signing up! Here is how to get started.", "sent_at": 1752537600, "delivered_at": 1752537600, "bounced_at": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/emails/1" } } ], "links": { "first": "https://getkollek.com/api/administration/emails?page=1", "last": "https://getkollek.com/api/administration/emails?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/administration/emails?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/administration/emails", "per_page": 10, "to": 1, "total": 1 } } ``` ## Get an email `GET https://getkollek.com/api/administration/emails/{email}` Retrieve a single sent email of your user by its ID. ### Path parameters - `email` (integer, required): The ID of the sent email. **Returns:** An email object, or 404 when the email belongs to another user. ### Example request ```bash curl https://getkollek.com/api/administration/emails/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "email", "id": "1", "attributes": { "email_type": "welcome", "email_address": "monica@example.com", "subject": "Welcome to Kollek", "body": "Thanks for signing up! Here is how to get started.", "sent_at": 1752537600, "delivered_at": 1752537600, "bounced_at": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/administration/emails/1" } } } ``` # Conditions ## List conditions `GET https://getkollek.com/api/item-conditions` Retrieve the conditions of your account, e.g. New, Used or Damaged, used to describe the state of an item. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of conditions to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of condition objects. ### Example request ```bash curl https://getkollek.com/api/item-conditions \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "item_condition", "id": "1", "attributes": { "name": "New", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/item-conditions/1" } }, { "type": "item_condition", "id": "2", "attributes": { "name": "Used", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/item-conditions/2" } } ], "links": { "first": "https://getkollek.com/api/item-conditions?page=1", "last": "https://getkollek.com/api/item-conditions?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/item-conditions?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/item-conditions", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a condition `GET https://getkollek.com/api/item-conditions/{itemCondition}` Retrieve a single condition of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `itemCondition` (integer, required): The ID of the condition. **Returns:** A condition object, or 404 when the condition does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/item-conditions/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "item_condition", "id": "2", "attributes": { "name": "Used", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/item-conditions/2" } } } ``` ## Create a condition `POST https://getkollek.com/api/item-conditions` Create a condition for your account. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the condition. Maximum 255 characters. **Returns:** The created condition object. ### Example request ```bash curl https://getkollek.com/api/item-conditions \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Used" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "item_condition", "id": "2", "attributes": { "name": "Used", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/item-conditions/2" } } } ``` ## Update a condition `PUT https://getkollek.com/api/item-conditions/{itemCondition}` Update the name of a condition. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `itemCondition` (integer, required): The ID of the condition. ### Body parameters - `name` (string, required): The name of the condition. Maximum 255 characters. **Returns:** The updated condition object. ### Example request ```bash curl https://getkollek.com/api/item-conditions/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Used" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "item_condition", "id": "2", "attributes": { "name": "Used", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/item-conditions/2" } } } ``` ## Delete a condition `DELETE https://getkollek.com/api/item-conditions/{itemCondition}` Delete a condition. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `itemCondition` (integer, required): The ID of the condition. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/item-conditions/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Tags ## List tags `GET https://getkollek.com/api/tags` Retrieve the tags of your account: free-form labels reusable across all your collections, e.g. Signed or First Issue. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of tags to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of tag objects. ### Example request ```bash curl https://getkollek.com/api/tags \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "tag", "id": "1", "attributes": { "name": "Signed", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/1" } }, { "type": "tag", "id": "2", "attributes": { "name": "First Issue", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/2" } } ], "links": { "first": "https://getkollek.com/api/tags?page=1", "last": "https://getkollek.com/api/tags?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/tags?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/tags", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a tag `GET https://getkollek.com/api/tags/{tag}` Retrieve a single tag of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `tag` (integer, required): The ID of the tag. **Returns:** A tag object, or 404 when the tag does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/tags/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "tag", "id": "2", "attributes": { "name": "First Issue", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/2" } } } ``` ## Create a tag `POST https://getkollek.com/api/tags` Create a tag for your account. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the tag. Maximum 255 characters. **Returns:** The created tag object. ### Example request ```bash curl https://getkollek.com/api/tags \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "First Issue" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "tag", "id": "2", "attributes": { "name": "First Issue", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/2" } } } ``` ## Update a tag `PUT https://getkollek.com/api/tags/{tag}` Update the name of a tag. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `tag` (integer, required): The ID of the tag. ### Body parameters - `name` (string, required): The name of the tag. Maximum 255 characters. **Returns:** The updated tag object. ### Example request ```bash curl https://getkollek.com/api/tags/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "First Issue" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "tag", "id": "2", "attributes": { "name": "First Issue", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/2" } } } ``` ## Delete a tag `DELETE https://getkollek.com/api/tags/{tag}` Delete a tag. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `tag` (integer, required): The ID of the tag. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/tags/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## List the tags of an item `GET https://getkollek.com/api/items/{item}/tags` Retrieve the tags attached to an item, oldest first. Tags are shared across the account, so the same tag can be on many items. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item. **Returns:** A list of tag objects, or 404 when the item does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/items/1/tags \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "tag", "id": "1", "attributes": { "name": "Signed", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/1" } }, { "type": "tag", "id": "2", "attributes": { "name": "First Issue", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/2" } } ] } ``` ## Add a tag to an item `POST https://getkollek.com/api/items/{item}/tags` Attach a tag to an item by name. When the account already has a tag with that name it is reused, matching regardless of case, so this never creates duplicates. Otherwise the tag is created first, then attached. Attaching a tag the item already carries is accepted and changes nothing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item. ### Body parameters - `name` (string, required): The name of the tag to attach. Maximum 255 characters. **Returns:** The attached tag object, whether it was reused or created. ### Example request ```bash curl https://getkollek.com/api/items/1/tags \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Signed" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "tag", "id": "1", "attributes": { "name": "Signed", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/tags/1" } } } ``` ## Remove a tag from an item `DELETE https://getkollek.com/api/items/{item}/tags/{tag}` Detach a tag from an item. The tag itself is kept and stays available for other items. Use the delete tag endpoint to remove it from the account entirely. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item. - `tag` (integer, required): The ID of the tag. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/items/1/tags/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Categories ## List categories `GET https://getkollek.com/api/collections/{collection}/categories` Retrieve the categories of a collection. A category groups items within a collection, e.g. Marvel within a comics collection, and can be nested. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection the category belongs to. ### Query parameters - `per_page` (integer, optional): The number of categories to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of category objects. ### Example request ```bash curl https://getkollek.com/api/collections/1/categories \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "category", "id": "1", "attributes": { "name": "Marvel", "description": "Key issues and full runs from the 1990s Marvel era.", "collection_id": "1", "parent_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/categories/1" } }, { "type": "category", "id": "2", "attributes": { "name": "Spider-Man", "description": null, "collection_id": "1", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/categories/2" } } ], "links": { "first": "https://getkollek.com/api/collections/1/categories?page=1", "last": "https://getkollek.com/api/collections/1/categories?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collections/1/categories?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collections/1/categories", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a category `GET https://getkollek.com/api/collections/{collection}/categories/{category}` Retrieve a single category of a collection by its ID. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection the category belongs to. - `category` (integer, required): The ID of the category. **Returns:** A category object, or 404 when the category does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collections/1/categories/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "category", "id": "1", "attributes": { "name": "Marvel", "description": "Key issues and full runs from the 1990s Marvel era.", "collection_id": "1", "parent_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/categories/1" } } } ``` ## Create a category `POST https://getkollek.com/api/collections/{collection}/categories` Create a category within a collection. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the category belongs to. ### Body parameters - `name` (string, required): The name of the category. Maximum 255 characters. - `parent_id` (integer, optional): The ID of the parent category, for nesting. Must belong to the same collection. - `description` (string, optional): What the category holds, shown on the category page. Maximum 255 characters. **Returns:** The created category object. ### Example request ```bash curl https://getkollek.com/api/collections/1/categories \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Marvel", "parent_id": "1", "description": "Key issues and full runs from the 1990s Marvel era." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "category", "id": "1", "attributes": { "name": "Marvel", "description": "Key issues and full runs from the 1990s Marvel era.", "collection_id": "1", "parent_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/categories/1" } } } ``` ## Update a category `PUT https://getkollek.com/api/collections/{collection}/categories/{category}` Update the name, description and parent of a category. A category cannot be its own parent, nor be nested under one of its own descendants. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the category belongs to. - `category` (integer, required): The ID of the category. ### Body parameters - `name` (string, required): The name of the category. Maximum 255 characters. - `parent_id` (integer, optional): The ID of the parent category, for nesting. Must belong to the same collection. - `description` (string, optional): What the category holds, shown on the category page. Maximum 255 characters. **Returns:** The updated category object. ### Example request ```bash curl https://getkollek.com/api/collections/1/categories/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Marvel", "parent_id": "1", "description": "Key issues and full runs from the 1990s Marvel era." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "category", "id": "2", "attributes": { "name": "Spider-Man", "description": null, "collection_id": "1", "parent_id": "1", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/categories/2" } } } ``` ## Delete a category `DELETE https://getkollek.com/api/collections/{collection}/categories/{category}` Delete a category. Its nested child categories are deleted as well. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the category belongs to. - `category` (integer, required): The ID of the category. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collections/1/categories/2 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Sets ## List sets `GET https://getkollek.com/api/sets` Retrieve the sets of your account. A set groups items collected together as a series, e.g. Amazing Spider-Man #1-10, and is used to track completion. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of sets to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of set objects. ### Example request ```bash curl https://getkollek.com/api/sets \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "set", "id": "1", "attributes": { "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/sets/1" } }, { "type": "set", "id": "2", "attributes": { "name": "Beatles studio albums", "description": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/sets/2" } } ], "links": { "first": "https://getkollek.com/api/sets?page=1", "last": "https://getkollek.com/api/sets?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/sets?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/sets", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a set `GET https://getkollek.com/api/sets/{set}` Retrieve a single set of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `set` (integer, required): The ID of the set. **Returns:** A set object, or 404 when the set does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/sets/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "set", "id": "1", "attributes": { "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/sets/1" } } } ``` ## Create a set `POST https://getkollek.com/api/sets` Create a set for your account. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the set. Maximum 255 characters. - `description` (string, optional): A free text description of the set. Maximum 2000 characters. **Returns:** The created set object. ### Example request ```bash curl https://getkollek.com/api/sets \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "set", "id": "1", "attributes": { "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/sets/1" } } } ``` ## Update a set `PUT https://getkollek.com/api/sets/{set}` Update the name and description of a set. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `set` (integer, required): The ID of the set. ### Body parameters - `name` (string, required): The name of the set. Maximum 255 characters. - `description` (string, optional): A free text description of the set. Maximum 2000 characters. **Returns:** The updated set object. ### Example request ```bash curl https://getkollek.com/api/sets/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "set", "id": "1", "attributes": { "name": "Amazing Spider-Man #1-10", "description": "The first ten issues of the run.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/sets/1" } } } ``` ## Delete a set `DELETE https://getkollek.com/api/sets/{set}` Delete a set. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `set` (integer, required): The ID of the set. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/sets/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Series ## List series `GET https://getkollek.com/api/series` Retrieve the series of your account. A series links related items into a broader franchise or body of work, e.g. Harry Potter or Star Wars, and may span several collections. Unlike a set, a series has no target and tracks no completion. Link an item to a series with the series_id attribute of the item endpoints. **Permissions:** Any member of the account. ### Query parameters - `per_page` (integer, optional): The number of series to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of series objects. ### Example request ```bash curl https://getkollek.com/api/series \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "series", "id": "1", "attributes": { "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/series/1" } }, { "type": "series", "id": "2", "attributes": { "name": "Star Wars", "description": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/series/2" } } ], "links": { "first": "https://getkollek.com/api/series?page=1", "last": "https://getkollek.com/api/series?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/series?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/series", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a series `GET https://getkollek.com/api/series/{series}` Retrieve a single series of your account by its ID. **Permissions:** Any member of the account. ### Path parameters - `series` (integer, required): The ID of the series. **Returns:** A series object, or 404 when the series does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/series/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "series", "id": "1", "attributes": { "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/series/1" } } } ``` ## Create a series `POST https://getkollek.com/api/series` Create a series for your account. A series is account-wide, so it takes no collection. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the series. Maximum 255 characters. - `description` (string, optional): A free text description of the series. Maximum 2000 characters. **Returns:** The created series object. ### Example request ```bash curl https://getkollek.com/api/series \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "series", "id": "1", "attributes": { "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/series/1" } } } ``` ## Update a series `PUT https://getkollek.com/api/series/{series}` Update the name and description of a series. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `series` (integer, required): The ID of the series. ### Body parameters - `name` (string, required): The name of the series. Maximum 255 characters. - `description` (string, optional): A free text description of the series. Maximum 2000 characters. **Returns:** The updated series object. ### Example request ```bash curl https://getkollek.com/api/series/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "series", "id": "1", "attributes": { "name": "Harry Potter", "description": "The wizarding world across books, films and collectibles.", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/series/1" } } } ``` ## Delete a series `DELETE https://getkollek.com/api/series/{series}` Delete a series. The items linked to it are unlinked, not deleted. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `series` (integer, required): The ID of the series. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/series/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Items ## List items `GET https://getkollek.com/api/collections/{collection}/items` Retrieve the items catalogued within a collection. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection the item belongs to. ### Query parameters - `per_page` (integer, optional): The number of items to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of item objects. ### Example request ```bash curl https://getkollek.com/api/collections/1/items \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "item", "id": "1", "attributes": { "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "collection_id": "1", "type_id": null, "category_id": null, "set_id": null, "series_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/items/1" } }, { "type": "item", "id": "2", "attributes": { "name": "Amazing Spider-Man #2", "description": null, "collection_id": "1", "type_id": null, "category_id": null, "set_id": null, "series_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/items/2" } } ], "links": { "first": "https://getkollek.com/api/collections/1/items?page=1", "last": "https://getkollek.com/api/collections/1/items?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/collections/1/items?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/collections/1/items", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get an item `GET https://getkollek.com/api/collections/{collection}/items/{item}` Retrieve a single item of a collection by its ID. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection the item belongs to. - `item` (integer, required): The ID of the item. **Returns:** An item object, or 404 when the item does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collections/1/items/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "item", "id": "1", "attributes": { "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "collection_id": "1", "type_id": null, "category_id": null, "set_id": null, "series_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/items/1" } } } ``` ## Create an item `POST https://getkollek.com/api/collections/{collection}/items` Create an item within a collection. A hosted account on the free plan holds a limited number of items. Once it is full, this endpoint answers 402 with a message rather than creating anything, and keeps doing so until the account is unlocked. Read the current standing from the `items_used` and `item_limit` attributes of the account endpoint. A self-hosted instance has no limit and never returns 402. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the item belongs to. ### Body parameters - `name` (string, required): The name of the item. Maximum 255 characters. - `description` (string, optional): A free text description of the item. Maximum 2000 characters. - `type_id` (integer, optional): The ID of the type of the item. Must be a type of your account. - `category_id` (integer, optional): The ID of the category the item sits in. Must belong to the collection. - `set_id` (integer, optional): The ID of the set the item is part of. Must be a set of the same collection as the item. - `series_id` (integer, optional): The ID of the series the item belongs to. A series is account-wide, so it only has to belong to your account, not to the item's collection. **Returns:** The created item object, or 402 when the account has reached its item limit. ### Example request ```bash curl https://getkollek.com/api/collections/1/items \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "type_id": "3", "category_id": "1", "set_id": "1", "series_id": "1" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "item", "id": "1", "attributes": { "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "collection_id": "1", "type_id": null, "category_id": null, "set_id": null, "series_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/items/1" } } } ``` ## Update an item `PUT https://getkollek.com/api/collections/{collection}/items/{item}` Update the name, description and type of an item. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the item belongs to. - `item` (integer, required): The ID of the item. ### Body parameters - `name` (string, required): The name of the item. Maximum 255 characters. - `description` (string, optional): A free text description of the item. Maximum 2000 characters. - `type_id` (integer, optional): The ID of the type of the item. Must be a type of your account. **Returns:** The updated item object. ### Example request ```bash curl https://getkollek.com/api/collections/1/items/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "type_id": "3" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "item", "id": "1", "attributes": { "name": "Amazing Spider-Man #1", "description": "Near mint condition.", "collection_id": "1", "type_id": null, "category_id": null, "set_id": null, "series_id": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/collections/1/items/1" } } } ``` ## Delete an item `DELETE https://getkollek.com/api/collections/{collection}/items/{item}` Delete an item. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `collection` (integer, required): The ID of the collection the item belongs to. - `item` (integer, required): The ID of the item. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/collections/1/items/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Copies ## List copies `GET https://getkollek.com/api/items/{item}/copies` Retrieve the physical copies owned of an item. Each copy carries its own identifier, condition, location and status. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the copy belongs to. ### Query parameters - `per_page` (integer, optional): The number of copies to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of copy objects. ### Example request ```bash curl https://getkollek.com/api/items/1/copies \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "copy", "id": "1", "attributes": { "item_id": "1", "identifier": null, "item_condition_id": "1", "current_location_id": null, "status": "owned", "quantity": 1, "disposed_at": null, "note": null, "estimated_value": 5000, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/copies/1" } }, { "type": "copy", "id": "2", "attributes": { "item_id": "1", "identifier": null, "item_condition_id": null, "current_location_id": null, "status": "owned", "quantity": 1, "disposed_at": null, "note": null, "estimated_value": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/copies/2" } } ], "links": { "first": "https://getkollek.com/api/items/1/copies?page=1", "last": "https://getkollek.com/api/items/1/copies?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/items/1/copies?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/items/1/copies", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a copy `GET https://getkollek.com/api/items/{item}/copies/{copy}` Retrieve a single copy of an item by its ID. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the copy belongs to. - `copy` (integer, required): The ID of the copy. **Returns:** A copy object, or 404 when the copy does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/items/1/copies/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "copy", "id": "1", "attributes": { "item_id": "1", "identifier": null, "item_condition_id": "1", "current_location_id": null, "status": "owned", "quantity": 1, "disposed_at": null, "note": null, "estimated_value": 5000, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/copies/1" } } } ``` ## Create a copy `POST https://getkollek.com/api/items/{item}/copies` Create a copy of an item. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the copy belongs to. ### Body parameters - `identifier` (string, optional): A reference of your own for this copy, such as a serial or a shelf number. - `item_condition_id` (integer, optional): The ID of the condition of the copy. Must be a condition of your account. - `location_id` (integer, optional): The ID of the location where the copy is stored. Must be a location of your account. - `status` (string, optional): Where the copy sits in its lifecycle. One of owned, ordered, loaned, sold, gifted, lost, stolen, disposed or other. Defaults to owned. - `quantity` (integer, optional): How many identical units this copy stands for. At least 1, and defaults to 1. - `disposed_at` (string, optional): The date the copy left the collection, in YYYY-MM-DD format. - `note` (string, optional): A free form note about the copy. - `estimated_value` (integer, optional): What the copy is currently reckoned to be worth, in the smallest currency unit (e.g. cents). Recorded as a new valuation rather than overwriting the previous one. **Returns:** The created copy object. ### Example request ```bash curl https://getkollek.com/api/items/1/copies \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "identifier": "CP-0042", "item_condition_id": "1", "location_id": "1", "status": "owned", "quantity": "1", "disposed_at": "2024-01-15", "note": "Signed by the artist.", "estimated_value": "5000" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "copy", "id": "1", "attributes": { "item_id": "1", "identifier": null, "item_condition_id": "1", "current_location_id": null, "status": "owned", "quantity": 1, "disposed_at": null, "note": null, "estimated_value": 5000, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/copies/1" } } } ``` ## Update a copy `PUT https://getkollek.com/api/items/{item}/copies/{copy}` Update the identifier, condition, location, status and estimated value of a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the copy belongs to. - `copy` (integer, required): The ID of the copy. ### Body parameters - `identifier` (string, optional): A reference of your own for this copy, such as a serial or a shelf number. - `item_condition_id` (integer, optional): The ID of the condition of the copy. Must be a condition of your account. - `location_id` (integer, optional): The ID of the location where the copy is stored. Must be a location of your account. - `status` (string, optional): Where the copy sits in its lifecycle. One of owned, ordered, loaned, sold, gifted, lost, stolen, disposed or other. Defaults to owned. - `quantity` (integer, optional): How many identical units this copy stands for. At least 1, and defaults to 1. - `disposed_at` (string, optional): The date the copy left the collection, in YYYY-MM-DD format. - `note` (string, optional): A free form note about the copy. - `estimated_value` (integer, optional): What the copy is currently reckoned to be worth, in the smallest currency unit (e.g. cents). Recorded as a new valuation rather than overwriting the previous one. **Returns:** The updated copy object. ### Example request ```bash curl https://getkollek.com/api/items/1/copies/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "identifier": "CP-0042", "item_condition_id": "1", "location_id": "1", "status": "owned", "quantity": "1", "disposed_at": "2024-01-15", "note": "Signed by the artist.", "estimated_value": "5000" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "copy", "id": "1", "attributes": { "item_id": "1", "identifier": null, "item_condition_id": "1", "current_location_id": null, "status": "owned", "quantity": 1, "disposed_at": null, "note": null, "estimated_value": 5000, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/copies/1" } } } ``` ## Delete a copy `DELETE https://getkollek.com/api/items/{item}/copies/{copy}` Delete a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the copy belongs to. - `copy` (integer, required): The ID of the copy. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/items/1/copies/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Item photos ## List item photos `GET https://getkollek.com/api/items/{item}/photos` Retrieve the photos of an item, in the order the user arranged them. Exactly one photo is the main visual. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the photo belongs to. ### Query parameters - `per_page` (integer, optional): The number of photos to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of item photo objects. ### Example request ```bash curl https://getkollek.com/api/items/1/photos \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "item_photo", "id": "1", "attributes": { "item_id": "1", "filename": "cover.jpg", "mime_type": "image/jpeg", "size": 204800, "is_main": true, "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/photos/1" } }, { "type": "item_photo", "id": "2", "attributes": { "item_id": "1", "filename": "cover.jpg", "mime_type": "image/jpeg", "size": 204800, "is_main": false, "position": 2, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/photos/2" } } ], "links": { "first": "https://getkollek.com/api/items/1/photos?page=1", "last": "https://getkollek.com/api/items/1/photos?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/items/1/photos?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/items/1/photos", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get an item photo `GET https://getkollek.com/api/items/{item}/photos/{photo}` Retrieve the metadata of a single item photo by its ID. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the photo belongs to. - `photo` (integer, required): The ID of the photo. **Returns:** An item photo object, or 404 when the photo does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/items/1/photos/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "item_photo", "id": "1", "attributes": { "item_id": "1", "filename": "cover.jpg", "mime_type": "image/jpeg", "size": 204800, "is_main": true, "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/photos/1" } } } ``` ## Upload an item photo `POST https://getkollek.com/api/items/{item}/photos` Upload a photo for an item, as multipart/form-data. The first photo added to an item becomes its main visual. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the photo belongs to. ### Body parameters - `file` (file, required): The image file to upload. Maximum 10 MB. **Returns:** The created item photo object. ### Example request ```bash curl https://getkollek.com/api/items/1/photos \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 201` ```json { "data": { "type": "item_photo", "id": "1", "attributes": { "item_id": "1", "filename": "cover.jpg", "mime_type": "image/jpeg", "size": 204800, "is_main": true, "position": 1, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/photos/1" } } } ``` ## Set the main photo `PUT https://getkollek.com/api/items/{item}/photos/{photo}/main` Promote a photo to be the main visual of its item. The previous main photo is demoted. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the photo belongs to. - `photo` (integer, required): The ID of the photo. **Returns:** The updated item photo object. ### Example request ```bash curl https://getkollek.com/api/items/1/photos/2/main \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "item_photo", "id": "2", "attributes": { "item_id": "1", "filename": "cover.jpg", "mime_type": "image/jpeg", "size": 204800, "is_main": true, "position": 2, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/photos/2" } } } ``` ## Delete an item photo `DELETE https://getkollek.com/api/items/{item}/photos/{photo}` Delete a photo, removing its file from storage. When the main photo is deleted, the next photo by position becomes the main visual. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `item` (integer, required): The ID of the item the photo belongs to. - `photo` (integer, required): The ID of the photo. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/items/1/photos/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## Delete several photos `DELETE https://getkollek.com/api/photos` Delete several photos of your account in one call, removing their files from storage. The photos do not have to belong to the same item, which is why this endpoint is not nested under one. The call is all or nothing. If any ID in the list does not belong to your account, nothing is deleted and the response is a 404. The call cannot be undone: deleted photos do not go to the trash. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `photo_ids` (array of integers, required): The IDs of the photos to delete. Must contain at least one ID, and every ID must belong to your account. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/photos \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "photo_ids": [ 1, 2 ] }' ``` ### Example response `Status: 204` The response has no body. # Item activity ## List the activity of an item `GET https://getkollek.com/api/items/{item}/logs` Retrieve everything that has been done to an item, most recent first. Entries are recorded automatically as actions are performed, so they cannot be created, changed or deleted through the API. Each entry carries the `action` that was performed, the `user_name` of whoever performed it, and a `description` already translated into the language of your account. A user who has since been deleted leaves the name recorded at the time of the action. The `parameters` object holds whatever the action recorded, and its shape depends on the action. A `label` names something the action applied to, such as a tag. A `file` names an uploaded file. A `changes` array lists the values that moved, each with a `label` and the `from` and `to` values (either may be null when the value was not set). Treat `parameters` as free form: new keys may be added over time. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the entry belongs to. ### Query parameters - `per_page` (integer, optional): The number of entries to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of item activity objects, or 404 when the item does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/items/1/logs \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "item_log", "id": "3", "attributes": { "user_name": "Monica Geller", "action": "copy_updated", "parameters": { "changes": [ { "label": "Estimated value", "from": "$390", "to": "$420" } ] }, "description": "updated a copy", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/logs/3" } }, { "type": "item_log", "id": "2", "attributes": { "user_name": "Monica Geller", "action": "tag_attached", "parameters": { "label": "Signed" }, "description": "added the tag", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/logs/2" } }, { "type": "item_log", "id": "1", "attributes": { "user_name": "Rachel Green", "action": "item_created", "parameters": null, "description": "created this item", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/logs/1" } } ], "links": { "first": "https://getkollek.com/api/items/1/logs?page=1", "last": "https://getkollek.com/api/items/1/logs?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/items/1/logs?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/items/1/logs", "per_page": 10, "to": 3, "total": 3 } } ``` ## Get an activity entry `GET https://getkollek.com/api/items/{item}/logs/{log}` Retrieve a single entry of the activity of an item by its ID. **Permissions:** Any member of the account. ### Path parameters - `item` (integer, required): The ID of the item the entry belongs to. - `log` (integer, required): The ID of the activity entry. **Returns:** An item activity object, or 404 when the entry belongs to another item or to another account. ### Example request ```bash curl https://getkollek.com/api/items/1/logs/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "item_log", "id": "2", "attributes": { "user_name": "Monica Geller", "action": "tag_attached", "parameters": { "label": "Signed" }, "description": "added the tag", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/items/1/logs/2" } } } ``` # Statistics ## Get the statistics of a collection `GET https://getkollek.com/api/collections/{collection}/statistics` Retrieve the aggregates behind the statistics screen of a collection: what it holds, what it is worth, how it grew and where it is stored. These are computed values rather than stored records, so the object has no created_at or updated_at. Every amount is an integer in cents, in the currency of the collection. Values come from the copies of the items, so an item with no copy counts towards items and contributes nothing to any amount. value_over_time and acquisitions_per_month cover a rolling twelve month window, one entry per month, labelled with the short month name in the locale of your user. value_over_time is a running total, so its first point already carries everything acquired before the window opened. sets_completion is null unless at least one set of the collection declares a target_count. A label is null where the copies have no condition or no location. In by_category, the entry with other set to true sums the categories too small to be named individually. **Permissions:** Any member of the account. ### Path parameters - `collection` (integer, required): The ID of the collection. **Returns:** A collection_statistics object, or 404 when the collection does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/collections/1/statistics \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "collection_statistics", "id": "1", "attributes": { "totals": { "items": 42, "copies": 57, "value": 128500, "average": 3059, "items_added_this_month": 5, "value_added_this_month": 32500, "undated_copies": 4 }, "sets_completion": { "percentage": 67, "owned": 8, "target": 12, "remaining": 4, "sets": 1 }, "value_over_time": [ { "label": "May", "value": 96000 }, { "label": "Jun", "value": 128500 } ], "acquisitions_per_month": [ { "label": "May", "count": 3 }, { "label": "Jun", "count": 5 } ], "by_category": [ { "label": "Silver Age", "other": false, "count": 18, "percentage": 43 }, { "label": null, "other": true, "count": 24, "percentage": 57 } ], "by_condition": [ { "label": "Near Mint", "count": 21, "percentage": 37 } ], "value_by_location": [ { "label": "Shelf A", "value": 91000 } ], "top_items": [ { "id": "7", "name": "Amazing Spider-Man #1", "value": 42000, "condition": "Near Mint", "location": "Shelf A" } ] }, "links": { "self": "https://getkollek.com/api/collections/1/statistics" } } } ``` # Trash ## List the trash `GET https://getkollek.com/api/trash` Retrieve everything your account has soft deleted and can still restore: collections, items, copies, categories and sets. The list is sorted by urgency, so whatever expires first comes first. Deleting a parent does not stamp its children, so this only surfaces the objects someone deleted on purpose. Restoring a collection brings its items back with it. The list merges five tables into one, so it is returned whole rather than paginated. The id is the ID of the object in its own table, which means an id is only unique together with object_type. **Permissions:** Any member of the account. **Returns:** A list of trashed_object entries. ### Example request ```bash curl https://getkollek.com/api/trash \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "trashed_object", "id": "7", "attributes": { "object_type": "item", "name": "Amazing Spider-Man #1", "subtitle": "My Comics", "deleted_at": 1752537600, "deleted_by_name": "Rachel Green", "days_left": 3 } }, { "type": "trashed_object", "id": "2", "attributes": { "object_type": "collection", "name": "My Vinyl", "subtitle": null, "deleted_at": 1752537600, "deleted_by_name": "Rachel Green", "days_left": 27 } } ] } ``` ## Restore an object `PUT https://getkollek.com/api/trash` Move one object out of the trash and back to where it was. Identify it with the object_type and id pair returned by the list endpoint. The response has no body: fetch the object from its own endpoint once it is back. Restoring an object whose parent is still in the trash restores the object alone, so it stays out of sight until the parent is restored too. **Permissions:** Owners and editors. Viewers get a 404 response. ### Body parameters - `type` (string, required): The kind of object to restore. One of collection, item, copy, category or set. - `id` (integer, required): The ID of the object to restore, within its own kind. **Returns:** An empty response, or 404 when nothing of that kind and ID sits in your trash. ### Example request ```bash curl https://getkollek.com/api/trash \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "item", "id": 7 }' ``` ### Example response `Status: 204` The response has no body. ## Empty the trash `DELETE https://getkollek.com/api/trash` Permanently delete everything in the trash of your account, across all five kinds of object at once. This cannot be undone, and there is no confirmation step. Objects left in the trash are purged automatically once their retention window runs out, so emptying it by hand is only a way to reclaim the space sooner. **Permissions:** Owners and editors. Viewers get a 404 response. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/trash \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Account ## Get the account `GET https://getkollek.com/api/account` Retrieve the account your API key belongs to. A user belongs to exactly one account, so there is no ID to pass. The `items_used` and `item_limit` attributes describe the free plan of a hosted account. `item_limit` is the number of items past which creating one is refused with a 402 response. It is `null` on a self-hosted instance and on an account that has been unlocked, because neither has a ceiling to report. **Permissions:** Any member of the account. **Returns:** An account object. ### Example request ```bash curl https://getkollek.com/api/account \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "account", "id": "1", "attributes": { "name": "Central Perk", "currency_code": "USD", "items_used": 7, "item_limit": 15, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account" } } } ``` ## Update the account `PUT https://getkollek.com/api/account` Update the name and default currency of the account. The currency applies to new amounts. Amounts already recorded keep the currency they were entered in. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Body parameters - `name` (string, required): The name of the account. Maximum 100 characters. - `currency_code` (string, required): The three letter code of the default currency, such as USD or EUR. **Returns:** The updated account object. ### Example request ```bash curl https://getkollek.com/api/account \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Central Perk", "currency_code": "USD" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "account", "id": "1", "attributes": { "name": "Central Perk", "currency_code": "USD", "items_used": 7, "item_limit": 15, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account" } } } ``` ## Delete the account `DELETE https://getkollek.com/api/account` Permanently delete the account and everything in it: every collection, item, copy, photo and type, along with every member, including you. This cannot be undone and there is no confirmation step. The API key used to make the call stops working immediately, as do the keys of every other member. Nothing goes to the trash, so an emptied account cannot be recovered from it. **Permissions:** Owners only. Editors and viewers get a 404 response. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/account \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## List members `GET https://getkollek.com/api/account/members` Retrieve the people who have access to the account, together with the role each one holds. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Query parameters - `per_page` (integer, optional): The number of members to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of member objects. ### Example request ```bash curl https://getkollek.com/api/account/members \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "member", "id": "1", "attributes": { "first_name": "Rachel", "last_name": "Green", "nickname": null, "email": "rachel@centralperk.test", "role": "owner", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/members/1" } }, { "type": "member", "id": "2", "attributes": { "first_name": "Chandler", "last_name": "Bing", "nickname": null, "email": "chandler@centralperk.test", "role": "editor", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/members/2" } } ], "links": { "first": "https://getkollek.com/api/account/members?page=1", "last": "https://getkollek.com/api/account/members?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/account/members?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/account/members", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a member `GET https://getkollek.com/api/account/members/{member}` Retrieve a single member of your account by their ID. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Path parameters - `member` (integer, required): The ID of the member. **Returns:** A member object, or 404 when the member does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/account/members/2 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "member", "id": "2", "attributes": { "first_name": "Chandler", "last_name": "Bing", "nickname": null, "email": "chandler@centralperk.test", "role": "editor", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/members/2" } } } ``` ## Invite a member `POST https://getkollek.com/api/account/members` Invite someone to join the account at a given role. This creates an invitation and emails it. It does not create a member. The invitation is claimed on the web, so the person becomes a member only once they follow the link and set up their user. Until then they show up under the invitations endpoint rather than the members one. The API cannot claim an invitation. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Body parameters - `email` (string, required): The email address to invite, in lowercase. Maximum 255 characters. - `role` (string, required): The role to grant. One of owner, editor or viewer. **Returns:** The created invitation object. ### Example request ```bash curl https://getkollek.com/api/account/members \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "email": "phoebe@centralperk.test", "role": "editor" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "invitation", "id": "1", "attributes": { "email": "phoebe@centralperk.test", "role": "editor", "expires_at": 1753142400, "accepted_at": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/invitations" } } } ``` ## Change the role of a member `PUT https://getkollek.com/api/account/members/{member}` Change the role a member holds in the account. An account always keeps at least one owner, so demoting the last one is refused. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Path parameters - `member` (integer, required): The ID of the member. ### Body parameters - `role` (string, required): The role to grant. One of owner, editor or viewer. **Returns:** The updated member object. ### Example request ```bash curl https://getkollek.com/api/account/members/2 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "role": "viewer" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "member", "id": "2", "attributes": { "first_name": "Chandler", "last_name": "Bing", "nickname": null, "email": "chandler@centralperk.test", "role": "viewer", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/members/2" } } } ``` ## Remove a member `DELETE https://getkollek.com/api/account/members/{member}` Remove someone from the account. Their user is deleted and their API keys stop working. What they catalogued stays in the account. An account always keeps at least one owner, so removing the last one is refused. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Path parameters - `member` (integer, required): The ID of the member. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/account/members/2 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. ## List pending invitations `GET https://getkollek.com/api/account/invitations` Retrieve the invitations that are still waiting to be claimed. Invitations that were accepted, and those that have expired, are left out. **Permissions:** Owners only. Editors and viewers get a 404 response. ### Query parameters - `per_page` (integer, optional): The number of invitations to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of invitation objects. ### Example request ```bash curl https://getkollek.com/api/account/invitations \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "invitation", "id": "1", "attributes": { "email": "phoebe@centralperk.test", "role": "editor", "expires_at": 1753142400, "accepted_at": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/account/invitations" } } ], "links": { "first": "https://getkollek.com/api/account/invitations?page=1", "last": "https://getkollek.com/api/account/invitations?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/account/invitations?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/account/invitations", "per_page": 10, "to": 1, "total": 1 } } ``` # Transactions ## List transactions `GET https://getkollek.com/api/copies/{copy}/transactions` Retrieve the transactions recorded against a copy: purchases, sales, trades, gifts, refunds and the fees, taxes and shipping around them. They are returned most recent first. Transactions are the single source of truth for commercial data. The acquisition date and the price paid of a copy are read from the earliest transaction that brought it into the collection rather than stored on the copy itself. Every transaction carries two totals. `total_amount` is what you recorded and may be null; `total` is what actually changed hands, falling back to the sum of the amount, the tax, the fees and the shipping when you did not record one. Read `total` unless you specifically want to know whether a total was given. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the transaction belongs to. ### Query parameters - `per_page` (integer, optional): The number of transactions to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of transaction objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/transactions \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "transaction", "id": "1", "attributes": { "copy_id": "1", "type": "purchase", "counterparty": "Central Perk Collectibles", "amount": 5000, "currency_code": "USD", "tax_amount": null, "fee_amount": null, "shipping_amount": null, "total_amount": 6550, "total": 6550, "occurred_at": 1752537600, "reference_number": null, "source_url": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/transactions/1" } }, { "type": "transaction", "id": "2", "attributes": { "copy_id": "1", "type": "shipping", "counterparty": "Central Perk Collectibles", "amount": 900, "currency_code": "USD", "tax_amount": null, "fee_amount": null, "shipping_amount": null, "total_amount": null, "total": 900, "occurred_at": 1752537600, "reference_number": null, "source_url": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/transactions/2" } } ], "links": { "first": "https://getkollek.com/api/copies/1/transactions?page=1", "last": "https://getkollek.com/api/copies/1/transactions?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/transactions?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/transactions", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a transaction `GET https://getkollek.com/api/copies/{copy}/transactions/{transaction}` Retrieve a single transaction of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the transaction belongs to. - `transaction` (integer, required): The ID of the transaction. **Returns:** A transaction object, or 404 when the transaction does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/transactions/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "transaction", "id": "1", "attributes": { "copy_id": "1", "type": "purchase", "counterparty": "Central Perk Collectibles", "amount": 5000, "currency_code": "USD", "tax_amount": null, "fee_amount": null, "shipping_amount": null, "total_amount": 6550, "total": 6550, "occurred_at": 1752537600, "reference_number": null, "source_url": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/transactions/1" } } } ``` ## Create a transaction `POST https://getkollek.com/api/copies/{copy}/transactions` Record a transaction against a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the transaction belongs to. ### Body parameters - `type` (string, required): What kind of exchange this records. One of purchase, sale, trade, gift_received, gift_given, inheritance, refund, fee, tax, shipping or other. - `occurred_at` (string, required): The date the exchange happened, in YYYY-MM-DD format. - `counterparty` (string, optional): Who was on the other side of the exchange, such as the seller or the buyer. - `amount` (integer, optional): The headline price, in the smallest currency unit (e.g. cents), before tax, fees and shipping. - `currency_code` (string, optional): The three letter currency code every amount on the transaction is expressed in. Defaults to the currency of the collection. - `tax_amount` (integer, optional): The tax paid, in the smallest currency unit. - `fee_amount` (integer, optional): The fees paid, in the smallest currency unit. - `shipping_amount` (integer, optional): The shipping paid, in the smallest currency unit. - `total_amount` (integer, optional): What actually changed hands, in the smallest currency unit. Leave it out and the total is read as the sum of the amount, the tax, the fees and the shipping. - `reference_number` (string, optional): An order or invoice number for the exchange. - `source_url` (string, optional): A link to the listing or the receipt the exchange came from. - `note` (string, optional): A free form note about the exchange. **Returns:** The created transaction object. ### Example request ```bash curl https://getkollek.com/api/copies/1/transactions \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "purchase", "occurred_at": "2024-01-15", "counterparty": "Central Perk Collectibles", "amount": "5000", "currency_code": "USD", "tax_amount": "400", "fee_amount": "250", "shipping_amount": "900", "total_amount": "6550", "reference_number": "INV-1994", "source_url": "https://example.com/listings/1994", "note": "Haggled down at the flea market." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "transaction", "id": "1", "attributes": { "copy_id": "1", "type": "purchase", "counterparty": "Central Perk Collectibles", "amount": 5000, "currency_code": "USD", "tax_amount": null, "fee_amount": null, "shipping_amount": null, "total_amount": 6550, "total": 6550, "occurred_at": 1752537600, "reference_number": null, "source_url": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/transactions/1" } } } ``` ## Update a transaction `PUT https://getkollek.com/api/copies/{copy}/transactions/{transaction}` Update a transaction. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the transaction belongs to. - `transaction` (integer, required): The ID of the transaction. ### Body parameters - `type` (string, required): What kind of exchange this records. One of purchase, sale, trade, gift_received, gift_given, inheritance, refund, fee, tax, shipping or other. - `occurred_at` (string, required): The date the exchange happened, in YYYY-MM-DD format. - `counterparty` (string, optional): Who was on the other side of the exchange, such as the seller or the buyer. - `amount` (integer, optional): The headline price, in the smallest currency unit (e.g. cents), before tax, fees and shipping. - `currency_code` (string, optional): The three letter currency code every amount on the transaction is expressed in. Defaults to the currency of the collection. - `tax_amount` (integer, optional): The tax paid, in the smallest currency unit. - `fee_amount` (integer, optional): The fees paid, in the smallest currency unit. - `shipping_amount` (integer, optional): The shipping paid, in the smallest currency unit. - `total_amount` (integer, optional): What actually changed hands, in the smallest currency unit. Leave it out and the total is read as the sum of the amount, the tax, the fees and the shipping. - `reference_number` (string, optional): An order or invoice number for the exchange. - `source_url` (string, optional): A link to the listing or the receipt the exchange came from. - `note` (string, optional): A free form note about the exchange. **Returns:** The updated transaction object. ### Example request ```bash curl https://getkollek.com/api/copies/1/transactions/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "purchase", "occurred_at": "2024-01-15", "counterparty": "Central Perk Collectibles", "amount": "5000", "currency_code": "USD", "tax_amount": "400", "fee_amount": "250", "shipping_amount": "900", "total_amount": "6550", "reference_number": "INV-1994", "source_url": "https://example.com/listings/1994", "note": "Haggled down at the flea market." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "transaction", "id": "1", "attributes": { "copy_id": "1", "type": "purchase", "counterparty": "Central Perk Collectibles", "amount": 5000, "currency_code": "USD", "tax_amount": null, "fee_amount": null, "shipping_amount": null, "total_amount": 6550, "total": 6550, "occurred_at": 1752537600, "reference_number": null, "source_url": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/transactions/1" } } } ``` ## Delete a transaction `DELETE https://getkollek.com/api/copies/{copy}/transactions/{transaction}` Delete a transaction. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the transaction belongs to. - `transaction` (integer, required): The ID of the transaction. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/transactions/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Provenance events ## List provenance events `GET https://getkollek.com/api/copies/{copy}/provenance-events` Retrieve the documented story of a copy: how it was acquired, who held it, where it was shown, when it was authenticated. Provenance reads as a narrative rather than as a feed, so events are returned oldest first, and an undated event sorts to the front. No amounts live here. Prices, taxes, fees and shipping belong to the transaction and are never duplicated onto the event, so an event that came from an exchange sets `transaction_id` and you read the money from the transaction itself. A transaction is one exchange, so it can be the source of at most one event. Deleting a linked transaction unlinks the event rather than deleting it: the moment in the object story outlives the record of what was paid for it. Provenance dates are frequently uncertain, so every date is paired with `occurred_at_precision`. A precision of unknown stores no date at all, and `formatted_date` is the read only rendering of the date at its precision, which is what you should show rather than formatting `occurred_at` yourself. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the provenance event belongs to. ### Query parameters - `per_page` (integer, optional): The number of provenance events to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of provenance event objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/provenance-events \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "provenance_event", "id": "1", "attributes": { "copy_id": "1", "transaction_id": null, "type": "origin", "title": "Printed in New York", "description": null, "occurred_at": 550972800, "occurred_at_precision": "year", "formatted_date": "1987", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": null, "source_url": null, "is_verified": false, "verification_note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/provenance-events/1" } }, { "type": "provenance_event", "id": "2", "attributes": { "copy_id": "1", "transaction_id": "1", "type": "acquisition", "title": "Bought at the Central Perk estate sale", "description": null, "occurred_at": 1752537600, "occurred_at_precision": "exact", "formatted_date": "July 15, 2025", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": null, "source_url": null, "is_verified": false, "verification_note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/provenance-events/2" } } ], "links": { "first": "https://getkollek.com/api/copies/1/provenance-events?page=1", "last": "https://getkollek.com/api/copies/1/provenance-events?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/provenance-events?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/provenance-events", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a provenance event `GET https://getkollek.com/api/copies/{copy}/provenance-events/{provenanceEvent}` Retrieve a single provenance event of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the provenance event belongs to. - `provenanceEvent` (integer, required): The ID of the provenance event. **Returns:** A provenance event object, or 404 when the event does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/provenance-events/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "provenance_event", "id": "1", "attributes": { "copy_id": "1", "transaction_id": null, "type": "origin", "title": "Printed in New York", "description": null, "occurred_at": 550972800, "occurred_at_precision": "year", "formatted_date": "1987", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": null, "source_url": null, "is_verified": false, "verification_note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/provenance-events/1" } } } ``` ## Create a provenance event `POST https://getkollek.com/api/copies/{copy}/provenance-events` Record a moment in the story of a copy. No amounts live here. Prices, taxes, fees and shipping belong to the transaction and are never duplicated onto the event, so an event that came from an exchange sets `transaction_id` and you read the money from the transaction itself. A transaction is one exchange, so it can be the source of at most one event. Deleting a linked transaction unlinks the event rather than deleting it: the moment in the object story outlives the record of what was paid for it. Provenance dates are frequently uncertain, so every date is paired with `occurred_at_precision`. A precision of unknown stores no date at all, and `formatted_date` is the read only rendering of the date at its precision, which is what you should show rather than formatting `occurred_at` yourself. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the provenance event belongs to. ### Body parameters - `type` (string, required): What kind of moment this records. One of acquisition, sale, gift, inheritance, ownership_transfer, custody_transfer, loan, return, exhibition, authentication, appraisal, significant_restoration, origin, discovery or other. - `title` (string, required): A short summary of the moment, shown in the timeline. - `description` (string, optional): The detail behind the title. - `occurred_at` (string, optional): When it happened, in YYYY-MM-DD format. Ignored when the precision is unknown, in which case no date is stored at all. - `occurred_at_precision` (string, optional): How much of the date is actually known. One of exact, month, year, approximate or unknown. Default: `exact`. - `location` (string, optional): Where it happened. - `from_party` (string, optional): Who the object came from. - `to_party` (string, optional): Who the object went to. - `reference_number` (string, optional): An auction lot, a certificate number or an archive reference. - `source_url` (string, optional): A link to where the event can be checked. - `is_verified` (boolean, optional): Whether evidence backs this event. Default: `false`. - `verification_note` (string, optional): How it was verified. Dropped when is_verified is false, since a note about how something was verified means nothing when it was not. - `transaction_id` (integer, optional): The transaction this event came from. It must belong to the same copy and must not already carry another event, otherwise the request returns 404. **Returns:** The created provenance event object. ### Example request ```bash curl https://getkollek.com/api/copies/1/provenance-events \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "acquisition", "title": "Bought at the Central Perk estate sale", "description": "Sold as part of the Gunther estate, lot 42.", "occurred_at": "1987-06-15", "occurred_at_precision": "year", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": "LOT-1994", "source_url": "https://example.com/lots/1994", "is_verified": "true", "verification_note": "Certificate held on file.", "transaction_id": "1" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "provenance_event", "id": "1", "attributes": { "copy_id": "1", "transaction_id": null, "type": "origin", "title": "Printed in New York", "description": null, "occurred_at": 550972800, "occurred_at_precision": "year", "formatted_date": "1987", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": null, "source_url": null, "is_verified": false, "verification_note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/provenance-events/1" } } } ``` ## Update a provenance event `PUT https://getkollek.com/api/copies/{copy}/provenance-events/{provenanceEvent}` Update a provenance event. Every field is replaced, so send the ones you want to keep along with the ones you are changing. Relinking an event to the transaction it already carries is allowed. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the provenance event belongs to. - `provenanceEvent` (integer, required): The ID of the provenance event. ### Body parameters - `type` (string, required): What kind of moment this records. One of acquisition, sale, gift, inheritance, ownership_transfer, custody_transfer, loan, return, exhibition, authentication, appraisal, significant_restoration, origin, discovery or other. - `title` (string, required): A short summary of the moment, shown in the timeline. - `description` (string, optional): The detail behind the title. - `occurred_at` (string, optional): When it happened, in YYYY-MM-DD format. Ignored when the precision is unknown, in which case no date is stored at all. - `occurred_at_precision` (string, optional): How much of the date is actually known. One of exact, month, year, approximate or unknown. Default: `exact`. - `location` (string, optional): Where it happened. - `from_party` (string, optional): Who the object came from. - `to_party` (string, optional): Who the object went to. - `reference_number` (string, optional): An auction lot, a certificate number or an archive reference. - `source_url` (string, optional): A link to where the event can be checked. - `is_verified` (boolean, optional): Whether evidence backs this event. Default: `false`. - `verification_note` (string, optional): How it was verified. Dropped when is_verified is false, since a note about how something was verified means nothing when it was not. - `transaction_id` (integer, optional): The transaction this event came from. It must belong to the same copy and must not already carry another event, otherwise the request returns 404. **Returns:** The updated provenance event object. ### Example request ```bash curl https://getkollek.com/api/copies/1/provenance-events/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "acquisition", "title": "Bought at the Central Perk estate sale", "description": "Sold as part of the Gunther estate, lot 42.", "occurred_at": "1987-06-15", "occurred_at_precision": "year", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": "LOT-1994", "source_url": "https://example.com/lots/1994", "is_verified": "true", "verification_note": "Certificate held on file.", "transaction_id": "1" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "provenance_event", "id": "1", "attributes": { "copy_id": "1", "transaction_id": null, "type": "origin", "title": "Printed in New York", "description": null, "occurred_at": 550972800, "occurred_at_precision": "year", "formatted_date": "1987", "location": "New York", "from_party": "Central Perk Collectibles", "to_party": "Ross Geller", "reference_number": null, "source_url": null, "is_verified": false, "verification_note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/provenance-events/1" } } } ``` ## Delete a provenance event `DELETE https://getkollek.com/api/copies/{copy}/provenance-events/{provenanceEvent}` Delete a provenance event. The transaction it was linked to, if any, is left untouched. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the provenance event belongs to. - `provenanceEvent` (integer, required): The ID of the provenance event. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/provenance-events/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Valuations ## List valuations `GET https://getkollek.com/api/copies/{copy}/valuations` Retrieve the valuations recorded against a copy: what it has been reckoned to be worth over time. They are returned most recent first. Valuations are append-only. Changing what a copy is worth records a new valuation rather than overwriting an old one, and the latest by `valued_at` is what the application shows as the current estimated value. A purchase price is not a valuation: what was actually paid belongs to a transaction. A valuation is only ever an estimate of worth. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the valuation belongs to. ### Query parameters - `per_page` (integer, optional): The number of valuations to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of valuation objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/valuations \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "valuation", "id": "2", "attributes": { "copy_id": "1", "type": "professional_appraisal", "amount": 25000, "currency_code": "USD", "valued_at": 1752537600, "confidence": "high", "valuer": null, "method": null, "source_url": null, "reference_number": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/valuations/2" } }, { "type": "valuation", "id": "1", "attributes": { "copy_id": "1", "type": "user_estimate", "amount": 10000, "currency_code": "USD", "valued_at": 1752537600, "confidence": "unknown", "valuer": null, "method": null, "source_url": null, "reference_number": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/valuations/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/valuations?page=1", "last": "https://getkollek.com/api/copies/1/valuations?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/valuations?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/valuations", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a valuation `GET https://getkollek.com/api/copies/{copy}/valuations/{valuation}` Retrieve a single valuation of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the valuation belongs to. - `valuation` (integer, required): The ID of the valuation. **Returns:** A valuation object, or 404 when the valuation does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/valuations/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "valuation", "id": "1", "attributes": { "copy_id": "1", "type": "user_estimate", "amount": 10000, "currency_code": "USD", "valued_at": 1752537600, "confidence": "unknown", "valuer": null, "method": null, "source_url": null, "reference_number": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/valuations/1" } } } ``` ## Create a valuation `POST https://getkollek.com/api/copies/{copy}/valuations` Record a valuation against a copy. This is the normal way to change what a copy is worth, since valuations are kept as history rather than edited in place. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the valuation belongs to. ### Body parameters - `type` (string, required): Where the valuation came from. One of user_estimate, professional_appraisal, market_estimate, insurance_value, auction_estimate, automated_estimate or other. - `amount` (integer, required): What the copy was reckoned to be worth, in the smallest currency unit (e.g. cents). - `valued_at` (string, required): The date the copy was valued, in YYYY-MM-DD format. This is what orders the valuations, so the latest date is read as the current estimated value. - `currency_code` (string, optional): The three letter currency code the amount is expressed in. Defaults to the currency of the collection. - `confidence` (string, optional): How much weight the valuation carries. One of low, medium, high or unknown. Defaults to unknown. - `valuer` (string, optional): Who or what produced the valuation, such as the appraiser or the marketplace. - `method` (string, optional): How the figure was arrived at, such as comparable sales. - `source_url` (string, optional): A link to where the valuation can be checked, such as the appraisal report or the listing. - `reference_number` (string, optional): An appraisal or report reference for the valuation. - `note` (string, optional): A free form note about the valuation. **Returns:** The created valuation object. ### Example request ```bash curl https://getkollek.com/api/copies/1/valuations \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "professional_appraisal", "amount": "25000", "valued_at": "2024-01-15", "currency_code": "USD", "confidence": "high", "valuer": "Central Perk Appraisals", "method": "Comparable sales", "source_url": "https://example.com/appraisals/1994", "reference_number": "CP-1994", "note": "Valued after the Central Perk auction." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "valuation", "id": "1", "attributes": { "copy_id": "1", "type": "professional_appraisal", "amount": 25000, "currency_code": "USD", "valued_at": 1752537600, "confidence": "high", "valuer": null, "method": null, "source_url": null, "reference_number": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/valuations/1" } } } ``` ## Update a valuation `PUT https://getkollek.com/api/copies/{copy}/valuations/{valuation}` Update a valuation, for correcting a figure that was entered wrong. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the valuation belongs to. - `valuation` (integer, required): The ID of the valuation. ### Body parameters - `type` (string, required): Where the valuation came from. One of user_estimate, professional_appraisal, market_estimate, insurance_value, auction_estimate, automated_estimate or other. - `amount` (integer, required): What the copy was reckoned to be worth, in the smallest currency unit (e.g. cents). - `valued_at` (string, required): The date the copy was valued, in YYYY-MM-DD format. This is what orders the valuations, so the latest date is read as the current estimated value. - `currency_code` (string, optional): The three letter currency code the amount is expressed in. Defaults to the currency of the collection. - `confidence` (string, optional): How much weight the valuation carries. One of low, medium, high or unknown. Defaults to unknown. - `valuer` (string, optional): Who or what produced the valuation, such as the appraiser or the marketplace. - `method` (string, optional): How the figure was arrived at, such as comparable sales. - `source_url` (string, optional): A link to where the valuation can be checked, such as the appraisal report or the listing. - `reference_number` (string, optional): An appraisal or report reference for the valuation. - `note` (string, optional): A free form note about the valuation. **Returns:** The updated valuation object. ### Example request ```bash curl https://getkollek.com/api/copies/1/valuations/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "professional_appraisal", "amount": "25000", "valued_at": "2024-01-15", "currency_code": "USD", "confidence": "high", "valuer": "Central Perk Appraisals", "method": "Comparable sales", "source_url": "https://example.com/appraisals/1994", "reference_number": "CP-1994", "note": "Valued after the Central Perk auction." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "valuation", "id": "1", "attributes": { "copy_id": "1", "type": "professional_appraisal", "amount": 25000, "currency_code": "USD", "valued_at": 1752537600, "confidence": "high", "valuer": null, "method": null, "source_url": null, "reference_number": null, "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/valuations/1" } } } ``` ## Delete a valuation `DELETE https://getkollek.com/api/copies/{copy}/valuations/{valuation}` Delete a valuation. Deleting the latest one hands the current estimated value back to the valuation before it. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the valuation belongs to. - `valuation` (integer, required): The ID of the valuation. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/valuations/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Insurance records ## List insurance records `GET https://getkollek.com/api/copies/{copy}/insurance-records` Retrieve the insurance coverage held against a copy: the policies, providers and insured values it has carried. They are returned newest window first. Coverage is historical. Changing the insured value records a new record rather than overwriting an old one, so a copy accumulates records as its policies and values change. A copy may hold only one active record per policy number at a time. Recording or reviving a second active record under the same policy number is rejected with a validation error. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the insurance record belongs to. ### Query parameters - `per_page` (integer, optional): The number of insurance records to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of insurance record objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/insurance-records \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "insurance_record", "id": "2", "attributes": { "copy_id": "1", "provider": "Collectibles Insurance Services", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "insured_value": 45000, "currency_code": "USD", "deductible_amount": 10000, "deductible_currency_code": "USD", "starts_at": 1704067200, "ends_at": null, "status": "active", "is_scheduled_item": true, "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/insurance-records/2" } }, { "type": "insurance_record", "id": "1", "attributes": { "copy_id": "1", "provider": "Homeowner Rider (Allstate)", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "insured_value": 30000, "currency_code": "USD", "deductible_amount": 10000, "deductible_currency_code": "USD", "starts_at": 1704067200, "ends_at": null, "status": "expired", "is_scheduled_item": true, "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/insurance-records/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/insurance-records?page=1", "last": "https://getkollek.com/api/copies/1/insurance-records?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/insurance-records?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/insurance-records", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get an insurance record `GET https://getkollek.com/api/copies/{copy}/insurance-records/{insuranceRecord}` Retrieve a single insurance record of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the insurance record belongs to. - `insuranceRecord` (integer, required): The ID of the insurance record. **Returns:** An insurance record object, or 404 when the record does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/insurance-records/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "insurance_record", "id": "1", "attributes": { "copy_id": "1", "provider": "Collectibles Insurance Services", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "insured_value": 45000, "currency_code": "USD", "deductible_amount": 10000, "deductible_currency_code": "USD", "starts_at": 1704067200, "ends_at": null, "status": "active", "is_scheduled_item": true, "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/insurance-records/1" } } } ``` ## Create an insurance record `POST https://getkollek.com/api/copies/{copy}/insurance-records` Record a piece of insurance coverage against a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the insurance record belongs to. ### Body parameters - `provider` (string, required): The insurer that holds the coverage. - `insured_value` (integer, required): What the copy is insured for, in the smallest currency unit (e.g. cents). - `status` (string, optional): Where the coverage stands. One of active, expired, cancelled or pending. Defaults to active. A copy may hold only one active record per policy number at a time. - `currency_code` (string, optional): The three letter currency code the insured value is expressed in. Defaults to the currency of the collection. - `policy_number` (string, optional): The policy number the coverage sits under. - `coverage_type` (string, optional): What kind of coverage this is, such as a scheduled item or blanket contents. - `deductible_amount` (integer, optional): The deductible, in the smallest currency unit. - `deductible_currency_code` (string, optional): The three letter currency code the deductible is expressed in. Defaults to the currency of the insured value. - `starts_at` (string, optional): The date the coverage begins, in YYYY-MM-DD format. - `ends_at` (string, optional): The date the coverage ends, in YYYY-MM-DD format. Leave it out for ongoing coverage. - `is_scheduled_item` (boolean, optional): Whether the copy is individually listed on the policy rather than covered under blanket contents. - `contact_name` (string, optional): The broker or agent for the policy. - `contact_email` (string, optional): The email of the broker or agent. - `contact_phone` (string, optional): The phone number of the broker or agent. - `note` (string, optional): A free form note about the coverage. **Returns:** The created insurance record object. ### Example request ```bash curl https://getkollek.com/api/copies/1/insurance-records \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "provider": "Collectibles Insurance Services", "insured_value": "45000", "status": "active", "currency_code": "USD", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "deductible_amount": "10000", "deductible_currency_code": "USD", "starts_at": "2024-01-01", "ends_at": "2025-01-01", "is_scheduled_item": "true", "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": "On the fine-collectibles rider." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "insurance_record", "id": "1", "attributes": { "copy_id": "1", "provider": "Collectibles Insurance Services", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "insured_value": 45000, "currency_code": "USD", "deductible_amount": 10000, "deductible_currency_code": "USD", "starts_at": 1704067200, "ends_at": null, "status": "active", "is_scheduled_item": true, "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/insurance-records/1" } } } ``` ## Update an insurance record `PUT https://getkollek.com/api/copies/{copy}/insurance-records/{insuranceRecord}` Update an insurance record. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the insurance record belongs to. - `insuranceRecord` (integer, required): The ID of the insurance record. ### Body parameters - `provider` (string, required): The insurer that holds the coverage. - `insured_value` (integer, required): What the copy is insured for, in the smallest currency unit (e.g. cents). - `status` (string, optional): Where the coverage stands. One of active, expired, cancelled or pending. Defaults to active. A copy may hold only one active record per policy number at a time. - `currency_code` (string, optional): The three letter currency code the insured value is expressed in. Defaults to the currency of the collection. - `policy_number` (string, optional): The policy number the coverage sits under. - `coverage_type` (string, optional): What kind of coverage this is, such as a scheduled item or blanket contents. - `deductible_amount` (integer, optional): The deductible, in the smallest currency unit. - `deductible_currency_code` (string, optional): The three letter currency code the deductible is expressed in. Defaults to the currency of the insured value. - `starts_at` (string, optional): The date the coverage begins, in YYYY-MM-DD format. - `ends_at` (string, optional): The date the coverage ends, in YYYY-MM-DD format. Leave it out for ongoing coverage. - `is_scheduled_item` (boolean, optional): Whether the copy is individually listed on the policy rather than covered under blanket contents. - `contact_name` (string, optional): The broker or agent for the policy. - `contact_email` (string, optional): The email of the broker or agent. - `contact_phone` (string, optional): The phone number of the broker or agent. - `note` (string, optional): A free form note about the coverage. **Returns:** The updated insurance record object. ### Example request ```bash curl https://getkollek.com/api/copies/1/insurance-records/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "provider": "Collectibles Insurance Services", "insured_value": "45000", "status": "active", "currency_code": "USD", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "deductible_amount": "10000", "deductible_currency_code": "USD", "starts_at": "2024-01-01", "ends_at": "2025-01-01", "is_scheduled_item": "true", "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": "On the fine-collectibles rider." }' ``` ### Example response `Status: 200` ```json { "data": { "type": "insurance_record", "id": "1", "attributes": { "copy_id": "1", "provider": "Collectibles Insurance Services", "policy_number": "CIS-88231", "coverage_type": "Scheduled item", "insured_value": 45000, "currency_code": "USD", "deductible_amount": 10000, "deductible_currency_code": "USD", "starts_at": 1704067200, "ends_at": null, "status": "active", "is_scheduled_item": true, "contact_name": "Dana Whitfield", "contact_email": "dana@cisinsurance.com", "contact_phone": "+1 888 837 9537", "note": null, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/insurance-records/1" } } } ``` ## Delete an insurance record `DELETE https://getkollek.com/api/copies/{copy}/insurance-records/{insuranceRecord}` Delete an insurance record. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the insurance record belongs to. - `insuranceRecord` (integer, required): The ID of the insurance record. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/insurance-records/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Maintenance records ## List maintenance records `GET https://getkollek.com/api/copies/{copy}/maintenance-records` Retrieve the work logged against a copy: the cleanings, repairs, servicings, conservations, restorations, replacements and inspections it has been through. They are returned newest first. Maintenance costs live on this model rather than in transactions, so a record carries its own cost and currency. A record marked for provenance generates a matching provenance event, so a significant restoration or conservation also reads in the object's documented story. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the maintenance record belongs to. ### Query parameters - `per_page` (integer, optional): The number of maintenance records to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of maintenance record objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/maintenance-records \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "maintenance_record", "id": "2", "attributes": { "copy_id": "1", "provenance_event_id": null, "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": 1704067200, "cost_amount": 12000, "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": 1735689600, "include_in_provenance": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/maintenance-records/2" } }, { "type": "maintenance_record", "id": "1", "attributes": { "copy_id": "1", "provenance_event_id": null, "type": "inspection", "title": "Annual condition check", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": 1704067200, "cost_amount": null, "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": 1735689600, "include_in_provenance": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/maintenance-records/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/maintenance-records?page=1", "last": "https://getkollek.com/api/copies/1/maintenance-records?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/maintenance-records?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/maintenance-records", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a maintenance record `GET https://getkollek.com/api/copies/{copy}/maintenance-records/{maintenanceRecord}` Retrieve a single maintenance record of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the maintenance record belongs to. - `maintenanceRecord` (integer, required): The ID of the maintenance record. **Returns:** A maintenance record object, or 404 when the record does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/maintenance-records/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "maintenance_record", "id": "1", "attributes": { "copy_id": "1", "provenance_event_id": null, "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": 1704067200, "cost_amount": 12000, "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": 1735689600, "include_in_provenance": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/maintenance-records/1" } } } ``` ## Create a maintenance record `POST https://getkollek.com/api/copies/{copy}/maintenance-records` Log a piece of work performed on a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the maintenance record belongs to. ### Body parameters - `type` (string, required): What kind of work this was. One of cleaning, repair, servicing, conservation, restoration, replacement or inspection. - `title` (string, required): A short summary of the work. - `description` (string, optional): The detail behind the title. - `performed_by` (string, optional): Who performed the work. - `performed_at` (string, optional): The date the work was done, in YYYY-MM-DD format. - `cost_amount` (integer, optional): What the work cost, in the smallest currency unit (e.g. cents). - `cost_currency_code` (string, optional): The three letter currency code the cost is expressed in. Defaults to the currency of the collection. - `item_condition_before_id` (integer, optional): The ID of the condition the copy was in before the work. Must be a condition of your account. - `item_condition_after_id` (integer, optional): The ID of the condition the copy is in after the work. Must be a condition of your account. Setting it updates the copy's current condition. - `next_due_at` (string, optional): When this care is next due, in YYYY-MM-DD format. Leave it out when the work is not recurring. - `include_in_provenance` (boolean, optional): Whether the work is significant enough to belong to the object's story. When true, a matching provenance event is generated; setting it back to false removes that event. **Returns:** The created maintenance record object. ### Example request ```bash curl https://getkollek.com/api/copies/1/maintenance-records \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": "2024-01-01", "cost_amount": "12000", "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": "2025-01-01", "include_in_provenance": "false" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "maintenance_record", "id": "1", "attributes": { "copy_id": "1", "provenance_event_id": null, "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": 1704067200, "cost_amount": 12000, "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": 1735689600, "include_in_provenance": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/maintenance-records/1" } } } ``` ## Update a maintenance record `PUT https://getkollek.com/api/copies/{copy}/maintenance-records/{maintenanceRecord}` Update a maintenance record. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the maintenance record belongs to. - `maintenanceRecord` (integer, required): The ID of the maintenance record. ### Body parameters - `type` (string, required): What kind of work this was. One of cleaning, repair, servicing, conservation, restoration, replacement or inspection. - `title` (string, required): A short summary of the work. - `description` (string, optional): The detail behind the title. - `performed_by` (string, optional): Who performed the work. - `performed_at` (string, optional): The date the work was done, in YYYY-MM-DD format. - `cost_amount` (integer, optional): What the work cost, in the smallest currency unit (e.g. cents). - `cost_currency_code` (string, optional): The three letter currency code the cost is expressed in. Defaults to the currency of the collection. - `item_condition_before_id` (integer, optional): The ID of the condition the copy was in before the work. Must be a condition of your account. - `item_condition_after_id` (integer, optional): The ID of the condition the copy is in after the work. Must be a condition of your account. Setting it updates the copy's current condition. - `next_due_at` (string, optional): When this care is next due, in YYYY-MM-DD format. Leave it out when the work is not recurring. - `include_in_provenance` (boolean, optional): Whether the work is significant enough to belong to the object's story. When true, a matching provenance event is generated; setting it back to false removes that event. **Returns:** The updated maintenance record object. ### Example request ```bash curl https://getkollek.com/api/copies/1/maintenance-records/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": "2024-01-01", "cost_amount": "12000", "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": "2025-01-01", "include_in_provenance": "false" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "maintenance_record", "id": "1", "attributes": { "copy_id": "1", "provenance_event_id": null, "type": "conservation", "title": "Archival cleaning and re-housing", "description": "Surface cleaned and re-boxed in archival storage.", "performed_by": "Atelier Restauration", "performed_at": 1704067200, "cost_amount": 12000, "cost_currency_code": "USD", "item_condition_before_id": "3", "item_condition_after_id": "1", "next_due_at": 1735689600, "include_in_provenance": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/maintenance-records/1" } } } ``` ## Delete a maintenance record `DELETE https://getkollek.com/api/copies/{copy}/maintenance-records/{maintenanceRecord}` Delete a maintenance record. Any provenance event it generated is removed with it. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the maintenance record belongs to. - `maintenanceRecord` (integer, required): The ID of the maintenance record. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/maintenance-records/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Location history ## List location history `GET https://getkollek.com/api/copies/{copy}/location-history` Retrieve where a copy has been stored over time: each place it lived and the period it was there. They are returned newest move first. The open record, with no moved_out_at, is where the copy is now. A copy has at most one open record at a time, and its current location always mirrors that record. Ordinary movement is not provenance; a historically significant institutional movement is recorded separately as a provenance event. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the record belongs to. ### Query parameters - `per_page` (integer, optional): The number of records to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of location history objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/location-history \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "location_history", "id": "2", "attributes": { "copy_id": "1", "location_id": "4", "moved_at": 1704067200, "moved_out_at": null, "reason": "Rotated into the display case", "note": null, "is_open": true, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/location-history/2" } }, { "type": "location_history", "id": "1", "attributes": { "copy_id": "1", "location_id": "2", "moved_at": 1704067200, "moved_out_at": 1704067200, "reason": "Rotated into the display case", "note": null, "is_open": false, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/location-history/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/location-history?page=1", "last": "https://getkollek.com/api/copies/1/location-history?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/location-history?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/location-history", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a location record `GET https://getkollek.com/api/copies/{copy}/location-history/{locationHistory}` Retrieve a single location history record of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the record belongs to. - `locationHistory` (integer, required): The ID of the location history record. **Returns:** A location history object, or 404 when the record does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/location-history/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "location_history", "id": "1", "attributes": { "copy_id": "1", "location_id": "4", "moved_at": 1704067200, "moved_out_at": null, "reason": "Rotated into the display case", "note": null, "is_open": true, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/location-history/1" } } } ``` ## Move a copy `POST https://getkollek.com/api/copies/{copy}/location-history` Move a copy to a location. This closes the copy's open record, opens a new one and updates its current location in one step, so the copy and its history never disagree about where it is. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the record belongs to. ### Body parameters - `location_id` (integer, required): The ID of the location the copy is moving to. Must be a location of your account. - `moved_at` (string, required): The date the copy arrived at the location, in YYYY-MM-DD format. - `reason` (string, optional): Why the copy was moved. - `note` (string, optional): A free form note about the move. **Returns:** The new open location history record. ### Example request ```bash curl https://getkollek.com/api/copies/1/location-history \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "location_id": "4", "moved_at": "2024-01-01", "reason": "Rotated into the display case", "note": "Front row, eye level." }' ``` ### Example response `Status: 201` ```json { "data": { "type": "location_history", "id": "1", "attributes": { "copy_id": "1", "location_id": "4", "moved_at": 1704067200, "moved_out_at": null, "reason": "Rotated into the display case", "note": null, "is_open": true, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/location-history/1" } } } ``` ## Correct a location record `PUT https://getkollek.com/api/copies/{copy}/location-history/{locationHistory}` Correct a location history record that was logged wrong. Every field is replaced, so send the ones you want to keep. The copy's current location is recomputed from the history afterwards. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the record belongs to. - `locationHistory` (integer, required): The ID of the location history record. ### Body parameters - `location_id` (integer, required): The ID of the location the copy is moving to. Must be a location of your account. - `moved_at` (string, required): The date the copy arrived at the location, in YYYY-MM-DD format. - `reason` (string, optional): Why the copy was moved. - `note` (string, optional): A free form note about the move. - `moved_out_at` (string, optional): The date the copy left the location, in YYYY-MM-DD format. Leave it out for the record that is still open. **Returns:** The updated location history record. ### Example request ```bash curl https://getkollek.com/api/copies/1/location-history/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "location_id": "4", "moved_at": "2024-01-01", "reason": "Rotated into the display case", "note": "Front row, eye level.", "moved_out_at": "2024-06-01" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "location_history", "id": "1", "attributes": { "copy_id": "1", "location_id": "4", "moved_at": 1704067200, "moved_out_at": null, "reason": "Rotated into the display case", "note": null, "is_open": true, "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/copies/1/location-history/1" } } } ``` ## Delete a location record `DELETE https://getkollek.com/api/copies/{copy}/location-history/{locationHistory}` Delete a location history record. If it was the open record, the copy's current location falls back to what remains. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the record belongs to. - `locationHistory` (integer, required): The ID of the location history record. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/location-history/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Loans ## List all loans `GET https://getkollek.com/api/loans` Retrieve every loan in your account, across all copies, newest first. This is the account-wide view the Loans section is built on. Optional filters narrow the list by direction and status. A loan moves custody without moving ownership. Each entry carries a context block with the object it is about (item name, copy identifier and collection), so a list is readable without a second request per loan. **Permissions:** Any member of the account. ### Query parameters - `direction` (string, optional): Narrow the list to one direction: outgoing (lent out) or incoming (borrowed in). - `status` (string, optional): Narrow the list to one status: planned, active, overdue, returned, cancelled or lost. - `per_page` (integer, optional): The number of loans to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of loan objects. ### Example request ```bash curl https://getkollek.com/api/loans \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "loan", "id": "2", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/2" } }, { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "incoming", "status": "returned", "party": "A private collector", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } ], "links": { "first": "https://getkollek.com/api/loans?page=1", "last": "https://getkollek.com/api/loans?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/loans?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/loans", "per_page": 10, "to": 2, "total": 2 } } ``` ## List loans of a copy `GET https://getkollek.com/api/copies/{copy}/loans` Retrieve the loans recorded against a copy: the pieces lent out and the pieces borrowed in. They are returned newest first. A loan moves custody without moving ownership. An outgoing loan that is active or overdue means the copy is not currently in your physical custody, and the copy reads as loaned out while one is outstanding. A loan marked for provenance generates a matching provenance event for the loan and, once it is returned, another for the return, so an institutional loan or an exhibition also reads in the object's documented story. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. ### Query parameters - `per_page` (integer, optional): The number of loans to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of loan objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "loan", "id": "2", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/2" } }, { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "incoming", "status": "returned", "party": "A private collector", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/loans?page=1", "last": "https://getkollek.com/api/copies/1/loans?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/loans?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/loans", "per_page": 10, "to": 2, "total": 2 } } ``` ## Get a loan `GET https://getkollek.com/api/copies/{copy}/loans/{loan}` Retrieve a single loan of a copy by its ID. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. - `loan` (integer, required): The ID of the loan. **Returns:** A loan object, or 404 when the loan does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } } ``` ## Create a loan `POST https://getkollek.com/api/copies/{copy}/loans` Record a loan against a copy. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. ### Body parameters - `direction` (string, required): Which way custody moves. One of outgoing (a piece lent out) or incoming (a piece borrowed in). - `status` (string, optional): Where the loan sits in its lifecycle. One of planned, active, overdue, returned, cancelled or lost. Defaults to active. Prefer the return endpoint over setting returned by hand, and leave overdue to be reached on its own. - `party` (string, required): Who the copy was lent to or borrowed from. - `purpose` (string, optional): Why the copy was loaned. - `loaned_at` (string, required): The date the copy left or arrived, in YYYY-MM-DD format. - `due_at` (string, optional): When the copy is expected back, in YYYY-MM-DD format. Leave it out for an open ended loan. - `returned_at` (string, optional): When the loan was closed, in YYYY-MM-DD format. Usually set through the return endpoint rather than here. - `item_condition_out_id` (integer, optional): The ID of the condition the copy was in when it left. Must be a condition of your account. - `item_condition_in_id` (integer, optional): The ID of the condition the copy was in when it came back. Must be a condition of your account. - `deposit_amount` (integer, optional): A deposit held against the loan, in the smallest currency unit (e.g. cents). - `deposit_currency_code` (string, optional): The three letter currency code the deposit is expressed in. Defaults to the currency of the collection. - `include_in_provenance` (boolean, optional): Whether the loan belongs to the object's story. When true, a matching provenance event is generated for the loan, and another for the return; setting it back to false removes them. **Returns:** The created loan object. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": "2024-01-01", "due_at": "2024-07-01", "returned_at": "2024-06-15", "item_condition_out_id": "1", "item_condition_in_id": "3", "deposit_amount": "250000", "deposit_currency_code": "USD", "include_in_provenance": "true" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } } ``` ## Update a loan `PUT https://getkollek.com/api/copies/{copy}/loans/{loan}` Update a loan. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. - `loan` (integer, required): The ID of the loan. ### Body parameters - `direction` (string, required): Which way custody moves. One of outgoing (a piece lent out) or incoming (a piece borrowed in). - `status` (string, optional): Where the loan sits in its lifecycle. One of planned, active, overdue, returned, cancelled or lost. Defaults to active. Prefer the return endpoint over setting returned by hand, and leave overdue to be reached on its own. - `party` (string, required): Who the copy was lent to or borrowed from. - `purpose` (string, optional): Why the copy was loaned. - `loaned_at` (string, required): The date the copy left or arrived, in YYYY-MM-DD format. - `due_at` (string, optional): When the copy is expected back, in YYYY-MM-DD format. Leave it out for an open ended loan. - `returned_at` (string, optional): When the loan was closed, in YYYY-MM-DD format. Usually set through the return endpoint rather than here. - `item_condition_out_id` (integer, optional): The ID of the condition the copy was in when it left. Must be a condition of your account. - `item_condition_in_id` (integer, optional): The ID of the condition the copy was in when it came back. Must be a condition of your account. - `deposit_amount` (integer, optional): A deposit held against the loan, in the smallest currency unit (e.g. cents). - `deposit_currency_code` (string, optional): The three letter currency code the deposit is expressed in. Defaults to the currency of the collection. - `include_in_provenance` (boolean, optional): Whether the loan belongs to the object's story. When true, a matching provenance event is generated for the loan, and another for the return; setting it back to false removes them. **Returns:** The updated loan object. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": "2024-01-01", "due_at": "2024-07-01", "returned_at": "2024-06-15", "item_condition_out_id": "1", "item_condition_in_id": "3", "deposit_amount": "250000", "deposit_currency_code": "USD", "include_in_provenance": "true" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "active", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } } ``` ## Return a loan `POST https://getkollek.com/api/copies/{copy}/loans/{loan}/return` Mark an open loan as returned. This closes it with the return date and the condition it came back in, brings the copy back into your custody, and, when the loan is part of provenance, records the return in the object's story. A loan that is already closed returns a 404. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. - `loan` (integer, required): The ID of the loan. ### Body parameters - `returned_at` (string, required): The date the copy came back, in YYYY-MM-DD format. - `item_condition_in_id` (integer, optional): The ID of the condition the copy came back in. Must be a condition of your account. Setting it updates the copy's current condition. **Returns:** The returned loan object. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans/1/return \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "returned_at": "2024-06-15", "item_condition_in_id": "3" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "loan", "id": "1", "attributes": { "copy_id": "1", "loan_provenance_event_id": null, "return_provenance_event_id": null, "direction": "outgoing", "status": "returned", "party": "The Whitney Museum", "purpose": "Retrospective exhibition, east wing.", "loaned_at": 1704067200, "due_at": 1719792000, "returned_at": null, "item_condition_out_id": "1", "item_condition_in_id": null, "deposit_amount": 250000, "deposit_currency_code": "USD", "include_in_provenance": true, "created_at": 1752537600, "updated_at": 1752537600 }, "context": { "item_name": "Amazing Spider-Man #1", "copy_identifier": "CBX-042", "collection_name": "My Comics" }, "links": { "self": "https://getkollek.com/api/copies/1/loans/1" } } } ``` ## Delete a loan `DELETE https://getkollek.com/api/copies/{copy}/loans/{loan}` Delete a loan. Any provenance events it generated are removed with it, and a copy left with no outstanding loan comes back into your custody. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy the loan belongs to. - `loan` (integer, required): The ID of the loan. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/copies/1/loans/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Documents ## List documents `GET https://getkollek.com/api/copies/{copy}/documents` Retrieve the documents attached to a copy and to every record on it: its transactions, provenance events, valuations, insurance records, maintenance records and loans. Each document names the record it hangs from through documentable_type and documentable_id. A document is either a file stored with us or a link to one held elsewhere. A stored file is never served from a public URL; reach it through the download_url, which streams it to members of the account. Deleting a document removes its stored file too, and deleting a record removes the documents attached to it. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy whose documents you are listing or adding to. ### Query parameters - `per_page` (integer, optional): The number of documents to return per page, between 1 and 100. Default: `10`. - `page` (integer, optional): The page number to return. Default: `1`. **Returns:** A paginated list of document objects. ### Example request ```bash curl https://getkollek.com/api/copies/1/documents \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "document", "id": "2", "attributes": { "documentable_type": "valuation", "documentable_id": "5", "document_type": "receipt", "name": "Appraisal report", "external_url": null, "download_url": "https://getkollek.com/api/documents/2", "mime_type": "application/pdf", "size": 248000, "description": "Signed and dated by the appraiser.", "issued_at": 1704067200, "reference_number": "INV-2024-0117", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/documents/2" } }, { "type": "document", "id": "1", "attributes": { "documentable_type": "copy", "documentable_id": "1", "document_type": "receipt", "name": "Certificate of authenticity", "external_url": "https://drive.example.com/appraisal.pdf", "download_url": null, "mime_type": null, "size": null, "description": "Signed and dated by the appraiser.", "issued_at": 1704067200, "reference_number": "INV-2024-0117", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/documents/1" } } ], "links": { "first": "https://getkollek.com/api/copies/1/documents?page=1", "last": "https://getkollek.com/api/copies/1/documents?page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://getkollek.com/api/copies/1/documents?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "path": "https://getkollek.com/api/copies/1/documents", "per_page": 10, "to": 2, "total": 2 } } ``` ## Add a document `POST https://getkollek.com/api/copies/{copy}/documents` Attach a document to a copy or one of its records, by uploading a file as multipart/form-data or by pointing at an external URL. Provide exactly one of the two. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `copy` (integer, required): The ID of the copy whose documents you are listing or adding to. ### Body parameters - `documentable_type` (string, optional): The kind of record the document is attached to. One of copy, transaction, provenance_event, valuation, insurance_record, maintenance_record or loan. Defaults to copy. - `documentable_id` (integer, optional): The ID of the record the document is attached to. Must belong to the copy in the path. Defaults to the copy itself. - `type` (string, required): What the document is. One of receipt, invoice, certificate, appraisal, insurance, photograph, condition_report, restoration_report, catalogue, correspondence, ownership_record, authenticity_record or other. - `name` (string, required): The display name of the document. - `file` (file, optional): The file to store, sent as multipart/form-data. Provide either a file or an external_url, not both. A stored file may be up to 20 MB and must be a PDF, an image, or a common document or spreadsheet format. - `external_url` (string, optional): A link to a file held elsewhere, used instead of uploading one. Provide either a file or an external_url. - `description` (string, optional): A free note about the document. - `issued_at` (string, optional): The date the document was issued, in YYYY-MM-DD format. - `reference_number` (string, optional): An external reference such as an invoice or certificate number. **Returns:** The created document object. ### Example request ```bash curl https://getkollek.com/api/copies/1/documents \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "documentable_type": "valuation", "documentable_id": "5", "type": "appraisal", "name": "Appraisal report", "file": "@appraisal.pdf", "external_url": "https://drive.example.com/appraisal.pdf", "description": "Signed and dated by the appraiser.", "issued_at": "2024-01-01", "reference_number": "INV-2024-0117" }' ``` ### Example response `Status: 201` ```json { "data": { "type": "document", "id": "1", "attributes": { "documentable_type": "valuation", "documentable_id": "5", "document_type": "receipt", "name": "Appraisal report", "external_url": null, "download_url": "https://getkollek.com/api/documents/1", "mime_type": "application/pdf", "size": 248000, "description": "Signed and dated by the appraiser.", "issued_at": 1704067200, "reference_number": "INV-2024-0117", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/documents/1" } } } ``` ## Get a document `GET https://getkollek.com/api/documents/{document}` Retrieve a single document by its ID. The stored disk path is never exposed; a stored file is reached through its download_url. **Permissions:** Any member of the account. ### Path parameters - `document` (integer, required): The ID of the document. **Returns:** A document object, or 404 when the document does not belong to your account. ### Example request ```bash curl https://getkollek.com/api/documents/1 \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "document", "id": "1", "attributes": { "documentable_type": "valuation", "documentable_id": "5", "document_type": "receipt", "name": "Appraisal report", "external_url": null, "download_url": "https://getkollek.com/api/documents/1", "mime_type": "application/pdf", "size": 248000, "description": "Signed and dated by the appraiser.", "issued_at": 1704067200, "reference_number": "INV-2024-0117", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/documents/1" } } } ``` ## Update a document `PUT https://getkollek.com/api/documents/{document}` Update a document's details. The stored file or the external link itself does not change here; to replace what is stored, delete the document and add a fresh one. Every field is replaced, so send the ones you want to keep along with the ones you are changing. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `document` (integer, required): The ID of the document. ### Body parameters - `type` (string, required): What the document is. One of receipt, invoice, certificate, appraisal, insurance, photograph, condition_report, restoration_report, catalogue, correspondence, ownership_record, authenticity_record or other. - `name` (string, required): The display name of the document. - `description` (string, optional): A free note about the document. - `issued_at` (string, optional): The date the document was issued, in YYYY-MM-DD format. - `reference_number` (string, optional): An external reference such as an invoice or certificate number. **Returns:** The updated document object. ### Example request ```bash curl https://getkollek.com/api/documents/1 \ -X PUT \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "type": "appraisal", "name": "Appraisal report", "description": "Signed and dated by the appraiser.", "issued_at": "2024-01-01", "reference_number": "INV-2024-0117" }' ``` ### Example response `Status: 200` ```json { "data": { "type": "document", "id": "1", "attributes": { "documentable_type": "valuation", "documentable_id": "5", "document_type": "receipt", "name": "Appraisal report", "external_url": null, "download_url": "https://getkollek.com/api/documents/1", "mime_type": "application/pdf", "size": 248000, "description": "Signed and dated by the appraiser.", "issued_at": 1704067200, "reference_number": "INV-2024-0117", "created_at": 1752537600, "updated_at": 1752537600 }, "links": { "self": "https://getkollek.com/api/documents/1" } } } ``` ## Delete a document `DELETE https://getkollek.com/api/documents/{document}` Delete a document. If it is a stored file, the file is removed from disk as well. This cannot be undone. **Permissions:** Owners and editors. Viewers get a 404 response. ### Path parameters - `document` (integer, required): The ID of the document. **Returns:** An empty response. ### Example request ```bash curl https://getkollek.com/api/documents/1 \ -X DELETE \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 204` The response has no body. # Copy history ## Get a copy's history `GET https://getkollek.com/api/copies/{copy}/history` Retrieve the unified history of a copy: its qualifying transactions, provenance events, valuations, insurance records, meaningful maintenance, loans and returns, and location moves, merged into one chronological read, newest first. The history is a read model, not a stored table. Every entry is assembled from a source record at read time, and each source stays the source of truth for its own data. An entry names the source it came from through source_type and source_id, so you can fetch the full record from its own endpoint. Only the historically meaningful entries are returned by default. Pass view=complete to add the routine records. Undated entries, and provenance events recorded as unknown, sort to the end. Amounts are returned in cents in the currency they were recorded in, and are never converted. **Permissions:** Any member of the account. ### Path parameters - `copy` (integer, required): The ID of the copy whose history you are reading. ### Query parameters - `view` (string, optional): Which entries to include. meaningful returns only the historically meaningful ones; complete adds the routine records too, such as ordinary location moves, informal loans and routine maintenance. Default: `meaningful`. - `type` (array, optional): Filter to one or more sources, sent as repeated type parameters (type[]=valuation&type[]=loan). One of transaction, provenance, valuation, insurance, maintenance, loan or location. Omit to include every source. **Returns:** A list of timeline entry objects, newest first. ### Example request ```bash curl https://getkollek.com/api/copies/1/history \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": [ { "type": "timeline_entry", "id": "location-9", "attributes": { "source_type": "location", "source_id": "9", "title": "Moved to Secure storage", "summary": "Climate-controlled unit", "date": 1782777600, "date_precision": "exact", "amount": null, "currency_code": null, "meaningful": false } }, { "type": "timeline_entry", "id": "loan-4-return", "attributes": { "source_type": "loan", "source_id": "4", "title": "Returned from Montreal Museum of Fine Arts", "summary": "Condition in: Excellent", "date": 1743465600, "date_precision": "exact", "amount": null, "currency_code": null, "meaningful": true } }, { "type": "timeline_entry", "id": "valuation-5", "attributes": { "source_type": "valuation", "source_id": "5", "title": "Professional appraisal", "summary": "Jane Smith", "date": 1325376000, "date_precision": "exact", "amount": 450000, "currency_code": "CAD", "meaningful": true } }, { "type": "timeline_entry", "id": "provenance-2", "attributes": { "source_type": "provenance", "source_id": "2", "title": "Acquired from Sotheby's", "summary": "Purchased at the London spring sale.", "date": 542764800, "date_precision": "month", "amount": null, "currency_code": null, "meaningful": true } } ] } ``` # Search ## Search your account `GET https://getkollek.com/api/search` Search everything your account holds in one call: items, collections, copies, photos, loans, locations, sets, series, categories, tags and documents. The query is split into words. Every word has to match somewhere in a record, so adding a word narrows the result rather than widening it. A word matches from its start, which means spi finds Spider-Man, and case and punctuation are ignored, so asm-300, asm 300 and ASM_300 behave the same. Single character words are never indexed on their own, so they are dropped. A query made only of single characters therefore returns nothing rather than everything. Names and descriptions are encrypted at rest, so the search runs against an index of keyed hashes rather than the text itself. That index is built as records change; a freshly upgraded instance fills it by running php artisan search:rebuild-index once. A result is scored by the weakest field its words matched in: 100 when every word appeared in the name of the record, 80 for an identifier or a file name, 60 for something filed around it such as its collection or a tag, and 30 for a description or a note. Results come back ranked, at most 50 of them, and total says how many matched in all. Objects in the trash are not searched. Every result carries a self link to the screen in the web app that shows it. A tag is only visible to owners and editors, so results of that type are absent for a viewer. **Permissions:** Any member of the account. Results never cross accounts. ### Query parameters - `q` (string, required): The words to search for, up to 255 characters. - `type` (string, optional): Narrow the results to one kind of record. One of item, collection, copy, photo, loan, location, set, series, category, tag or document. **Returns:** A search_results object. ### Example request ```bash curl https://getkollek.com/api/search?q=spider \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "search_results", "attributes": { "query": "spider", "total": 4, "matched": 4, "truncated": false, "counts": { "item": 2, "copy": 1, "tag": 1 }, "results": [ { "type": "item", "id": "812", "title": "Amazing Spider-Man #365", "context": "2 copies", "collection_name": "Marvel Comics 1990s", "score": 100, "name_match": true, "links": { "self": "https://getkollek.com/api/collections/3/items/812" } }, { "type": "item", "id": "640", "title": "Amazing Spider-Man #300", "context": "1 copy", "collection_name": "Marvel Comics 1990s", "score": 100, "name_match": true, "links": { "self": "https://getkollek.com/api/collections/3/items/640" } }, { "type": "copy", "id": "990", "title": "ASM-300-B", "context": "Amazing Spider-Man #300 ยท Very Fine ยท Display Case", "collection_name": "Marvel Comics 1990s", "score": 60, "name_match": false, "links": { "self": "https://getkollek.com/api/collections/3/items/640/copies/990" } }, { "type": "tag", "id": "18", "title": "spider-man", "context": "41 items", "collection_name": null, "score": 100, "name_match": true, "links": { "self": "https://getkollek.com/api/settings/tags" } } ] } } } ``` # Dashboard ## Get the dashboard of your account `GET https://getkollek.com/api/dashboard` Retrieve the aggregates behind the dashboard: what the account holds, what it is worth, what was catalogued last, where custody stands and where the value physically sits. These are computed values rather than stored records, so the object has no created_at or updated_at. Every amount is an integer in cents. A collection may name a currency of its own, but an account wide roll up has to settle on one, so every amount here reads in the currency of the account, returned as currency. Amounts come from the copies of the items, so an item with no copy counts towards items and contributes nothing to any amount. A copy nobody has valued counts towards copies but not towards valued_copies, which is how you spot the gap. What a copy is worth is its most recent valuation. value_added_this_month sums what was acquired since the first of the month, by the date of the transaction that brought each copy in. A copy with no such transaction is left out of it. collections lists the four most recently updated collections, recent_additions the five newest items, and value_by_location the five locations holding the most value. A location label is null for the copies filed under no location. **Permissions:** Any member of the account. **Returns:** An account_dashboard object. ### Example request ```bash curl https://getkollek.com/api/dashboard \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json" ``` ### Example response `Status: 200` ```json { "data": { "type": "account_dashboard", "id": "1", "attributes": { "currency": "USD", "totals": { "collections": 4, "items": 567, "copies": 677, "valued_copies": 654, "value": 2031000, "average": 3582, "items_added_this_month": 18, "value_added_this_month": 124000 }, "collections": [ { "collection_id": "1", "collection_name": "Marvel Comics 1990s", "visibility": "shared", "items": 142, "copies": 168, "value": 842000, "updated_at": "2026-08-03T09:12:44+00:00" } ], "recent_additions": [ { "id": "918", "name": "Amazing Spider-Man #365", "collection_id": "1", "collection_name": "Marvel Comics 1990s", "condition": "Near Mint", "location": "Box A1", "copies": 1, "created_at": "2026-08-03T09:12:44+00:00" } ], "loans": { "outgoing": 5, "incoming": 2, "overdue": 2, "dueSoon": 3, "planned": 2, "returned": 4, "deposits": { "USD": 105000 } }, "value_by_location": [ { "label": "Display Case", "value": 684000 }, { "label": null, "value": 42000 } ] }, "links": { "self": "https://getkollek.com/api/dashboard" } } } ```