Prerequisites
Create a dedicated API token with the minimum abilities:workspaces-readworkflows-readworkflow-runs-output-readdocuments-read
workflow-agent and do not send workflow-agent headers.
Your workflow must finish with files.persistWorkspace. Its public output must expose the resulting documents array described in Get Workflow Run Output.
Activate a workflow feed
Send one bootstrap request in cursor mode. Ignore its runs, then store itsmeta.server_time as enabled_at and its meta.next_cursor as the initial cursor.
created_after equal to the stored enabled_at. This excludes runs created before activation while still discovering runs created after activation that take hours or days to complete.
Process one discovery page
For each returned run:- Request the run’s public output.
- Validate that
documentsis an array and every entry containsdocumentIdandfilename. - Build the idempotency key
workflow_id:run_id:documentId. - Store one download event per document.
- Commit the events and
meta.next_cursortogether. - Request the next page when
meta.has_more=true.
meta.has_more=true. After the last page, keep polling with its returned cursor; runs that complete later appear after the stored (completed_at, id) checkpoint.
Download a document
Request a fresh signed URL with the document’sdocumentId, then stream the response to a temporary local file.
size and sha256 when present, flush the file to disk, and rename it atomically on the same volume. Request a new signed URL after expiration; never store a signed URL as durable state.
Reliability rules
- Keep
enabled_atimmutable. - Treat the cursor as opaque.
- Store the page cursor only after its events are durable.
- Use the
workflow_id:run_id:documentIdidempotency key to absorb client or network retries safely. - Never advance past an invalid run output.
- Never use temporary workflow
fileRefdownload routes for persisted documents.
