> ## Documentation Index
> Fetch the complete documentation index at: https://docs.therefrain.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk Form Submission

> Read rows from a CSV and submit each as a form entry across any web app.

## Overview

Data entry across web forms is one of the most repetitive tasks in any organization — onboarding new employees, submitting vendor registrations, updating records in legacy systems. When there's no API, someone has to type each entry manually.

Refrain's batch execution reads rows from a CSV and submits each one as a form entry. Self-healing selectors ensure the automation keeps working even when the form's UI changes.

## Example runbook

```yaml theme={null}
name: bulk-employee-registration
url: https://hr.example.com/employees/new
variables:
  - name: first_name
    source: data
  - name: last_name
    source: data
  - name: email
    source: data
  - name: department
    source: data
steps:
  - action: input
    selector: "#firstName"
    value: "{{ first_name }}"
  - action: input
    selector: "#lastName"
    value: "{{ last_name }}"
  - action: input
    selector: "#email"
    value: "{{ email }}"
  - action: select
    selector: "#department"
    value: "{{ department }}"
  - action: click
    selector: "#submit"
    requiresConfirmation: true
    confirmationMessage: "Submit registration for {{ first_name }} {{ last_name }}?"
  - action: wait
    selector: ".success-message"
```

## Generate and execute

<Steps>
  <Step title="Generate the runbook">
    ```bash theme={null}
    npx @refrainai/cli generate -- \
      --url https://hr.example.com/employees/new \
      --goal "Fill in the employee registration form and submit" \
      --context ./context.md \
      --output ./employee-registration.yaml
    ```
  </Step>

  <Step title="Prepare the CSV">
    ```csv theme={null}
    first_name,last_name,email,department
    Alice,Johnson,alice@example.com,Engineering
    Bob,Smith,bob@example.com,Marketing
    Carol,Williams,carol@example.com,Sales
    ```
  </Step>

  <Step title="Batch execute">
    ```bash theme={null}
    npx @refrainai/cli execute -- \
      --runbook ./employee-registration.yaml \
      --data ./employees.csv
    ```
  </Step>
</Steps>

## Why this works well

* **CSV-driven** — Each row becomes one form submission. No code needed.
* **Self-healing** — Form field changes are handled automatically.
* **Approval per row** — Add `requiresConfirmation` to review each submission before it's sent.
* **Scalable** — Process hundreds or thousands of rows in a single batch run.

## What's next

<CardGroup cols={2}>
  <Card title="Execute a runbook" icon="play" href="/guides/execute-runbook">
    Learn about batch execution with CSV data.
  </Card>

  <Card title="Variables and secrets" icon="key" href="/guides/variables-and-secrets">
    Use data sources and variable resolution.
  </Card>
</CardGroup>
