Skip to main content

/download API

The /download API is used for returning files Chrome has downloaded during the execution of puppeteer code, which is ran inside context of the browser. Browserless sets up a blank page, a fresh download directory, injects your puppeteer code, and then executes it.

You can load external libraries via the import syntax, and import ESM-style modules that are written for execution inside of the browser. Once your script is finished, any downloaded files from Chromium are returned back with the appropriate content-type header.

You can check the full Open API schema here.

warning

If your download request doesn't result in a file being downloaded, Browserless will likely time out the function.

Example

Here's an example of downloading a file using local Puppeteer:

import puppeteer from "puppeteer";

async function run() {
const browser = await puppeteer.launch();
const page = await browser.newPage();

// Here we generate a json file and have the browser download it
await page.evaluate(() => {
const json = {
ping: "pong",
rnd: [...Array(5)].map(() => Math.random()),
};
const jsonContent = `data:application/json,${JSON.stringify(json)}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");

link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
return link.click();
});
await browser.close();
}

run();

Limitations of Local Puppeteer setup:

  • Downloads go to your local Downloads folder
  • No easy way to programmatically access downloaded files
  • Requires complex file system monitoring
  • High resource usage (runs full Chrome locally)

Approach using Browserless

Instead of monitoring the file system, send an HTTP request to Browserless to handle file downloads automatically. The code below does just that for you.

Core JavaScript Code

export default async function ({ page }) {  
await page.evaluate(() => {
const json = {
ping: "pong",
rnd: [...Array(5)].map(() => Math.random())
};
const jsonContent = `data:application/json,${JSON.stringify(json)}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
link.click();
});
// Add delay to ensure download completes
await new Promise(r => setTimeout(r, 1000));
}

Implementation Examples

curl -X POST \\  
https://production-sfo.browserless.io/download?token=YOUR_API_TOKEN_HERE \\
-H 'Content-Type: application/javascript' \\
-d 'export default async function ({ page }) {
await page.evaluate(() => {
const json = { ping: "pong", rnd: [...Array(5)].map(() => Math.random()) };
const jsonContent = `data:application/json,${JSON.stringify(json)}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
link.click();
});
await new Promise(r => setTimeout(r, 1000));
};'
note

This API is sensitive to the downloaded file and will return an appropriate Content-Type with the response.

Import libraries

Both the /function and /download API environments support ECMAScript modules, allowing you to use import syntax to load modules directly from HTTP URLs. For example, let's import the Faker.js library:

JS Code

import { faker } from "https://esm.sh/@faker-js/faker";

export default async function ({ page }) {
const rndName = faker.person.fullName();
const rndEmail = faker.internet.email();

await page.evaluate(
(name, email) => {
const jsonStr = JSON.stringify({ name, email });
const jsonContent = `data:application/json,${jsonStr}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");

link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
return link.click();
},
rndName,
rndEmail
);
}
curl -X POST \
https://production-sfo.browserless.io/download?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/javascript' \
-d 'import { faker } from '\''https://esm.sh/@faker-js/faker'\'';

export default async function ({ page }) {
const rndName = faker.person.fullName();
const rndEmail = faker.internet.email();

await page.evaluate((name, email) => {
const jsonStr = JSON.stringify({name, email});
const jsonContent = `data:application/json,${jsonStr}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");

link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
return link.click();
}, rndName, rndEmail);
}'

Example response

{
"name": "Jasmine Littel",
"email": "Giovanna26@hotmail.com"
}

JSON API

You can also use the /download API sending a JSON payload. You must send an object with the following values:

  • code: String, required — custom download code.
  • context: Object, optional — value used to pass context values and arguments to the code

Example

JS Code

export default async function ({ page, context }) {
await page.evaluate((context) => {
const json = {
url: context.url,
ping: "pong",
rnd: [...Array(context.arrayLen)].map(() => Math.random()),
};
const jsonContent = `data:application/json,${JSON.stringify(json)}`;
const encodedUri = encodeURI(jsonContent);
const link = document.createElement("a");

link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.json");
document.body.appendChild(link);
return link.click();
}, context);
}
curl --request POST \
--url 'https://production-sfo.browserless.io/download?token=YOUR_API_TOKEN_HERE' \
--header 'Content-Type: application/json' \
# Minified code
--data '{
"code": "export default async function({page:t,context:a}){await t.evaluate(t=>{let a={url:t.url,ping:`pong`,rnd:[...Array(t.arrayLen)].map(()=>Math.random())},e=`data:application/json,${JSON.stringify(a)}`,n=encodeURI(e),r=document.createElement(`a`);return r.setAttribute(`href`,n),r.setAttribute(`download`,`data.json`),document.body.appendChild(r),r.click()},a)};",
"context": {
"url": "https://browserless.io/",
"arrayLen": 10
}
}''