Export API
Fetch a URL and stream the result with its detected content type (HTML, PDF, image, etc.). PDFs are re-printed by the browser rather than returned byte-for-byte. While its capabilities may overlap with the /download API, the /export API is best suited for downloading files from a URL when you don't know the content type ahead of time. It automatically detects the file type and returns the appropriate response. It can also bundle all resources from a page (HTML, CSS, JavaScript, images, etc.) into a single ZIP file for convenient offline use.
Endpoint
- Method:
POST - Path:
/export - Auth:
tokenquery parameter (?token=) - Content-Type:
application/json - Response:
*/*(based on upstream content)
See the OpenAPI reference for complete details.
- A Browserless API token from your account dashboard
Quickstart
- cURL
- Javascript
- Python
curl -X POST "https://production-sfo.browserless.io/export?token=YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf","gotoOptions":{"waitUntil":["networkidle0"]}}' \
-o output.pdf
import { writeFile } from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/export?token=${TOKEN}`;
const headers = {
'Content-Type': 'application/json'
};
const data = {
url: "https://example.com/"
};
const exportPage = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('text/html')) {
const content = await response.text();
await writeFile('page.html', content);
console.log('Content saved as page.html');
} else {
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
await writeFile('page.html', buffer);
console.log('Content saved as page.html');
}
};
exportPage();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/export?token={TOKEN}"
headers = {
'Content-Type': 'application/json'
}
data = {
"url": "https://example.com/"
}
response = requests.post(url, headers=headers, json=data)
with open("page.html", "wb") as file:
file.write(response.content)
print("Content saved as page.html")
Response
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="output.pdf"
<binary>
For PDFs, images, or other binary content, the API returns the appropriate content type (e.g., application/pdf, image/jpeg) with a Content-Disposition: attachment header. Images and other files come back in their native format. PDFs are the exception: the browser opens the PDF and prints it to a new PDF, so the file you get back isn't byte-for-byte the original (see the FAQ). For HTML pages, you'll receive the HTML content with Content-Type: text/html.
Handling Different Content Types
The /export API automatically detects the content type and sets it on the response. Here's how to handle different response types in your code:
HTML Content
const response = await fetch(url, options);
if (response.headers.get('content-type')?.includes('text/html')) {
const htmlContent = await response.text();
// Process HTML content
}
PDF Content
const response = await fetch(url, options);
if (response.headers.get('content-type')?.includes('application/pdf')) {
const arrayBuffer = await response.arrayBuffer();
const pdfBuffer = Buffer.from(arrayBuffer);
// Save or process PDF buffer
}
Binary Content (Images, etc.)
const response = await fetch(url, options);
const contentType = response.headers.get('content-type');
if (contentType?.includes('image/') || !contentType?.includes('text/')) {
const arrayBuffer = await response.arrayBuffer();
const binaryBuffer = Buffer.from(arrayBuffer);
// Save or process binary buffer
}
Export with All Resources (Zip File)
When includeResources is set to true, the API returns a zip file containing the HTML and all linked resources (images, CSS, JavaScript):
curl -s -X POST "https://production-sfo.browserless.io/export?token=YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{"url":"https://quotes.toscrape.com/","includeResources":true}' \
-o rest-api-export-quotes.zip
Response
The API returns a zip file with Content-Type: application/zip and Content-Disposition: attachment header:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="rest-api-export-quotes.zip"
[Binary zip file content containing HTML and all resources]
Configuration options
The /export API supports shared request configuration options that apply across REST endpoints:
- Waiting for things: Wait for events, functions, selectors, or timeouts before exporting
- Navigation options: Customize navigation behavior with
gotoOptions - Continue on error: Use
bestAttemptto continue when async events fail or time out
FAQ & Troubleshooting
Why am I getting a 401 Unauthorized error?
Your API token is missing or invalid. Include it as a ?token= query parameter or in the Authorization header. Verify the token in your account dashboard.
My request returns an empty response
The page may not have finished loading. Increase waitForTimeout or use waitForSelector to wait for specific content before extracting data.
I get a 200 for a PDF URL, but the file isn't the original PDF
/export re-prints PDFs from the browser instead of passing through the original bytes, so the output can differ from the source file. If the PDF is publicly reachable, download it with a plain HTTP request instead. If you need the browser to get to it (cookies, a login, or a bot check first), open the page with BaaS and save the file with file downloads.