Step 1 of the CSV import flow. Uploads a file and returns an auto-detected column mapping plus preview rows. Nothing is inserted yet.
campaign_lead_lists record, runs a best-effort auto-mapping (pattern match first, then an LLM fallback for anything unmapped), and echoes the CSV back to you for the confirm step.
Nothing is written to campaign_prospects yet — agents should review (or blindly trust) the mapping and then call confirmCampaignCsv with the returned lead_list_id, csv_text, and final mapping.
Request format. multipart/form-data with a single file part — NOT application/json. The CSV/XLSX binary goes under the key file. Maximum file size is 10 MB. Supported extensions are .csv, .xlsx, .xls. Campaign must be in draft.
Email, First Name, Company, etc.). For esoteric headers the server calls an LLM (csvColumnMapping model) to map remaining fields against the first 3 data rows. If OPENROUTER_API_KEY isn’t set, only the pattern-matched columns are returned.Mapping shape. Keys are target fields (email, first_name, last_name, company, position, linkedin_url, headline). Values are the exact source column name, or null if no match was found. Agents should review, fill in any null entries where they’re confident, and pass the edited map to confirmCampaignCsv.Unmapped columns become custom fields. Anything in columns that isn’t in the final mapping values is rolled into each prospect’s custom_fields during confirm. Source headers are normalized (lowercased, spaces → underscores, non-alphanum stripped) for the JSON key.Round-tripping the content. The csv_text field is the raw CSV body — pass it verbatim to confirmCampaignCsv. The server re-parses with the confirmed mapping; no need to reconstruct the file.Preview cap. preview_rows contains the first 5 data rows keyed by source header. Use for UI preview only.Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Campaign UUID
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Send as multipart/form-data (NOT JSON). Attach the file under the key file. Example curl: -F [email protected].
The CSV (.csv) or Excel (.xlsx, .xls) file to upload. Maximum 10 MB. First row must be a header row; at least one data row is required.
File parsed. Returns lead_list_id, column headers, auto-detected mapping, preview rows, and the raw CSV text for the confirm step.
Newly-created campaign_lead_lists row. Pass this to confirmCampaignCsv along with the final mapping to actually insert prospects.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Header names detected in the uploaded file, in source order.
Best-effort map from target field (email, first_name, last_name, company, position, linkedin_url, headline) to the source column name. Uses pattern matching first, then an LLM fallback for unmapped columns. Values are the exact source header, or null if no match. Review and override before confirming.
First 5 data rows, keyed by source header. For UI preview.
Total non-empty data rows in the file.
0 <= x <= 9007199254740991Round-trip the file contents back as CSV text. Pass this verbatim to confirmCampaignCsv so the server can re-parse with the confirmed mapping.