Inject one or more files into the workdir mid-run

Each file is persisted as an artifact (source of truth) and, if the

POST /api/v1/runs/{runId}/files

Each file is persisted as an artifact (source of truth) and, if the container is live, immediately written to the workdir via a file:inject WebSocket frame.

Where a file is kept

Every injected file is written to the working directory. Whether a copy is also kept in flow storage depends on the flow’s .flowignore:

Working directoryFlow storage (shared, pushed to git)
Ordinary pathyesyes — returned in persisted
Matched by .flowignoreyesno — returned in instanceOnly

A file matched by .flowignore is not dropped. It is instance-only: it lives in the working directory, is preserved by that instance’s snapshot, and is restored when the container respawns — it simply is not stored as a flow file and never reaches your git repo. This is the same rule the container’s own file sweep applies, so a path behaves identically whether it is written by the flow or injected through this endpoint.

Because an instance-only file has nowhere to live but a running container’s working directory, injecting one into a sleeping run returns 409 CONTAINER_NOT_RUNNING rather than accepting the request and discarding the file.

The response reports which paths were persisted, which were instanceOnly, and whether the write was also liveDelivered to the running container.

Text by default, binary when you say so

content is UTF-8 text and is written to the workdir exactly as sent.

For a file that is not text — an image, a font, an archive — set encoding: "base64" and send the base64 of the bytes. It is decoded once, on arrival, and the bytes are stored and written verbatim.

Do not base64-encode without declaring it. The string is then written to the workdir as the file, which is what happens to any content sent as text. This was previously the only outcome, because the field did not exist and was silently discarded.

Each file object accepts path, content and encoding, and nothing else. An unrecognised field is a 400, not a silent omission: a request we do not fully understand must not be answered 202, since that status is a promise the write happened as asked.

Limits

LimitValue
Files per callno limit — the body size bounds it
Bytes per file1,000,000
Bytes per request body26,214,400 (25 MiB)

The per-file limit is set by Firestore: each file becomes a document, and a document cannot exceed 1 MiB. Both file limits are measured in bytes, not characters — one multi-byte character costs more than one. Exceeding the body limit returns 413 PAYLOAD_TOO_LARGE with the size sent and the limit in the message, so a client can decide how far to split a batch instead of guessing.

Authentication

Requires a project API key — see Authentication.

Parameters

NameInTypeRequiredDescription
runIdpathstringrequiredUUID of the run.

Request body

FieldTypeRequiredDescription
filesarrayrequired

Responses

StatusDescription
202Files accepted.
400Request body or query parameters failed validation.
404Resource not found or not accessible to this project.
413Request body exceeded 26,214,400 bytes (25 MiB). The message names the size sent and the limit. Split the files across multiple calls.

Tag: Interactions