Skip to content
Get API Key

Concepts

Files

A file is something you upload for a task to work with, or something a task made, and you can download both.

Updated
View as Markdown

Work often starts with a file, such as a spreadsheet to read or a PDF to summarize, and often ends with one, such as a report a worker wrote. The Files API holds both. You upload a file once, give it to as many tasks as you like, and download what a task made.

One store holds every file of a workspace: what you upload and what tasks make. Each has an id that starts with file_. This page explains how a file gets to a task, how to get one back, the size limits, and when a file is kept or goes.

What a file holds

Field What it is
id The file's id: file_ and 32 characters.
filename Up to 255 characters.
mime_type What the file is, such as application/pdf.
size_bytes The size of the file.
created_at When the file was made.
downloadable Always true. An uploaded file can be downloaded here. In Claude Managed Agents it cannot.
expires_at When the file expires, or null when it does not.
scope null for a file you uploaded or kept. { "type": "task", "id" } for a file a task made.

Upload a file

POST /files takes a multipart form with one file part, and optionally expires_in_seconds. Send one file in each upload. The answer is the file.

Shell
curl https://core.thelittleworker.com/api/v1/files \
  -H "x-api-key: $LITTLE_WORKER_API_KEY" \
  -H "Little-Worker-Version: 2026-10-19" \
  -F "[email protected];type=text/csv" \
  -F "expires_in_seconds=86400"
  • Size. A file is at most 500 MB (500,000,000 bytes), and a workspace keeps at most 1 TB of files. A larger file, or an upload into a full workspace, is 413 with error.type request_too_large. The 10 MiB limit on other requests does not apply to an upload.
  • Expiry. expires_in_seconds is a whole number from 3,600 (one hour) to 7,776,000 (90 days). Left out, the file does not expire. An expired file's content is gone at once, and its record stays readable for 30 days more.
  • Name and type. The name is trimmed and cut to 255 characters. A blank name becomes file. The type comes from the part's content type, or is application/octet-stream.

Give a file to a task

A file reaches a task as a resource. Name it when you give the task, in resources:

JSON
{ "type": "file", "file_id": "file_8d4b2f6a0e1c4973a5d8c3e7b9f10264" }

You can add one later with POST /tasks/{task_id}/resources and the same body. A file can be on a task once: a second time is 400. An expired file cannot be given: upload it again.

The task's resource has its own id, which starts with resource_. It also has a mount_path, which is where the file sits on the task's computer, under the task's own folder. Little Worker sets it, and you can only send null. List a task's resources with GET /tasks/{task_id}/resources, and take a file off with DELETE /tasks/{task_id}/resources/{resource_id}. A task and a routine can take up to 100 resources of all kinds. A routine copies its resources onto each task it makes.

There are two other ways to put a file in front of a worker:

  • In a message. A user.message can carry image and document blocks with the bytes inline, as base64 or plain text. One message holds at most 6 images and documents, and a request body is at most 10 MiB. A file or url source in a message block is 400 for now.
  • As a rubric. A task's outcome can use a file as its rubric, with { "type": "file", "file_id" }.

Get a file back

A file a task made has a scope of { "type": "task", "id" }. List a task's files with GET /files?scope_id= and the task's id. GET /files lists them all, newest first, and GET /files/{file_id} reads one.

GET /files/{file_id}/content downloads the bytes. It answers with the file's own content type and a content-disposition of attachment. An expired file, or one whose content is gone, is 404.

Keep a file after history goes

A task's history is not kept forever on every plan, and the files a task made go with it. Keep a file to hold on to it. POST /files/{file_id}/keep turns a file a task made into a saved file with no task scope, so it lasts after the task's history goes. Keeping an upload, or a file you already kept, answers the file as it is.

When a file goes depends on how it was made. You can tell by its scope.

How the file was made scope When it is deleted
Uploaded with POST /files null Never by a purge. By DELETE /files/{file_id}, or at its expires_at if you set one. A purged message that named it loses only the link.
Made by a task { "type": "task", "id" } With the task's history: by the free plan's purge after 7 days, or by DELETE /tasks/{task_id}. Not if you keep it first.
Made by a task, then kept null Only by DELETE /files/{file_id}.
Attached to a chat message in the app, with no upload through the Files API None With its message, when the message is purged.

DELETE /files/{file_id} removes a file and answers { "type": "file_deleted", "id" }. The bytes go too, unless another file still holds the same content. Copies in Little Worker's nightly backups are erased within 31 days after that.

A purge on the free plan removes the files a task made along with the rest of its work, but it keeps your uploaded files and the files you kept. Paid plans keep history until you delete it. See Tasks.

Limits

What Limit
One file 500 MB
Files in a workspace 1 TB in all
Files in one upload 1
expires_in_seconds 3,600 to 7,776,000
After a file expires Its record is readable for 30 more days
Name 255 characters
Resources on a task 100, of all kinds
Images and documents in one message 6
Any other request body 10 MiB

Next steps

  • Tasks: how resources is set when you give a task, and how history is kept.
  • Computers: where a file sits on the computer a task works on.
  • Memory: notes that last from task to task, when a file is too much.

Type a few words, like “give a task” or “errors”.