Skip to main content
Write a file to the session’s machine and pass its path to DOM.setFileInputFiles. List, read and delete what the browser downloaded. These routes talk to the session’s machine, not the browser, so they work while a CDP client is connected. Files live in the session’s memory and end with the session, so there is nothing to clean up and nothing to recover afterwards. The routes add no credit charge and count under the drive throttle. To fetch one URL through the page instead, with the session’s cookies, use POST /v1/session/{id}/files/fetch.

PUT /v1/session/{session_id}/files/{path}

The raw request body is the file, sent as a stream with curl -T or any chunked or sized body. The limit is 200 MB by default, and the route is exempt from the 4 MB body cap of other routes. path is relative to the upload folder and may include subdirectories. An existing file is replaced. A file appears only after its upload completes.
Response (201):

Attach an upload to a file input

Pass the response’s path to the CDP command DOM.setFileInputFiles:
nodeId is the file input’s node, from DOM.querySelector. The guide has a Playwright example.

GET /v1/session/{session_id}/files

List uploads:
modified is in epoch seconds. truncated is true when the folder holds more than the list returns.

DELETE /v1/session/{session_id}/files/{path}

Delete one file, or a directory with everything in it. DELETE /v1/session/{id}/files empties the folder. A delete answers {"session_id": "...", "deleted": 1}, where deleted counts the files removed.

GET /v1/session/{session_id}/downloads

List the browser’s download folder, including downloads started by a click, with or without a connected client:
in_progress is true while Chrome writes the file as .crdownload. Poll until the final name appears.

GET /v1/session/{session_id}/downloads/{name}

Stream one finished file, up to 1 GB. A .crdownload file answers 409 in_progress.
Reading a download counts the bytes sent as your egress, at the datacenter rate whichever exit the session uses. A client that disconnects pays for what it received. A spent quota refuses the read with its usual answer. Uploads are not charged.

DELETE /v1/session/{session_id}/downloads/{name}

Delete one file or directory. DELETE /v1/session/{id}/downloads empties the folder. Deleting the file of a running download makes that download fail in the browser.

Playwright downloads

Playwright sends its own Browser.setDownloadBehavior on connect, to a playwright-artifacts folder, whichever system your client runs on. Those downloads appear in the same list as playwright-downloads/<folder>/<GUID>. Read and delete them by that full name. Encode each part of a name when you put it in a URL:
Playwright’s GUID is the only name these files have. Playwright’s suggested_filename gives the site’s name for the file. Deleting playwright-downloads/<folder> empties that folder and keeps it, and emptying the download folder clears these files too.

What is not listed

Your own Browser.setDownloadBehavior takes precedence while the client that sent it stays connected: Chrome writes where you said, and behavior: "deny" stops downloads. When that client disconnects, Chrome returns to the session’s folder. A downloadPath outside /tmp names a folder on your client’s machine, which the session’s machine does not have. Tilion points it at the session’s folder, so the download still lands and is listed. A path under /tmp stays as you sent it, and those files are not listed unless the folder is the session’s own or Playwright’s. To use your own behavior and the list together, send:

Errors

These routes also answer 402 and 429 like every drive call.