Skip to main content
Unlike screenshots saved locally, files downloaded during browser automation are stored in Browserbase’s cloud storage. Retrieve them using the Browserbase API. A common use case for headless browsers is downloading files from web pages. Browserbase syncs every downloaded file to cloud storage and appends a Unix timestamp to avoid naming conflicts (e.g., sample.pdf becomes sample-1719265797164.pdf).
View or run the example template here

Triggering downloads

First, trigger a download in your browser automation:
  1. Create a browser session and get the session ID
  2. Connect to the session using your preferred framework
  3. Configure your library’s downloads location
  4. Perform the download action in your automation script
import { chromium } from "playwright-core";
import { Browserbase } from "@browserbasehq/sdk";

(async () => {
  const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
  const session = await bb.sessions.create();

  const browser = await chromium.connectOverCDP(session.connectUrl);
  const defaultContext = browser.contexts()[0];
  const page = defaultContext.pages()[0];

  // Required to avoid playwright overriding location
  const client = await defaultContext.newCDPSession(page);
  await client.send("Browser.setDownloadBehavior", {
    behavior: "allow",
    downloadPath: "downloads",
    eventsEnabled: true,
  });

  await page.goto("https://browser-tests-alpha.vercel.app/api/download-test");

  const [download] = await Promise.all([
    page.waitForEvent("download"),
    page.locator("#download").click(),
  ]);

  let downloadError = await download.failure();
  if (downloadError !== null) {
    console.log("Error happened on download:", downloadError);
    throw new Error(downloadError);
  }

  // Store the session ID to retrieve downloads later
  console.log("Download completed. Session ID:", session.id);

  await page.close();
  await browser.close();
})().catch((error) => console.error(error.message));
Critical: setDownloadBehavior ConfigurationWhen using Playwright or Puppeteer, you must call Browser.setDownloadBehavior via CDP to ensure downloads are synced to Browserbase’s storage. Pay special attention to the downloadPath parameter—it must be set to "downloads" exactly as shown in the examples above.Common misconfiguration issues:
  • Using an absolute path (e.g., /tmp/downloads) instead of "downloads"
  • Omitting the setDownloadBehavior call entirely
  • Setting behavior to something other than "allow"
Without proper configuration, your downloads won’t be available for retrieval.
Opening a PDF URL in a browser session also triggers a download to Browserbase’s cloud storage. To view the PDF instead of downloading it, configure your browser settings as shown here.

Retrieving downloaded files

After triggering downloads, retrieve them using the Downloads API. The API provides granular access to individual downloaded files — you can list, filter, retrieve, and delete downloads. Filenames don’t include the timestamp suffix Browserbase adds during storage.
Files sync in real time — large downloads may not be immediately available through the /downloads endpoint. The code below includes retry logic to handle this.

List downloads

List all downloads for a session with optional filtering by filename, MIME type, file size, and creation time.
Node
import { writeFileSync } from "node:fs";

const API_KEY = process.env.BROWSERBASE_API_KEY!;

async function saveDownloadsOnDisk(sessionId: string, retryForSeconds: number) {
  const endTime = Date.now() + retryForSeconds * 1000;

  while (Date.now() < endTime) {
    try {
      // List individual downloads for the session
      const listResponse = await fetch(
        `https://api.browserbase.com/v1/downloads?sessionId=${sessionId}`,
        { headers: { "x-bb-api-key": API_KEY } }
      );
      const { downloads, total } = await listResponse.json();

      if (total > 0) {
        console.log(`Found ${total} download(s)`);

        for (const download of downloads) {
          // Download each file individually
          const fileResponse = await fetch(
            `https://api.browserbase.com/v1/downloads/${download.id}`,
            {
              headers: {
                "x-bb-api-key": API_KEY,
                Accept: "application/octet-stream",
              },
            }
          );
          const buffer = Buffer.from(await fileResponse.arrayBuffer());
          writeFileSync(download.filename, buffer);
          console.log(`Saved: ${download.filename} (${download.size} bytes)`);
        }
        return;
      }
    } catch (e) {
      console.error("Error fetching downloads:", e);
      throw e;
    }

    // Wait 2 seconds before retrying
    await new Promise((resolve) => setTimeout(resolve, 2000));
  }

  throw new Error("No downloads found within the retry period");
}

