---
title: "Uploads"
description: "Upload local files into a browser session."
image: "https://help.agent.mq/og.svg"
---

> Documentation Index
> Fetch the complete documentation index at: https://help.agent.mq/llms.txt
> Use this file to discover all available pages before exploring further.

# Uploads

Upload files to websites using Playwright, Puppeteer, or Selenium. The approach varies by framework:

## Playwright

### Direct upload

With Playwright, upload files directly from your local path. After [creating and connecting to a session](/browsers/getting-started/using-browser-session), follow these steps:

1. Make sure your file is available where you're running your Playwright code
2. Use the `setInputFiles` method to upload the file
3. The file path should be relative to your current working directory

### Node.js

```typescript Playwright
import { chromium } from "playwright-core";
import { Browsers } from "@agentmq/browsers";

(async () => {
  const browsers = new Browsers({ apiKey: process.env.AGENTMQ_TOKEN! });
  const session = await browsers.sessions.create();

  const browser = await chromium.connectOverCDP(session.connectUrl);
  const defaultContext = browser.contexts()[0];
  const page = defaultContext.pages()[0];

  await page.goto("https://browser-tests-alpha.vercel.app/api/upload-test");

  const fileInput = page.locator("#fileUpload");
  // logo.png is available relative to the current working directory
  await fileInput.setInputFiles("logo.png");
})().catch((error) => console.error(error));
```

### Python

```Python Playwright
from playwright.sync_api import sync_playwright
from agentmq.browsers import Browsers
import os

browsers = Browsers(api_key=os.environ["AGENTMQ_TOKEN"])
session = browsers.sessions.create()

with sync_playwright() as playwright:
    browser = playwright.chromium.connect_over_cdp(session.connect_url)
    context = browser.contexts[0]
    page = context.pages[0]

    page.goto("https://browser-tests-alpha.vercel.app/api/upload-test")

    file_input = page.locator("#fileUpload")
    file_input.set_input_files("logo.png")
```

### Large file uploads

For larger files, use the [Session Uploads API](/browsers/api):

### Node.js

```typescript Playwright
  // IMPORTANT: Set your file name below
  const fileName = "YOUR_FILE_NAME.EXAMPLE";

  import { chromium } from "playwright-core";
  import { Browsers } from "@agentmq/browsers";
  import * as fs from "fs";

  const apiKey = process.env.AGENTMQ_TOKEN!;

  async function upload() {
    // 1. Initialize Browsers Client
    console.log("Initializing Browsers client");
    const browsers = new Browsers({ apiKey });

    // 2. Create Browser Session
    console.log("Creating new browser session");
    const session = await browsers.sessions.create();

    // 3. Upload file via the Uploads API
    console.log("Uploading file");
    try {
      const fileStream = fs.createReadStream(fileName);
      const result = await browsers.sessions.uploads.create(session.id, {
        file: fileStream,
      });
      console.log(`Upload successful: ${JSON.stringify(result)}`);
    } catch (error) {
      console.error(`Upload failed... exiting: ${error}`);
      return;
    }

    // 4. Connect to the Session
    console.log("Connecting to browser session");
    const browser = await chromium.connectOverCDP(session.connectUrl);
    const defaultContext = browser.contexts()[0];
    const page = defaultContext.pages()[0];

    // 5. Get Live View link for remote debugging
    const liveViews = await browsers.sessions.debug(session.id);
    console.log("Live View link:", liveViews.debuggerUrl);

    // 6. Use the Browser
    console.log("Navigating to page: upload-test");
    await page.goto("https://browser-tests-alpha.vercel.app/api/upload-test", {
      waitUntil: "domcontentloaded",
    });

    // Set up CDP client for additional controls
    const cdpSession = await defaultContext.newCDPSession(page);
    const root = await cdpSession.send("DOM.getDocument");

    // Find the input element
    const inputNode = await cdpSession.send("DOM.querySelector", {
      nodeId: root.root.nodeId,
      selector: "#fileUpload",
    });

    // Use DOM.setFileInputFiles CDP command
    const remoteFilePath = `/tmp/.uploads/${fileName}`;
    await cdpSession.send("DOM.setFileInputFiles", {
      files: [remoteFilePath],
      nodeId: inputNode.nodeId,
    });

    console.log("Waiting for 60 seconds: allow time for 1) file upload and 2) to see the file upload...");
    await new Promise((resolve) => setTimeout(resolve, 60000));

    // 7. Cleanup
    console.log("Closing browser session");
    await page.close();
    await browser.close();

    // 8. Session Replay Link
    console.log(`
  Your session console is ready:
    https://agent.mq/sessions/${session.id}`);
  }

  // Execute the main function
  upload().catch((error) => console.error(error));

```

### Python

```python Playwright
  # IMPORTANT: Set your file name below
  file_name = "YOUR_FILE_NAME.EXAMPLE"

  import os
  from agentmq.browsers import Browsers
  from playwright.sync_api import sync_playwright
  import time

  api_key = os.environ.get("AGENTMQ_TOKEN")

  def upload(playwright):
    # 1. Initialize Browsers Client
    print("Initializing Browsers client")
    browsers = Browsers(api_key=api_key)

    # 2. Create Browser Session
    print("Creating new browser session")
    session = browsers.sessions.create()

    # 3. Upload file via the Uploads API: https://help.agent.mq/reference/api/create-session-uploads
    print("Uploading file")
    try:
      with open(file_name, 'rb') as file:
        result = browsers.sessions.uploads.create(
          id=session.id,
          file=file
      )
        print(f"Upload successful: {result}")
    except Exception as e:
      print(f"Upload failed... exiting: {str(e)}")
      return

    # 4. Connect to the Session
    print("Connecting to browser session")
    browser = playwright.chromium.connect_over_cdp(session.connect_url)
    default_context = browser.contexts[0]
    page = default_context.pages[0]

    # 5. Get Live View link for remote debugging
    live_views = browsers.sessions.debug(session.id)
    print("Live View link:", live_views.debugger_url)

    # 6. Use the Browser
    print("Navigating to page: upload-test")
    page.goto("https://browser-tests-alpha.vercel.app/api/upload-test", wait_until="domcontentloaded")

    # Set up CDP client for additional controls
    cdp_session = default_context.new_cdp_session(page)

    root = cdp_session.send('DOM.getDocument')

    # Find the input element
    input_node = cdp_session.send('DOM.querySelector', {
      'nodeId': root['root']['nodeId'],
      'selector': '#fileUpload'
    })

    # Use DOM.setFileInputFiles CDP command with the found nodeId and set the remote file path
    remote_file_path = f"/tmp/.uploads/{file_name}";
    cdp_session.send('DOM.setFileInputFiles', {
      'files': [remote_file_path],
      'nodeId': input_node['nodeId']
    })

    print("Waiting for 60 seconds: allow time for 1) file upload and 2) to see the file upload...")
    time.sleep(60)

    # 7. Cleanup
    print("Closing browser session")
    page.close()
    browser.close()

    # 8. Session Replay Link
    print(f"""
  Your session console is ready:
    https://agent.mq/sessions/{session.id}""")

  # Execute the main function
  if __name__ == "__main__":
      with sync_playwright() as playwright:
          upload(playwright)
```

### Manual upload through Live View

When using [Live View](/browsers/observability/session-live-view), clicking a file input triggers the browser's native file picker. Since the browser runs remotely on Browsers infrastructure, it can't access files on your local machine.

To handle manual uploads through Live View, intercept file chooser events and upload programmatically:

1. Detect file input clicks using Playwright's `page.on('filechooser')` event
2. Show your own file picker (e.g., a native OS picker or web UI) to select a local file
3. Upload the file via the Session Uploads API
4. Attach the file to the input element using CDP's `DOM.setFileInputFiles`

See the following [example script](https://github.com/agentmq/playbook/blob/main/node/playwright/_tools/uploads/live-view-upload.ts) for a complete implementation.

- **Session uploads API** — [Learn more about the available params and response fields](/browsers/api)

Source: https://help.agent.mq/browsers/files/uploads/index.mdx
