Overview

How to upload, download, manage and work with files within an active session

Files API Overview

Steel provides two complementary file management systems: Session Files for working with files within active browser sessions, and Global Files for persistent file storage across your organization.

Overview

Steel's file management system makes it easy to work with files in your automated workflows:

  • Session-Based File Operations: Upload files to active sessions for immediate use in browser automations, download files acquired during browsing

  • Persistent File Storage: Maintain a global file repository for reuse across multiple sessions and workflows

  • Workspace Management: Organize and access files generated across different automation runs

  • Data Pipeline Integration: Upload datasets once and reference them across multiple automation sessions

  • File Archival: Automatically preserve files from completed sessions for later access

How It Works

Session Files System

Files uploaded to active sessions become available within that session's isolated VM environment. These files can be used immediately with web applications and browser automation tools. When files are downloaded from the internet during a session, they become accessible through the same API. Session files persist beyond session lifecycle - files are automatically backed up when sessions end.

Global Files System

The Global Files API provides persistent, organization-wide file storage independent of browser sessions. Files uploaded to global storage can be referenced and mounted in any session. All session files are automatically promoted to global storage when sessions are released, creating a comprehensive file workspace.

Session Files API

This section outlines how to interact with the filesystem inside of the VM that your session is running from. All of these files are accessible from the browser.

Upload Files to Session File System

1
// Upload file to session environment
2
const file = fs.createReadStream("./steel.png");
3
const session = await client.sessions.create();
4
const uploadedFile = await client.sessions.files.upload(session.id, {
5
file: file, // or path in global files api or absolute url
6
});

List Files in a Session File System

1
const files = await client.session.files.list(sessionId);
2
files.forEach(file => {
3
console.log(`${file.path} | Size: ${file.size} | Last Modified: ${file.lastModified}`);
4
});

Download Files from Session File System

1
// Download a specific file from a session
2
const response = await client.sessions.files.download(sessionId, "path/to/file");
3
const fileBlob = await response.blob();
4
5
// Download all files as zip archive
6
const archiveResponse = await client.sessions.files.downloadArchive(sessionId);

Delete Files from Sessions File System

1
// Delete a specific file from a session
2
const response = await client.sessions.files.delete(sessionId, "path/to/file");
3
4
// Delete all files in a session
5
const archiveResponse = await client.sessions.files.deleteAll(session.id);

Global Files API

Upload File to Global Storage

1
const file = fs.createReadStream("./dataset.csv");
2
const globalFile = await client.files.upload({
3
file,
4
// path: "dataset.csv" // optional
5
});
6
console.log(globalFile.path); // dataset.csv
7
8
// Using the file from Global Files API in a session
9
const session = await client.sessions.create();
10
const uploadedFile = await client.sessions.files.upload(session.id, {
11
file: globalFile.path
12
});

List All Files

1
const files = await client.files.list();
2
files.forEach(file => {
3
console.log(`${file.path} | Size: ${file.size} | Last Modified: ${file.lastModified}`);
4
});

Download Global File

1
const response = await client.files.download(file.path); // dataset.csv
2
const fileBlob = await response.blob();

Delete Global File

1
await client.files.delete(file.path);

Usage in Context

Set File Input Values

Reference uploaded files in file input elements using CDP (Chrome DevTools Protocol).

Typescript
main.ts
1
// Create CDP session for advanced controls
2
const cdpSession = await currentContext.newCDPSession(page);
3
const document = await cdpSession.send("DOM.getDocument");
4
5
// Find the input element
6
const inputNode = await cdpSession.send("DOM.querySelector", {
7
nodeId: document.root.nodeId,
8
selector: "#file-input"
9
});
10
11
// Set the uploaded file as input
12
await cdpSession.send("DOM.setFileInputFiles", {
13
files: [uploadedSessionFile.path],
14
nodeId: inputNode.nodeId,
15
});
16

Standard Playwright/Puppeteer Upload

Typescript
main.ts
1
// For simple/smaller file uploads,
2
// using standard automation library methods will look at local files
3
await page.setInputFiles("#file-input", [uploadedSessionFile.path]);

Browser-Use Example

Browser-use needs some setup before it can be used. This includes setting up the browser profile with the correct downloads path and adding in a step hook to extract downloaded files to your local machine if necessary.

