Migrating to restricted access files

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:

  1. use the new file API;
  2. request the temporary signed link right before the download;
  3. keep supporting old and new files at the same time, until the old files are deleted.

In all examples <your_domain> is the company subdomain and <token> is an API token.

Upload a file

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 targetPath
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:

  • GET /cards/{card_id} and GET /cards — for cards;
  • POST /cards/{card_id}/comments and GET /cards/{card_id}/comments — for comments;
  • GET /company/custom-properties — for custom properties.
Download a file

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:

  1. 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.

  2. 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.

Files uploaded earlier

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.

SignalCurrent fileRestricted access file
type1 for a regular attachment11
ida numbera UUID
entity_typeabsentcard, comment or custom_property
Route reference

The card, comment and custom property file routes support the same five operations, each with its own reference page:

Quick check

After updating the integration, verify that:

  • a file of every type you use can be uploaded and downloaded;
  • files with type = 11 are downloaded through a signed link;
  • old files are still handled by the current code;
  • signed links are neither stored nor cached — they expire.
logo
Kaiten
If you have any questions or need help with integration feel free to write us at support@kaiten.ru