(async () => {
  // Use the session ID from your browser automation to retrieve downloads
  const sessionId = "your-session-id";
  await saveDownloadsOnDisk(sessionId, 20); // wait up to 20s
  console.log("Downloads complete");
})().catch((error) => {
  console.error("Download failed:", error);
});

Filtering options

ParameterTypeDescription
sessionIdstringRequired. The session ID to list downloads for.
filenamestringFilter by exact filename match.
mimeTypestringFilter by MIME type (e.g., application/pdf).
minSizenumberMinimum file size in bytes.
maxSizenumberMaximum file size in bytes.
createdAfterstringFilter downloads created after this timestamp (ISO 8601).
createdBeforestringFilter downloads created before this timestamp (ISO 8601).
limitnumberMaximum results to return (1-100, default: 20).
offsetnumberNumber of results to skip for pagination.
Example with filters:
Node
const API_KEY = process.env.BROWSERBASE_API_KEY!;
const sessionId = "your-session-id";

// Find PDF files larger than 1KB created in the last hour
const params = new URLSearchParams({
  sessionId,
  mimeType: "application/pdf",
  minSize: "1024",
  createdAfter: new Date(Date.now() - 60 * 60 * 1000).toISOString(),
  limit: "10",
});

const response = await fetch(
  `https://api.browserbase.com/v1/downloads?${params}`,
  {
    headers: { "x-bb-api-key": API_KEY },
  }
);

const { downloads } = await response.json();
console.log(`Found ${downloads.length} matching PDFs`);

Get a download

Retrieve metadata or file content for a specific download. Use Accept: application/json for metadata, or Accept: application/octet-stream to download the file (default if no Accept header is provided).
Node
import { writeFileSync } from "node:fs";

const API_KEY = process.env.BROWSERBASE_API_KEY!;
const downloadId = "download-uuid";

// Get metadata
const metadataResponse = await fetch(
  `https://api.browserbase.com/v1/downloads/${downloadId}`,
  {
    headers: {
      "x-bb-api-key": API_KEY,
      Accept: "application/json",
    },
  }
);
const metadata = await metadataResponse.json();
console.log(`File: ${metadata.filename} (${metadata.size} bytes)`);

// Download file content
const fileResponse = await fetch(
  `https://api.browserbase.com/v1/downloads/${downloadId}`,
  {
    headers: {
      "x-bb-api-key": API_KEY,
      Accept: "application/octet-stream",
    },
  }
);
const buffer = Buffer.from(await fileResponse.arrayBuffer());
writeFileSync(metadata.filename, buffer);

Delete a download

Remove a download from storage. Returns 204 No Content on success.
Node
const API_KEY = process.env.BROWSERBASE_API_KEY!;
const downloadId = "download-uuid";

const response = await fetch(
  `https://api.browserbase.com/v1/downloads/${downloadId}`,
  {
    method: "DELETE",
    headers: { "x-bb-api-key": API_KEY },
  }
);

if (response.status === 204) {
  console.log("Download deleted");
}

Download object

Each download contains the following fields:
FieldTypeDescription
idstringUnique identifier for the download.
sessionIdstringThe session ID this download belongs to.
filenamestringThe filename of the downloaded file.
mimeTypestringThe MIME type of the file.
sizenumberFile size in bytes.
checksumstringSHA256 checksum of the file.
createdAtstringTimestamp when the file was downloaded (ISO 8601).

List downloads

List and filter downloads

Get download

Get metadata or file content

Delete download

Remove a download