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

# Batch CSV enrichment

> Create a CSV-safe pilot, run an inspected batch contract, and verify row outcomes and usage.

[Human guide: work with your agent →](https://deepline.com/docs/human/sdk-v2/batch-csv.md)

Run a representative CSV pilot, inspect its row outcomes, and export the same
run. The file contract belongs to the selected Play.

## Before you start

Use an authorized workspace and a CSV with a header. Preserve a stable source
ID for every row. This guide uses names and company domains for a work-email
batch. Other Plays can require different columns.

## 1. Inspect the file and contract

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline auth status --json
deepline csv show --csv leads.csv --summary
deepline describe prebuilt/name-and-domain-to-email-waterfall-batch --json
deepline plays check prebuilt/name-and-domain-to-email-waterfall-batch
```

Compare required row fields with your actual headers. The current batch has
canonical `first_name`, `last_name`, and `domain` inputs. Its default header
aliases are uppercase. The run below maps lowercase headers explicitly.

A check validates the Play without calling providers. It does not establish
that the file contains the correct people or acceptable business data.

## 2. Select representative CSV records

Choose existing zero-based data-row indexes from the file summary and preview.
Include easy, typical, and difficult cases. Do not split records with `head`
or `awk`: a quoted CSV field can contain a newline.

This Python example selects rows 0, 6, and 12. Change the indexes to three
existing representative records before running it:

```py theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
import csv

selected = {0, 6, 12}
found = set()
with open("leads.csv", newline="", encoding="utf-8-sig") as source:
    reader = csv.DictReader(source)
    if not reader.fieldnames:
        raise ValueError("The CSV needs a header")
    with open("leads-pilot.csv", "w", newline="", encoding="utf-8") as target:
        writer = csv.DictWriter(target, fieldnames=reader.fieldnames)
        writer.writeheader()
        for index, row in enumerate(reader):
            if index in selected:
                writer.writerow(row)
                found.add(index)
if found != selected:
    raise ValueError(f"Missing selected row indexes: {selected - found}")
```

> [!TIP]
>
> The pilot retains the source header and the three selected records. Embedded
> commas, quotes, and newlines remain CSV data rather than extra rows.

For input validation rules, use [Validate incoming CSV files](https://deepline.com/docs/guides/validate-incoming-csv-files.md).

## 3. Run only the pilot

This command starts provider-backed work and can incur usage:

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline plays run prebuilt/name-and-domain-to-email-waterfall-batch \
  --csv leads-pilot.csv \
  --columns.first_name first_name \
  --columns.last_name last_name \
  --columns.domain domain \
  --watch
```

Save the returned run ID. Then inspect, export, and read usage for that run:

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline runs get <run-id> --full --json
deepline runs export <run-id> --out leads-pilot-results.csv
deepline billing usage --run-id <run-id> --json
```

If several datasets exist, select a path returned by the run with `--dataset`.
Do not start another run to recover an export.

## 4. Decide whether the pilot passed

Reconcile input IDs with accepted, unresolved, and failed outcomes. Check person
identity, returned email, source, validation, and usage. Do not count completed
requests as accepted contacts.

Workspace balance changes can include other work. Use scoped billing evidence,
not a balance subtraction, to attribute the pilot's usage. Pending amounts are
not final charges.

## 5. Expand the same reviewed contract

Use the same mappings with `--csv leads.csv` only after the pilot passes.
A changed Play or acceptance rule needs another representative check.
For custom file logic, use [Write Plays](https://deepline.com/docs/sdk-v2/plays.md).

Ask your agent to explain missing row IDs or unexpected fields before scaling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.