/download API
The /download API runs your Puppeteer code in a browser and returns files Chrome downloaded, with appropriate Content-Type and Content-Disposition headers. You can load external libraries via import and use ESM modules that run inside the browser context. If your download request doesn't result in a file being downloaded, Browserless will time out the function.
You can check the full Open API schema here.
Quick Start
- cURL
- Javascript
- Python
- Java
- C#
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));
};'
import { writeFile } from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/download?token=${TOKEN}`;
const headers = {
"Content-Type": "application/javascript"
};
const data = `
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));
};
`;
const downloadFile = async () => {
try {
console.log("Testing JavaScript download functionality...");
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: data
});
console.log("Response status:", response.status);
console.log("Response headers:", Object.fromEntries(response.headers.entries()));
if (response.ok) {
const buffer = await response.arrayBuffer();
await writeFile("data.json", Buffer.from(buffer));
console.log("File saved as data.json");
const content = Buffer.from(buffer).toString('utf-8');
console.log("Downloaded content:", content);
} else {
console.error("Request failed:", response.status, response.statusText);
const errorText = await response.text();
console.error("Error details:", errorText);
}
} catch (error) {
console.error("Error:", error.message);
}
};
downloadFile();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/download?token={TOKEN}"
headers = {
"Content-Type": "application/javascript"
}
data = """
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));
};
"""
def test_download():
try:
print("Testing Python download functionality...")
print(f"URL: {url}")
print(f"Headers: {headers}")
response = requests.post(url, headers=headers, data=data)
print(f"Response status: {response.status_code}")
print(f"Response headers: {dict(response.headers)}")
if response.ok:
with open("data.json", "wb") as file:
file.write(response.content)
print("File saved as data.json")
content = response.content.decode('utf-8')
print(f"Downloaded content: {content}")
else:
print(f"Request failed: {response.status_code} {response.reason}")
print(f"Error details: {response.text}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
test_download()
import java.io.*;
import java.net.*;
import java.net.http.*;
import java.time.Duration;
public class DownloadJsonFile {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/download?token=" + TOKEN;
String javascriptCode = """
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));
};
""";
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/javascript")
.timeout(Duration.ofSeconds(60))
.POST(HttpRequest.BodyPublishers.ofString(javascriptCode))
.build();
try {
System.out.println("Testing Java download functionality...");
System.out.println("URL: " + url);
System.out.println("Headers: Content-Type: application/javascript");
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response status: " + response.statusCode());
System.out.println("Response headers: " + response.headers().map());
if (response.statusCode() == 200) {
String content = response.body();
try (FileWriter writer = new FileWriter("data.json")) {
writer.write(content);
System.out.println("File saved as data.json");
}
System.out.println("Downloaded content: " + content);
} else {
System.out.println("Request failed: " + response.statusCode());
System.out.println("Error details: " + response.body());
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/download?token={TOKEN}";
string javascriptCode = @"
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));
};";
using var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
var content = new StringContent(javascriptCode, Encoding.UTF8, "application/javascript");
try
{
Console.WriteLine("Testing C# download functionality...");
Console.WriteLine($"URL: {url}");
Console.WriteLine("Headers: Content-Type: application/javascript");
var response = await client.PostAsync(url, content);
Console.WriteLine($"Response status: {(int)response.StatusCode}");
Console.WriteLine($"Response headers: {response.Headers}");
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
await File.WriteAllTextAsync("data.json", responseContent);
Console.WriteLine("File saved as data.json");
Console.WriteLine($"Downloaded content: {responseContent}");
}
else
{
Console.WriteLine($"Request failed: {(int)response.StatusCode} {response.ReasonPhrase}");
var errorContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Error details: {errorContent}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine($"Stack trace: {ex.StackTrace}");
}
}
}
Response
The API returns the downloaded file with appropriate headers:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Disposition: attachment; filename="data.json"
{"ping":"pong","rnd":[854246,114512,212580,482122,107878]}
Additional Examples and Configuration
Local Puppeteer Example (Reference)
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)
Importing 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
- Javascript
- Python
- Java
- C#
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);
}'
import { writeFile } from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/download?token=${TOKEN}`;
const headers = {
"Content-Type": "application/javascript"
};
const data = `
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);
link.click();
}, rndName, rndEmail);
};
`;
const downloadFile = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: data
});
const buffer = await response.arrayBuffer();
await writeFile("data.json", Buffer.from(buffer));
console.log("File saved as data.json");
};
downloadFile();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/download?token={TOKEN}"
headers = {
"Content-Type": "application/javascript"
}
data = """
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);
link.click();
}, rndName, rndEmail);
};
"""
response = requests.post(url, headers=headers, data=data)
with open("data.json", "wb") as file:
file.write(response.content)
print("File saved as data.json")
import java.io.*;
import java.net.*;
import java.net.http.*;
public class DownloadJsonFileWithFaker {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/download?token=" + TOKEN;
String javascriptCode = """
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);
link.click();
}, rndName, rndEmail);
};
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/javascript")
.POST(HttpRequest.BodyPublishers.ofString(javascriptCode))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (InputStream in = response.body();
FileOutputStream fileOut = new FileOutputStream("data.json")) {
in.transferTo(fileOut);
System.out.println("File saved as data.json");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/download?token={TOKEN}";
string javascriptCode = @"
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);
link.click();
}, rndName, rndEmail);
};";
using var client = new HttpClient();
var content = new StringContent(javascriptCode, Encoding.UTF8, "application/javascript");
try
{
var response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
using var fileStream = new FileStream("data.json", FileMode.Create, FileAccess.Write);
await stream.CopyToAsync(fileStream);
Console.WriteLine("File saved as data.json");
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
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 thecode
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
- Javascript
- Python
- Java
- C#
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
}
}''
import { writeFile } from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/download?token=${TOKEN}`;
const headers = {
'Content-Type': 'application/json'
};
// Minified code
const 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
}
};
const downloadFile = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const buffer = await response.arrayBuffer();
await writeFile("data.json", Buffer.from(buffer));
console.log("File saved as data.json");
};
downloadFile();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/download?token={TOKEN}"
headers = {
'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
}
}
response = requests.post(url, headers=headers, json=data)
with open("data.json", "wb") as file:
file.write(response.content)
print("File saved as data.json")
import java.io.*;
import java.net.http.*;
import java.net.URI;
public class DownloadJsonFileWithMinifiedCode {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/download?token=" + TOKEN;
String jsonData = """
{
"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
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (InputStream in = response.body();
FileOutputStream fileOut = new FileOutputStream("data.json")) {
in.transferTo(fileOut);
System.out.println("File saved as data.json");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program {
static async Task Main(string[] args) {
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/download?token={TOKEN}";
string jsonData = @"
{
""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
}
}
";
using var client = new HttpClient();
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
try {
var response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
using var fileStream = new FileStream("data.json", FileMode.Create, FileAccess.Write);
await stream.CopyToAsync(fileStream);
Console.WriteLine("File saved as data.json");
} catch (Exception ex) {
Console.WriteLine("Error: " + ex.Message);
}
}
}