Loop variables

The data available on each pass of a loop – file, folder and email records, rows of a spreadsheet or API result, and the loop's own timing values.

Help Centre › Building Processes

When a process loops, each pass makes the current item available as a variable so your steps can work with it. How you reach that data depends on what you're looping over. For how to build a loop, see Working with loops in RPAs; for variable syntax, see Working with variables in RPAs.

1. Looping over files

Each pass binds the current file to your loop variable (if you named it file, read its fields as {file::name}, {file::path}, and so on):

nameFile name (e.g. invoice.pdf)
pathFull file path
folderParent directory path
extensionFile suffix including the dot (e.g. .pdf)
dateModified date, YYYY-MM-DD
datetimeModified date and time, e.g. 2026-06-16 14h30
sizeSize in bytes
timestampModified time as epoch seconds
in useWhether the file is currently locked or open
password protectedWhether the file is encrypted

Two of these fields contain a space, so you must quote or bracket them to reach them: {file::"in use"} or {file["password protected"]}.

2. Looping over folders

Folder records carry: name, path, folder (parent), date, datetime and timestamp. (The file-only fields – extension, size, in use, password protected – are not present.)

If you loop over a templated path such as /clients/[client]/invoices, the captured segment is also available as a field, e.g. {folder::client}.

3. Looping over spreadsheet rows or API results

If you opened an Excel spreadsheet or called an API before the loop, each pass exposes that row's columns by name. For a sheet with columns Nr1, Nr2 and Sum:

  • {Nr1} – the first column's value for the current row
  • {Sum} – the Sum column's value for the current row

When data comes back as a JSON record, drill in with separators and indexes – for a list of members, {members::0::age} reaches the first member's age. See Working with variables in RPAs for the full nested-access rules.

4. Looping over emails

A loop over unread emails binds each email to your loop variable. If you named it email, read the subject as {email::subject} and the sender's address as {email::sender}. Inside the loop, {subject} and {sender} also work.

In this loop, sender, sender_name, has_attachments and total_attachments need bot 6.6.8 or later. On an older bot, read the address as {email::from::email}. Use the exact field name: from 6.6.8 a field that does not exist makes a loop filter row fail. On older bots it lets every email through with a "not" operator such as !=, and lets nothing through with =. Compare a field such as {email::sender}, not the whole {email}. For every field, see Email fields.

5. The loop's own timing

  • {loop_start_time} – when the loop started (YYYY-MM-DD HH:mm:ss)
  • {loop_timestamp} – when the current pass ended (YYYY-MM-DD HH:mm:ss)
  • {loop_tat} – how long the loop has taken, in seconds

Related articles

See it working on your own data

Everything documented here ships with the platform – try the document tools free, or go live in 7 days.