Downloading and Uploading Files

How to download and upload files with Airtop

Downloading Files

Airtop allows your agents to download files from the web. This is useful for a variety of use cases such as downloading a PDF to analyze, or downloading an image to use in a design.

First, you’ll need to perform an action that will trigger a download. For example, you can use the Click action to click on a button that will trigger a download. Then, you can request that the file being downloaded be written to the local file system.

1// Click on the button that will trigger a download
2await client.windows.click(session.data.id, window.data.windowId, {
3 elementDescription: "The button with the text 'Download PDF'",
4});
5
6// Download the next file in the queue
7await client.sessions.downloadNextFile(session.data.id, "./test.pdf");

You can also specify a callback to get progress updates on the download.

1await client.sessions.downloadNextFile(session.data.id, "./test.pdf", (downloaded, total) => {
2 console.log(`Downloaded: ${downloaded} / ${total} bytes`);
3});

Lookback

By default, downloadNextFile waits for a file to be downloaded, or looks back in time for the previous 5 seconds to see if a file download was triggered. This can be useful if the click interaction was very fast and triggered a download before the downloadNextFile call was made. However, you can configure the lookback period to be as long or short as you want, including 0 to disable lookback.

1 await client.sessions.downloadNextFile(session.data.id, "./test.csv", {
2 lookbackSeconds: 0,
3 });

There are other options to further control the download process if you are downloading multiple files, or want to initiate the download process yourself at a later time.

Finer grained control of the download

Most of the time, you can use the downloadNextFile method to download the next file in the queue. However, if you need more control over the download, you can use other methods.

waitForDownload returns metadata about the file that allows you to manually download the file. The response includes a downloadUrl which is a 1 hour, signed URL that can be used to download the file from any HTTP client.

1 await client.windows.click(session.data.id, window.data.windowId, {
2 elementDescription: "The button with the text 'Download PDF' inside the 'Different MIME types' section",
3 });
4
5 const file = await client.sessions.waitForDownload(session.data.id);
6 const response = await fetch(file.downloadUrl);
7 ...

Alternatively, you can always list the files that have been downloaded so far for a single session.

1const files = await client.files.list({
2 sessionIds: [session.data.id],
3});

This can be useful if you need to download multiple files from the same session in succession and later want to retrieve them.

1for (const file of files.data.files ?? []) {
2 await client.files.download(file.id, `./${file.fileName}`);
3}

Uploading Files

Airtop allows your agents to upload files to the web, which is useful in a lot of use cases like uploading a CSV or PDF file to submit to a site.

Given a file on your local system you can upload and set the file input in one action.

1const filePath = '/path/to/file.pdf';
2const inputResponse = await client.windows.uploadFileAndSelectInput(sessionId, windowId, {
3 uploadFilePath: filePath,
4});
5if (inputResponse.errors && fileInputResponse.errors.length > 0) {
6 console.log("file input errors", inputResponse.errors);
7}

uploadFileAndSelectInput uploads the file to Airtop, gets it ready on the session, and then fills out the described file input.

Check the errors property on the result to verify that the file input was found and filled out.

Once the file input is set, you can use other actions like click (example shown above) to submit the form or otherwise continue the process.

Finer grained control of the upload process

If you need more control of the process, you can use these steps like these:

1//upload the file to Airtop
2const uploadResponse = await client.windows.upload('/local/file/path/name');
3const fileId = uploadResponse.data.id;
4
5//push the file to a specific browser session
6await client.files.push(fileId, { sessionIds: [sessionId] });
7
8//wait for the transfer to the session to complete
9await client.sessions.waitForUploadAvailable(sessionId, fileId);
10
11//fill out the file input and prompt the AI to find the right file input
12const inputResponse = await client.windows.fileInput(sessionId, windowId, {
13 elementDescription: "file input 'Choose File' in the 'submit documentation' section at the bottom of the page",
14 fileId,
15});

Hidden file inputs

Many pages hide the file input for styling or other reasons and activate it with other user interactions. By default, Airtop looks at all the inputs on a page, including hidden ones. In some cases it may be useful to ignore hidden file inputs and you can can do that with the includeHiddenElements property. includeHiddenElements defaults to true.

const inputResponse = await client.windows.uploadFileAndSelectInput(sessionId, windowId, {
elementDescription: "the input with the id documentationInput",
uploadFilePath: filePath,
includeHiddenElements: false
});

Multiple file inputs

When there is a single file input on a page, Airtop uses that input automatically, whether it is visible or hidden.

When there are multiple inputs on a page Airtop uses the elementDescription to decide which file input to use. For visible inputs, the AI can decide based on visual clues like “in the documentation section”. For hidden inputs, AI uses the input element’s HTML to decide which one to fill out. When building automations for more complex pages, you might need to manually inspect the HTML to find the correct element’s id. You can also use the position of the input like “the second input” or you can use information from the input’s html like “the input with the id ‘documentationInput’”.

const inputResponse = await client.windows.uploadFileAndSelectInput(sessionId, windowId, {
elementDescription: "the input with the id documentationInput",
uploadFilePath: filePath
});