Python
main.py
1
# Before agent main loop...
2
3
# Hook to extract downloaded files to local machine if necessary
4
async def step_hook_start(agent):
5
if os.environ.get("BROWSER_PROVIDER") == "steel":
6
await agent._check_and_update_downloads()
7
if agent.available_file_paths and len(agent.available_file_paths) > 0:
8
has_new_files = False
9
for file_path in agent.available_file_paths:
10
if file_path not in downloaded_files:
11
downloaded_files.append(file_path)
12
has_new_files = True
13
if has_new_files:
14
try:
15
extracted_files = await browser_service.extract_downloaded_files(DOWNLOAD_PATH)
16
logger.info(f"Extracted files: {extracted_files}")
17
except Exception as e:
18
logger.error(f"Failed to extract downloaded files: {e}")
19
20
async def main():
21
try:
22
browser_session = Browser(cdp_url=cdp_url, downloads_path="/files")
23
await browser_session.connect()
24
await browser_session.cdp_client.send.Target.createBrowserContext()
25
browser_context_ids_return = await browser_session.cdp_client.send.Target.getBrowserContexts()
26
browser_context_ids = browser_context_ids_return['browserContextIds']
27
browser_context_id = browser_context_ids[0]
28
await browser_session.cdp_client.send.Browser.setDownloadBehavior(params={"behavior": "allow", "downloadPath": "/files", "eventsEnabled": True, "browserContextId": browser_context_id})
29
agent = Agent(task=TASK, llm=model, browser_session=browser_session)
30
agent.browser_session.browser_profile.downloads_path = LOCAL_DOWNLOAD_PATH
31
agent_results = await agent.run(
32
on_step_start=step_hook_start,
33
max_steps=5
34
)
35
except Exception as e:
36
print(f"Error: {e}")
37
finally:
38
# Clean up resources
39
if session:
40
client.sessions.release(session.id)
41
print("Session released")
42
print("Done!")
43
# Rest of code...

Complete Example

End-to-end workflow demonstrating global file management and session file operations.

Typescript
main.ts
1
import dotenv from "dotenv";
2
import fs from "fs";
3
import { chromium } from "playwright";
4
import Steel from "steel-sdk";
5
6
dotenv.config();
7
8
const client = new Steel({
9
steelAPIKey: process.env.STEEL_API_KEY,
10
});
11
12
async function main() {
13
let session;
14
let browser;
15
16
try {
17
// Upload dataset to global storage for reuse
18
const datasetFile = new File(
19
[fs.readFileSync("./data/stock-data.csv")],
20
"stock-data.csv",
21
{ type: "text/csv" }
22
);
23
24
const globalFile = await client.files.upload({ file: datasetFile });
25
console.log(`Dataset uploaded to global storage: ${globalFile.id}`);
26
27
// Create session and mount global file
28
session = await client.sessions.create();
29
console.log(`Session created: ${session.sessionViewerUrl}`);
30
31
const sessionFile = await client.sessions.files.upload(session.id, {
32
file: globalFile.path
33
});
34
35
// Connect browser and use the file
36
browser = await chromium.connectOverCDP(
37
`wss://connect.steel.dev?apiKey=${process.env.STEEL_API_KEY}&sessionId=${session.id}`
38
);
39
40
const currentContext = browser.contexts()[0];
41
const page = currentContext.pages()[0];
42
43
// Navigate to data visualization tool
44
await page.goto("<https://www.csvplot.com/>");
45
46
// Upload file to web application using CDP
47
const cdpSession = await currentContext.newCDPSession(page);
48
const document = await cdpSession.send("DOM.getDocument");
49
const inputNode = await cdpSession.send("DOM.querySelector", {
50
nodeId: document.root.nodeId,
51
selector: "#load-file",
52
});
53
54
await cdpSession.send("DOM.setFileInputFiles", {
55
files: [sessionFile.path],
56
nodeId: inputNode.nodeId,
57
});
58
59
// Wait for visualization and capture
60
await page.waitForSelector("svg.main-svg");
61
62
// Download all session files (original upload + any generated files)
63
const archiveResponse = await client.sessions.files.download.archive(session.id);
64
const zipBlob = await archiveResponse.blob();
65
66
// Files are automatically available in global storage after session ends
67
68
} catch (error) {
69
console.error("Error:", error);
70
} finally {
71
if (browser) await browser.close();
72
if (session) await client.sessions.release(session.id);
73
74
// List all available files in global storage
75
const allFiles = await client.files.list();
76
console.log(`Total files in storage: ${allFiles.length}`);
77
}
78
}
79
80
main();
Need help building with the Files API?

Reach out to us on the #help channel on Discord under the ⭐ community section.