Hyperbrowser makes it easy to download files during your browser sessions. The files you download get stored securely in our cloud infrastructure as a zip file. You can then retrieve them using a simple API call.
How to Download Files
- Create a new Hyperbrowser session and set the saveDownloadsparam totrue
- Connect to the session using your preferred automation framework (like Puppeteer or Playwright)
- Set the download location in your code
- Download files
- Retrieve the download zip URL from Sessions API
Retrieving Downloads in Sessions
import { chromium } from "playwright-core";
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});
async function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}
async function waitForDownload(sessionId, timeout = 15_000) {
  const maxRetries = timeout / 1000;
  let retries = 0;
  while (retries < maxRetries) {
    console.log(
      `Waiting for download zip to be ready... (${retries + 1}/${maxRetries})`
    );
    const downloadsResponse = await client.sessions.getDownloadsURL(sessionId);
    if (
      downloadsResponse.status === "completed" ||
      downloadsResponse.status === "failed"
    ) {
      return downloadsResponse;
    }
    await sleep(1000);
    retries++;
  }
  throw new Error(`Download zip not ready after ${timeout}ms`);
}
async function main() {
  const session = await client.sessions.create({
    saveDownloads: true,
  });
  console.log("Session created:", session.id);
  try {
    const browser = await chromium.connectOverCDP(session.wsEndpoint);
    const defaultContext = browser.contexts()[0];
    const page = defaultContext.pages()[0];
    const cdp = await browser.newBrowserCDPSession();
    await cdp.send("Browser.setDownloadBehavior", {
      behavior: "allow",
      downloadPath: "/tmp/downloads",
      eventsEnabled: true,
    });
    await page.goto("https://browser-tests-alpha.vercel.app/api/download-test");
    // Download file from the page
    const downloadPromise = page.waitForEvent("download");
    await page.getByRole("link", { name: "Download File" }).click();
    const download = await downloadPromise;
    // Wait for the download to complete
    await download.path();
    console.log("Downloaded file:", download.suggestedFilename());
    await client.sessions.stop(session.id);
    await sleep(3000);
    // Wait for the zipped downloads to be uploaded to our storage
    const downloadsResponse = await waitForDownload(session.id);
    console.log("downloadsResponse", downloadsResponse);
  } catch (err) {
    console.error(`Encountered error: ${err}`);
  } finally {
    await client.sessions.stop(session.id);
  }
}
main().catch(console.error);
The downloads zip is synced in real-time to files that are downloaded during the session so you can retrieve it before the session stops as well.
By default, most PDF urls opened in the browser will open in a PDF viewer in the browser rather being downloaded. To force all PDFs to be downloaded, enable the enableAlwaysOpenPdfExternally/enable_always_open_pdf_externally parameter when creating the session.
Retrieving Downloads with API
After your session completes and files are downloaded, you can retrieve them using the Downloads API:
- Get the session ID - Note the idof the session that downloaded files
- Call the API - Use the Get Session Downloads URL endpoint or SDK method getDownloadsURL()
- Poll for completion - Check the status until it’s completed
- Download the zip - Use the downloadsUrlto download your files
The API returns a response with the following structure:{
  status: "not_enabled" | "pending" | "in_progress" | "completed" | "failed"
  downloadsUrl: string | null
  error?: string | null
}
Status Values
| Status | Description | 
|---|
| not_enabled | The saveDownloadsparameter was not set totruewhen creating the session | 
| pending | Files are queued for processing or no files have been downloaded yet in the session | 
| in_progress | Zip file is being created and uploaded to storage | 
| completed | Download zip is ready - downloadsUrlcontains the download link | 
| failed | Processing failed - check errorfield for details | 
The download zip URL is temporary and will expire according to your plan’s data retention policy. Download the file promptly after retrieval.
Using With AI Agents
Similarly as above, you can get the downloads zip of files that were downloaded during the session used by an AI Agent. We just need to create a session with saveDownloads set to true and then pass in that session ID. Here is an example of doing it with OpenAI CUA.
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});
async function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}
async function waitForDownload(sessionId, timeout = 15_000) {
  const maxRetries = timeout / 1000;
  let retries = 0;
  while (retries < maxRetries) {
    console.log(
      `Waiting for download zip to be ready... (${retries + 1}/${maxRetries})`
    );
    const downloadsResponse = await client.sessions.getDownloadsURL(sessionId);
    if (
      downloadsResponse.status === "completed" ||
      downloadsResponse.status === "failed"
    ) {
      return downloadsResponse;
    }
    await sleep(1000);
    retries++;
  }
  throw new Error(`Download zip not ready after ${timeout}ms`);
}
async function main() {
  const session = await client.sessions.create({
    saveDownloads: true,
  });
  console.log("Session created:", session.id);
  try {
    const resp = await client.agents.cua.startAndWait({
      task: "1. Go to this site https://browser-tests-alpha.vercel.app/api/download-test. 2. Click on the Download File link once, then end the task. Do not wait or double check the download, just end the task.",
      sessionId: session.id,
    });
    console.log("Status:", resp.status);
    console.log("Final result:", resp.data?.finalResult);
    await sleep(3000);
    // Wait for the zipped downloads to be uploaded to our storage
    const downloadsResponse = await waitForDownload(session.id);
    console.log("downloadsResponse", downloadsResponse);
  } catch (err) {
    console.error(`Encountered error: ${err}`);
  } finally {
    await client.sessions.stop(session.id);
  }
}
main().catch(console.error);
Check out the Agents Docs for more information on how to use AI Agents with Hyperbrowser. Storage and Retention
Downloaded zip files are stored securely in Hyperbrowser’s cloud infrastructure and are retained according to your plan’s data retention policy.
Next Steps
Now that you’ve configured your sessions, start using them to automate tasks: