← TemplatesPlaywright template

Form submission with file upload

Fill a portal form, attach a file, and submit it from a cloud Playwright session — the pattern behind most back-office automation.

PlaywrightFormsAutomation

Use this when a workflow ends at a web form that has no API: claims portals, supplier onboarding, government filings, support consoles. The session runs in the cloud with a coherent browser identity, and your existing Playwright knowledge transfers unchanged.

Executable starters

submit-form.ts
import { chromium } from 'playwright';const apiKey = process.env.BROWSERCITY_API_KEY;if (!apiKey) {  throw new Error('Set BROWSERCITY_API_KEY before running this script.');}const { endpoint, token, id } = await fetch('https://api.browser.city/v1/sessions', {  method: 'POST',  headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },  body: JSON.stringify({ browser: 'chromium' }),}).then((r) => r.json());try {  const browser = await chromium.connect(endpoint, {    headers: { Authorization: `Bearer ${token}` },  });  const page = browser.contexts().at(0)!.pages().at(0)!;  await page.goto('https://example.com/portal/submit');  await page.fill('#applicant-name', 'Ada Lovelace');  await page.fill('#reference', 'CASE-2026-0713');  await page.setInputFiles('#attachment', './report.pdf');  await page.click('button[type="submit"]');  await page.waitForSelector('.confirmation');  console.log(await page.textContent('.confirmation'));} finally {  await fetch(`https://api.browser.city/v1/sessions/${id}`, {    method: 'DELETE',    headers: { Authorization: `Bearer ${apiKey}` },  });}

Humanized REST upload alternative

When an HTTP-first workflow already uses /v1/do/*, open the file chooser with browser_click, then call POST /v1/do/file_upload. The public contract accepts caller-provided bytes or public HTTP(S) URLs; it never accepts a path on BrowserCity’s service filesystem.

{
  "sessionId": "<session id>",
  "files": [
    {
      "filename": "report.pdf",
      "mediaType": "application/pdf",
      "source": { "type": "base64", "data": "<base64 bytes>" }
    },
    {
      "filename": "terms.txt",
      "source": { "type": "url", "url": "https://files.example/terms.txt" }
    }
  ]
}

One request may contain 1–10 files, up to 8 MiB each and 20 MiB combined. BrowserCity validates and pins every public-URL redirect hop, stages private temporary files only for the transfer, and removes them afterward. The response reports safe filename, media type, and byte-count metadata without returning temporary paths.

Production hardening checklist

  • Wait for an explicit confirmation element before treating the submission as done.
  • Capture the confirmation text or reference number as your audit record.
  • Make the job idempotent: check whether the record already exists before resubmitting after a retry.
  • Keep credentials and uploaded files out of logs; only persist the outcome.

Cost and plan notes

A single form pass typically runs well under a minute of session time. For recurring workflows, multiply run frequency by observed session length in /pricing-calculator — traffic is usually negligible next to compute.

[ 08 / 08 ] — Get Started

Give your AI agents the web.

We're in private beta — request access and we'll get you set up. Private sessions by default.