Your GTM belongs in gitRegister
Blog

Migrate from Clay to Cargo, Column by Column

16 Oct
7min read

To migrate a go-to-market enrichment table from Clay to Cargo, map each Clay column to the Cargo action that does the same job, run those actions on a 20-row sample that includes rows Clay failed to fill, and compare coverage, agreement and cost per column before moving the next one. Columns you have not moved can keep running in Clay, called from Cargo.

You do not have to move the whole table at once, and you should not. The steps below are the clay-to-cargo skill, end to end. For the plan-level price comparison, see Cargo vs Clay.

What a Clay column becomes #

Match on what a column does, not on its label: Clay column names are whatever the table builder typed. Credits are list prices from each action’s definition in Cargo’s code.

What the Clay column doesCargo actionCreditsRecord fields
Find work email from name + domainprospeo.findEmail, then FullEnrich.findEmail on misses0.5, then 1firstName, lastName, companyDomain; then domainName
Person record from a LinkedIn URLprospeo.enrichLinkedin0.5url
LinkedIn profile detailslinkedin.enrichProfile0.25linkedinUrl
Validate emailwaterfall.verifyEmail0.1 per addressemail
Enrich company from domaincompanyEnrich.enrichByDomain0.25domain
Find mobile phoneFullEnrich.findPhone6firstName, lastName, domainName or linkedinUrl
A Clay table or workflow you keepclay.runRoutine0 Cargo creditsroutineId, inputs

Four Clay behaviours do not show up in a CSV export, and each one changes the migration:

  • Waterfalls. One Clay column can hide an ordered provider list. In Cargo each provider is its own step, cheapest first, and only the misses go to the next one, so you can see which step paid for each row.
  • Run conditions. A Clay column may only run on some rows. Ignore the condition and you run every action on every row, which is the usual way a migration comes back more expensive.
  • Auto-update. A table that re-runs on new rows is a schedule. In Cargo that is a play with a trigger, and it is a cost decision, not a default.
  • Partial runs. A column that only ever ran on 500 of 5,000 rows has a fill rate that describes 500 rows.

So export the column configuration, not just the CSV. The skill names the extraction paths in order of fidelity; with a CSV alone, the provider order and run conditions are guesses, and you should say so in the review.

What it costs on both sides #

Cargo platform data, 90 days to Oct 16 2026: work-email lookups returned an email in 63.6% of 1.85M runs, and 100% of the runs that found nothing were charged 0 credits. Company enrichment found a record in 91.6% of 2.45M runs.

That is what makes a Cargo table cheap to price in advance: you pay per action that returns data, so the ceiling per row is the sum of the columns. For the four columns most enrichment tables start with:

ColumnCeiling per row
Work email (prospeo.findEmail, then FullEnrich.findEmail on misses)1 credit (0.5 if the first step finds it, 1 if only the second does)
Email validation (waterfall.verifyEmail)0.1
Company enrichment (companyEnrich.enrichByDomain)0.25
Total1.35 credits

A 1,000-row table therefore costs at most 1,350 credits, which fits inside Cargo’s 1,500-credit monthly plan ($165/mo, from the pricing page). Rows that find nothing cost less. The email steps are covered in more detail in Find and Verify Work Emails at Scale.

Clay prices two meters, Actions and Data Credits, that add up to the plan price: Launch from 185/moandGrowthfrom185/mo and Growth from 495/mo on monthly billing (clay.com/pricing, fetched Oct 16 2026). Never compare a Clay credit to a Cargo credit: they are different units. Compare what the same sample of rows cost end to end on each side. The Clay vs Cargo calculator does that per record.

Run it #

1. Install and sign in

shellscript
npm install -g @cargo-ai/cli
cargo-ai login --email you@company.com                 # sends a code
cargo-ai login --email you@company.com --code 123456   # creates the account on first use

A new account starts with 100 free credits and needs no card, enough to migrate a 20-row sample of the four columns above several times over.

2. Pilot each column on the sample

Pick 20 rows, and include rows Clay left empty: a sample of Clay’s wins measures nothing, because both tools resolve the easy rows. --limit 5 submits only the first five records, so you see output and cost before the rest.

shellscript
# Work email, first step
cargo-ai orchestration action execute-batch \
  --action '{"kind":"connector","integrationSlug":"prospeo","actionSlug":"findEmail"}' \
  --records '[{"firstName":"Ada","lastName":"Lovelace","companyDomain":"example.com"}]' \
  --limit 5 --wait-until-finished

# Second step, on the misses only (note the field is domainName here)
cargo-ai orchestration action execute-batch \
  --action '{"kind":"connector","integrationSlug":"FullEnrich","actionSlug":"findEmail"}' \
  --records "$(cat misses.json)" \
  --wait-until-finished

# Company columns
cargo-ai orchestration action execute-batch \
  --action '{"kind":"connector","integrationSlug":"companyEnrich","actionSlug":"enrichByDomain"}' \
  --records '[{"domain":"example.com"}]' \
  --wait-until-finished

Download a batch’s results with cargo-ai orchestration batch download --uuid <batch uuid>.

3. Keep the columns you have not moved in Clay

clay.runRoutine runs a Clay table or workflow over one row from inside Cargo, on your own Clay API key. Cargo charges no credits for it; Clay bills its own credits as usual. The routineId is written as function:<id> for a table or workflow:<id> for a workflow, and the object has to be registered as a routine in Clay with API access enabled.

shellscript
cargo-ai orchestration action execute-batch \
  --action '{"kind":"connector","integrationSlug":"clay","actionSlug":"runRoutine"}' \
  --records '[{"routineId":"function:t_abc123","inputs":"{\"domain\":\"example.com\"}"}]' \
  --wait-until-finished

This is what makes column-by-column possible: the migrated columns run on Cargo and the rest still run in Clay, in the same flow.

4. Check parity before the next column

Report three numbers per column on the sample:

MeasureWhat it answers
CoverageOf the 20 rows, how many each side filled, against the column’s Clay fill rate
AgreementOn rows both filled, how often the values match
CostWhat the sample cost end to end on each side

On an email disagreement, run waterfall.verifyEmail on both values before calling either one wrong. Coverage above Clay’s is not a win on its own: a finder that fills more rows and agrees less is guessing.

5. Declare the table as code

When the columns hold, declare the flow in a Cargo project so it lives in git and changes are reviewed as diffs:

shellscript
cargo-ai project init my-engine
cd my-engine
cargo-ai project plan

plan prints the resource diff before anything is deployed.

Where Clay is still the better fit #

  • People who work in the grid. Clay’s table is something an operator without a terminal can open, read row by row and edit. Cargo is built for engineers and coding agents; if your table owner does not want a CLI or a repository, that is a real cost of moving.
  • Searching Clay’s own database. Clay sells search over its people and company data (Audiences, unlimited from the Launch plan). Cargo has no contact database of its own; it calls the providers you choose. If that search is the reason you use Clay, keep it, or call it from Cargo with the Clay connector’s search actions.
  • One provider bill you already pay. If most of your columns run on your own provider keys in Clay, the per-row saving is smaller. Run the parity sample before assuming a migration pays for itself.

Frequently asked questions #

Sources #

  • Clay: pricing and plan features, fetched Oct 16 2026.
  • Cargo: credit prices from each action’s definition in Cargo’s code; plan prices from pricing; job-level results from Cargo platform data, 90 days to Oct 16 2026.
AurelienOct 16, 2026

Give your agents a runtime

Bring the agents you have.Start free, deploy in one command.