CSV upload

Most production campaigns start with a CSV. Saaya accepts files up to 1GB or 5 million rows (whichever comes first), validates every row before any call goes out, and previews the first 100 rows in the dashboard so you can sanity-check.

Schema

The required column is `to` (E.164 phone number for voice / WhatsApp; email for chat-via-email). Every other column is optional and is exposed to the agent as a typed variable.

leads.csv
to,firstName,company,plan,locale
+919876543210,Anu,Acme,pro,en_IN
+919812345678,Ravi,Globex,starter,hi_IN
+14155550123,Sam,Initech,pro,en_US

Validation

On upload Saaya checks: phone numbers parse as E.164, emails are RFC-shaped, every row has the columns the agent expects, and no row exceeds 100KB. Invalid rows are surfaced before dispatch, no campaign starts with broken data.

campaigns-create.ts
const campaign = await saaya.campaigns.create({
  name:   "April refund follow-up",
  agentId: "agt_2N3rH...",
  channel: "voice",
  source: { type: "csv", uploadId: "upl_…" },
  schedule: { window: "weekdays-09-18-IST" },
});

await saaya.campaigns.start(campaign.id);

Preview

Before dispatch, the dashboard renders the first 100 rows with the agent's opening line filled in (placeholders resolved). Click into any row to see exactly what Saaya will say, catch personalisation bugs before they go to a customer.

Large files

Files over 100MB stream-upload directly to S3 with a presigned URL. Validation runs as a background job and emits progress events on `campaigns.upload.progress`. You can start the campaign as soon as validation completes.

Compliance reminder

Saaya checks each row against your opt-out list and the relevant DNC registry before dialing. Rows that fail this check are skipped and reported on the campaign summary.
Was this page helpful?