Restricted access files are the new way of working with files and will soon replace the current one. This guide helps you migrate your integrations if you use the Kaiten API to work with files.
They are protected by the permissions of their parent entity: a card, a comment or a custom property. They have no permanent public link — before a download the access of the user is checked and a temporary signed link is issued.
The feature is enabled for the whole company under Company settings → Restricted file access. Previously uploaded files are not protected automatically.
After the migration an integration has to:
In all examples <your_domain> is the company subdomain and <token> is an API token.
To upload a file, send a POST request with the Content-Type: multipart/form-data header and a file field. One request uploads one file.
An example of uploading a file to a card:
curl -X POST "https://<your_domain>.kaiten.ru/api/v1/cards/{card_uid}/files" \
-H "Authorization: Bearer <token>" \
-F "file=@/path/to/report.pdf"| Upload target | Path |
|---|---|
| To a card | /cards/{card_uid}/files |
| To a comment | /cards/{card_uid}/comments/{comment_uid}/files |
| To a custom property | /cards/{card_uid}/custom-properties/{property_uid}/files |
The new methods use a UUID instead of a numeric id in the path. The uid field is returned together with the entity. For example:
A restricted access file is downloaded through a temporary signed link. There are two ways to do it, both shown here for a file of a card:
Call GET /cards/{card_uid}/files/{id}. The response contains the file metadata, including the url field with the temporary signed link.
curl "https://<your_domain>.kaiten.ru/api/v1/cards/{card_uid}/files/{id}" \
-H "Authorization: Bearer <token>"{
"id": "9c1f0b7a-4f3d-4a2e-8c11-6b5d7e0a9f21",
"name": "report.pdf",
"size": "6848",
"mime_type": "application/pdf",
"entity_type": "card",
"created": "2026-08-11T11:21:23.390Z",
"updated": "2026-08-11T11:21:23.390Z",
"card_uid": "c50b47ab-0da2-480b-b9af-0e8593a4b850",
"author_uid": "ce7c915b-fedd-462a-bf8f-27b2d40467ee",
"card_cover": false,
"url": "https://<signed-file-url>"
}Every field is described on the Get card file page.
Call GET /cards/{card_uid}/files/{id}/content. In this case the server answers with a 302 redirect to the temporary signed link.
curl -L "https://<your_domain>.kaiten.ru/api/v1/cards/{card_uid}/files/{id}/content" \
-H "Authorization: Bearer <token>"By default the file is served with Content-Disposition: inline; with ?download=true it is served as an attachment.
Old files are not converted once the setting is enabled. They keep their numeric id and public URL and are still served by the current routes.
The files array returned by GET /api/v1/cards/{card_id} may contain files of every type. The signal that tells a restricted access file apart is type = 11.
| Signal | Current file | Restricted access file |
|---|---|---|
| type | 1 for a regular attachment | 11 |
| id | a number | a UUID |
| entity_type | absent | card, comment or custom_property |
The card, comment and custom property file routes support the same five operations, each with its own reference page:
| Operation | Card | Comment | Custom property |
|---|---|---|---|
| POST upload a file | Attach file to card | Attach file to comment | Attach file to custom property |
| GET /{id} get the file metadata with a signed link | Get card file | Get comment file | Get custom property file |
| GET /{id}/content redirect to the signed link | Get card file content | Get comment file content | Get custom property file content |
| PATCH /{id} change name or card_cover | Update card file | Update comment file | Update custom property file |
| DELETE /{id} delete a file | Delete card file | Delete comment file | Delete custom property file |
After updating the integration, verify that: