Skip to content

Import and Copy Records

Validate a CSV against the destination schema before committing it to the chosen development or live store. A commit skips invalid rows and appends valid ones. Copy to live copies development records and overwrites matching record keys.

Use Invoice intake and custom.invoice from Store Workflow Data. That guide creates INV-104. This fixture uses INV-105 and INV-106. Check for existing invoices first because business fields are not uniqueness constraints.

In the app: open Workflows → Invoice intake → Dev → Data tables, select Invoice, and use View data type to inspect fields. Record the row count.

With an assistant: list workflows to find the workflow ID.

Terminal window
cai workflow list --limit 100 --json

Note the matching data.items[].id as <workflowId>. If it is absent and data.hasMore is true, get the ID from the app or owner. After pinning the workflow once, subsequent CLI commands omit --workflow.

MCP uses workflow_list with limit: 100.

Pin the workflow and inspect its fields, collections, and existing records.

Terminal window
cai use <workflowId> --json
cai data fields --type custom.invoice --json
cai data collections --env dev --json
cai data query --type custom.invoice --env dev --limit 100 --offset 0 --json

Note data.totalCount. Increase offset by 100 until you have inspected every row. Choose unused invoice IDs.

MCP has no workflow pin. Use data_field_list, data_collection_list, and data_record_query with workflowId on each call.

Use field display names for CSV headers and field IDs for direct writes. Omit reserved headers id, created time, and updated time. Reserved or misspelled headers reject the file with Unknown CSV headers: …. Duplicate headers also reject it before row validation.

Save this CSV as invoices.csv to match the inspected labels and unused IDs.

Invoice ID,Amount,Status,Review needed,Submitted at,Source event ID
INV-105,120,ready,false,2026-09-07T14:00:00Z,docs-105
INV-106,1500,review,true,2026-09-07T14:00:00Z,docs-106

Numbers must be finite. Booleans use true or false. Dates use ISO-8601 text. Omitted columns and empty cells become null. Whitespace-only non-text cells also become null. Text preserves whitespace.

Text, number, and boolean lists use JSON arrays. References use existing record IDs from the destination store. Reference lists use JSON arrays of IDs. Nonblank values of unsupported types, including list.date, produce CSV import does not support field type "…".

You can upload up to 10 MB and 10,000 parsed rows after the header. Blank lines count toward that limit but are excluded from totalRows and import. If a row has the wrong column count, the whole row is invalid. MCP inline CSV is limited to 2 MiB of UTF-8 text.

In the app: choose Upload records manually → Choose CSV file to validate without writing. Before choosing Import 2 records, inspect the counts and issues. When at least one row is valid, the button permits partial imports.

With an assistant: validate the CSV to get a report of counts and issues.

Terminal window
cai data import --type custom.invoice --file invoices.csv --mode dryRun --env dev --json

Inspect totalRows, validCount, errorCount, warningCount, errors, and warnings. CLI JSON and MCP structured content put the report at data.result. MCP’s text block uses result.

MCP uses data_record_import_validate with workflowId, type, explicit env: "dev", and the CSV text as content instead of a local path.

One row can have multiple errors. CLI/MCP return at most 200 errors and 200 warnings. The app shows 50 combined issues. Counts remain complete, so fix listed problems and validate again.

Missing references produce warnings. Missing single references become null. Missing list items are dropped.

To check errors, change the second amount to not-a-number and validate. Expect two rows, one valid row, and an amount error. Restore 1500 and validate again before committing.

The hosted Build for me assistant can only validate. Its owner commits or copies in the app.

Commit skips invalid rows, then writes all valid rows in one transaction. With zero valid rows, the commit succeeds with importedCount: 0. If the database fails, none of the valid batch is committed. Even with identical invoice IDs, repeating a commit appends the records again.

Commit once and query the destination to inspect the imported records.

Terminal window
cai data import --type custom.invoice --file invoices.csv --mode commit --env dev --json
cai data query --type custom.invoice --env dev --limit 100 --offset 0 --json

Before retrying an uncertain result, check data.result.importedCount and destination values. Without other writers, expect two additional records. Verify amounts and review flags. Import validates types, not the example rule Amount > 1000.

MCP uses data_record_import_commit with the same workflowId, type, explicit env, and content.

Publish the matching schema first. Publication activates the workflow and lets enabled live triggers run. It never copies development rows.

If the live collection is missing, the CLI returns NO_LIVE_COLLECTION. Even when only a newly added development schema needs publication, the backend says This workflow has not been published yet. A changed schema produces The live schema for this data type is out of date — publish the workflow first.

Copying includes every undeleted development record of this type. It preserves live-only rows, overwrites matching id keys, and revives deleted matches using development values. Records are not matched by Invoice ID. Workflow restore cannot recover overwritten or deleted records.

Immediately before copying, query both stores to inspect every page.

Terminal window
cai data query --type custom.invoice --env dev --limit 100 --offset 0 --json
cai data query --type custom.invoice --env live --limit 100 --offset 0 --json

Check both data.totalCount values.

In the app: go to Dev → Data tables → Invoice, open the heading menu, choose Copy to live, and confirm.

With an assistant: copy the records to live and query the live store to inspect the result.

Terminal window
cai data copy-to-live --type custom.invoice --json
cai data query --type custom.invoice --env live --limit 100 --offset 0 --json

Check data.result.createdCount, data.result.updatedCount, data.result.totalRecords, and live values. In the app, switch to Live → Data tables. Repeating copy overwrites subsequent live edits on matching records.

MCP’s data_copy_to_live requires workflowId, type, and env: "live". CLI has no environment flag for this command.

To import directly into live, first publish a live version containing the type. Select Live before uploading, or use --env live for validation and commit (MCP: env: "live"). Validate against that destination’s schema and references. Committed rows reach live runs immediately without another publish.

Workflow restore recovers definitions, not overwritten or deleted records.

Deleting a type deactivates its collection and removes other types’ fields that reference it. Recreating the same key reactivates retained rows but does not recreate those reference fields.

Removing fields hides their stored values. Changing a field’s type does not convert its stored values. Incompatible values read as null. Restore the same field IDs and compatible types to expose retained values. Inspect schema mistakes before importing replacement rows.