Skip to content

Attachments

Upload files to a task via a presign → confirm flow (two requests, no chunking): presign for a direct-upload URL, upload the bytes yourself, then confirm to record the attachment. An attachment on a task the caller can't see 404s like the task itself.

GET

/tasks/{id}/attachments

Lists the latest version of each attachment on a task.

Query parameters

  • limitintegeroptionalPage size, default 25, max 100
  • offsetintegeroptionalNumber of results to skip, default 0
POST

/tasks/{id}/attachments/presign

Requests a direct-upload URL for one file. Also checked here: the workspace's storage-plan limit, using the fileSize you declare — rejected with 403 forbidden_plan before you waste an upload.

Body parameters

  • fileNamestringrequiredOriginal file name
  • fileTypestringrequiredMIME type
  • fileSizeintegerrequiredFile size in bytes
POST

/tasks/{id}/attachments/confirm

Records the attachment after you've uploaded the bytes to the presigned URL. Returns the created attachment.

Body parameters

  • fileNamestringrequiredOriginal file name
  • fileTypestringrequiredMIME type
  • fileSizeintegerrequiredFile size in bytes
  • s3KeystringrequiredThe s3Key returned by the presign call
GET

/projects/{id}/attachments

Lists a project's attachments, newest first.

Query parameters

  • limitintegeroptionalPage size, default 25, max 100
  • offsetintegeroptionalNumber of results to skip, default 0
GET

/attachments/{id}/download

Generates a presigned download URL for one task attachment by id.

View example
Presign an upload
curl -X POST https://api.klaarin.com/v1/tasks/318/attachments/presign \
  -H "Authorization: Bearer kl_live_9f2ac…" \
  -H "Content-Type: application/json" \
  -d '{ "fileName": "mockup.png", "fileType": "image/png", "fileSize": 482913 }'
Response
{
  "uploadUrl": "https://cdn.klaarin.com/tasks/318/...-mockup.png?X-Amz-...",
  "s3Key": "tasks/318/1785400000000-mockup.png",
  "fileUrl": "https://cdn.klaarin.com/tasks/318/...-mockup.png"
}