File uploads
Upload files once, let a run use them, and the agent attaches the right one to each upload field.
Forms often ask for a file: a resume, an ID scan, an invoice. Upload your files to Lovely Router once. When a run may use them, the agent attaches the file that fits each upload field, your CV for a "Resume" field and not your cover letter, even when both are PDFs.
Upload a file#
Send the raw bytes to PUT /v1/browser/files/{name}, with the file's type as Content-Type. An optional description query parameter helps the agent choose.
curl -X PUT "https://lovelyrouter.com/v1/browser/files/Maria_Garcia_CV_2026.pdf?description=Resume%2C%20updated%202026" \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/pdf" \
--data-binary @Maria_Garcia_CV_2026.pdfOr send a multipart form to POST /v1/browser/files, with the file in a file field. name (defaults to the uploaded file's name) and description are optional fields:
curl https://lovelyrouter.com/v1/browser/files \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-F "file=@Maria_Garcia_CV_2026.pdf;type=application/pdf" \
-F "description=Resume, updated 2026"Both return the stored file:
{
"id": "file_7a3c9e1b5d2f8a4c6e0b",
"name": "Maria_Garcia_CV_2026.pdf",
"mime": "application/pdf",
"bytes": 84213,
"sha256": "5f2b8c…",
"description": "Resume, updated 2026",
"created_at": "2026-10-11T09:20:44.000Z",
"last_used_at": null
}Without a Content-Type, the file is stored as application/octet-stream; send the real type so the agent and the website see it. Uploading again under the same name replaces the file and keeps its id. Files are encrypted at rest, like vault secrets. The Python and Node.js samples use the API, H and headers setup from Run your first task.
| Limit | Value |
|---|---|
| File size | 10 MB |
| Files per account | 100 |
| Name | 1 to 128 characters: letters, digits, spaces and . _ - ( ) + ,, starting with a letter, digit or _ |
| Description | 300 characters (longer text is cut) |
Let a run use your files#
Pass files when you start a run: a list of file names or ids, or "*" for all your files.
curl https://lovelyrouter.com/v1/browser/runs \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{
"goal": "Apply for the Backend Engineer role as Maria Garcia (maria.garcia@example.com), based in Portland, Oregon. Attach her resume. Submit the application and tell me the application ID.",
"start_url": "https://jobs.example.com/backend-engineer/apply",
"files": ["Maria_Garcia_CV_2026.pdf", "Maria_Garcia_Cover_Letter.pdf"],
"max_steps": 40
}'The agent can attach files only in runs that pass files, and only the files listed. An unknown name returns 400 with Unknown file(s): CV.pdf. Upload with PUT /v1/browser/files/{name}.
In the trace, an upload step's action starts with upload: and its description names the field. If the run pauses for your approval before submitting, needs.fields shows which file is attached, for example Resume: file "Maria_Garcia_CV_2026.pdf".
How the agent picks a file#
At each upload field, the agent compares your files with what the field asks for. It looks at:
- each file's name, type, size and description
- the field's label and the file types it accepts
- your goal and the page around the field
It matches the document's purpose, not only its type. To help it:
- Use descriptive names.
Maria_Garcia_CV_2026.pdfbeatsscan_0412.pdf. - Add a description when the name can't say it all: "Resume, updated 2026", "Passport photo page".
- Say in the goal which file to use when it matters: "Attach her resume (not the cover letter)".
- Pass only the files the run needs rather than
"*"when you have many similar files.
List and delete files#
# List your files, sorted by name
curl https://lovelyrouter.com/v1/browser/files -H "Authorization: Bearer $LOVELY_API_KEY"
# Delete by name or id
curl -X DELETE "https://lovelyrouter.com/v1/browser/files/Maria_Garcia_CV_2026.pdf" -H "Authorization: Bearer $LOVELY_API_KEY"The list returns {"object": "list", "data": [...]} with one file object per file. last_used_at shows when a run last attached it. Deleting returns {"deleted": "<name or id>"}, or 404 with No such file. You can also upload and delete files in the console under Secrets & files.
Errors#
| Status | Message | Cause |
|---|---|---|
400 | File names are 1-128 chars: letters, digits, space . _ - ( ) + , | The name has other characters or is too long. |
400 | Empty file | The body has no bytes. |
400 | Send multipart/form-data with a "file" field (and optional "description", "name") | The multipart form has no file field. |
409 | file limit reached (100); delete some first | You already have 100 files. Replacing an existing name still works. |
413 | Files are limited to 10 MB | The file is larger than 10 MB. |