Batch calls
The batchcall resource runs bulk outbound phone campaigns. Upload a recipients file, then launch or schedule the campaign.
Upload recipients
upload reads a .csv, .xls, or .xlsx file (max 5 MB), uploads it, and waits for parsing, returning the parsed batch.
- Node.js
- Go
- Rust
const batch = await client.batchcall.upload({ filePath: "./leads.csv" });
batch, err := client.BatchCall.Upload(ctx, videosdk.UploadBatchCallParams{FilePath: "./leads.csv"})
let batch = client.batch_call().upload(videosdk::UploadBatchCallParams {
file_path: "./leads.csv".into(),
..Default::default()
}).await?;
Options: filePath (required), batchId (replace the file on an existing batch), waitForParse (default true), poll interval / timeout.
Track parsing progress
Parsing runs after the file uploads. In Node.js, upload returns a handle that is both awaitable and an event emitter, so you can subscribe to progress with .on. In Go, pass an OnParsing callback; in Rust, pass an on_parsing callback. The parsed batch is the return value, and failures come back as the returned error.
- Node.js
- Go
- Rust
const job = client.batchcall.upload({ filePath: "./leads.csv" });
job.on("parsing", () => {}); // parsing started
job.on("parsed", (batch) => {}); // parsing finished, batch ready to launch
job.on("parse_failed", (err) => {}); // parsing failed
job.on("error", (err) => {}); // any failure: upload, parse, or timeout
const batch = await job; // the handle is also awaitable
batch, err := client.BatchCall.Upload(ctx, videosdk.UploadBatchCallParams{
FilePath: "./leads.csv",
OnParsing: func() { /* parsing started */ },
})
let batch = client.batch_call().upload(videosdk::UploadBatchCallParams {
file_path: "./leads.csv".into(),
on_parsing: Some(Box::new(|| { /* parsing started */ })),
..Default::default()
}).await?;
Create a campaign
- Node.js
- Go
- Rust
const campaign = await client.batchcall.create({
batchName: "Q3 outreach",
phoneNumberId: "pn_1",
routingRuleId: "rr_1",
batchId, // from upload
timing: "scheduled",
scheduledDate: "2026-07-01",
scheduledTime: "09:30",
});
campaign, err := client.BatchCall.Create(ctx, videosdk.CreateBatchCallParams{
BatchName: "Q3 outreach",
PhoneNumberID: "pn_1",
RoutingRuleID: "rr_1",
BatchID: batchID, // from upload
Timing: videosdk.BatchCallScheduled,
ScheduledDate: "2026-07-01",
ScheduledTime: "09:30",
})
let campaign = client.batch_call().create(videosdk::CreateBatchCallParams {
batch_name: "Q3 outreach".into(),
phone_number_id: "pn_1".into(),
routing_rule_id: "rr_1".into(),
batch_id: Some(batch_id), // from upload
timing: Some(videosdk::BatchCallTiming::SCHEDULED),
scheduled_date: Some("2026-07-01".into()),
scheduled_time: Some("09:30".into()),
..Default::default()
}).await?;
Required: batchName, phoneNumberId, routingRuleId. Scheduling: timing (immediate or scheduled), timezone, scheduledDate / scheduledTime, allowedFrom / allowedUntil, daysOfWeek. Also retry, webhook, saveAsDraft.
Manage a campaign
- Node.js
- Go
- Rust
await client.batchcall.list({ status: "running" });
await client.batchcall.get(batchId);
await client.batchcall.update(batchId, { scheduledTime: "10:00" });
await client.batchcall.cancel(batchId, "graceful"); // or "immediate"
await client.batchcall.delete(batchId);
await client.batchcall.stats(batchId);
client.BatchCall.List(ctx, videosdk.ListBatchCallsParams{Status: videosdk.BatchStatusRunning})
client.BatchCall.Get(ctx, batchID)
client.BatchCall.Update(ctx, batchID, videosdk.UpdateBatchCallParams{ScheduledTime: videosdk.String("10:00")})
client.BatchCall.Cancel(ctx, batchID, videosdk.BatchCancelGraceful) // or BatchCancelImmediate
client.BatchCall.Delete(ctx, batchID)
client.BatchCall.Stats(ctx, batchID)
client.batch_call().list(videosdk::ListBatchCallsParams {
status: Some(videosdk::BatchCallStatus::RUNNING),
..Default::default()
}).await?;
client.batch_call().get(&batch_id).await?;
client.batch_call().update(&batch_id, videosdk::UpdateBatchCallParams {
scheduled_time: Some("10:00".into()),
..Default::default()
}).await?;
client.batch_call().cancel(&batch_id, videosdk::BatchCallCancelMode::GRACEFUL).await?; // or IMMEDIATE
client.batch_call().delete(&batch_id).await?;
client.batch_call().stats(&batch_id).await?;
Records
A batch's per-number records are available on the records sub-resource.
- Node.js
- Go
- Rust
await client.batchcall.records.list(batchId, { status: "not connected" });
await client.batchcall.records.update(batchId, recordId, { phoneNumber: "+14155550123" });
await client.batchcall.records.delete(batchId, [recordId]);
const csv = await client.batchcall.records.export(batchId); // CSV text
client.BatchCall.Records.List(ctx, batchID, videosdk.ListBatchCallRecordsParams{Status: "not connected"})
client.BatchCall.Records.Update(ctx, batchID, recordID, videosdk.UpdateBatchCallRecordParams{PhoneNumber: videosdk.String("+14155550123")})
client.BatchCall.Records.Delete(ctx, batchID, []string{recordID})
csv, err := client.BatchCall.Records.Export(ctx, batchID, videosdk.ExportBatchCallRecordsParams{}) // CSV text
client.batch_call().records().list(&batch_id, videosdk::ListBatchCallRecordsParams {
status: Some("not connected".into()),
..Default::default()
}).await?;
client.batch_call().records().update(&batch_id, &record_id, videosdk::UpdateBatchCallRecordParams {
phone_number: Some("+14155550123".into()),
..Default::default()
}).await?;
client.batch_call().records().delete(&batch_id, &[record_id.clone()]).await?;
let csv = client.batch_call().records().export(&batch_id, videosdk::ExportBatchCallRecordsParams::default()).await?; // CSV text
The batch object
Returned by batchcall.create, list, get, update, cancel, and (resolved) upload.
| Field | Type | Description |
|---|---|---|
batchId | string | Unique batch id. |
batchName | string | Display name. |
status | string | Batch status (parsing, parsed, running, completed, cancelled, …). |
phoneNumberId | string | Outbound phone number id. |
routingRuleId | string | Outbound routing rule id. |
timing | string | immediate or scheduled. |
recordsUploaded | number | Count of parsed recipient rows. |
progress | number | Completion percentage (list view only). |
The record object
Returned by batchcall.records.list and update.
| Field | Type | Description |
|---|---|---|
recordId | string | Unique record id. |
batchId | string | Parent batch id. |
phoneNumber | string | Recipient number. |
status | string | Display status (scheduled, not connected, …). |
callId | string | Placed call id, once dialed. |
reason | string | Failure or outcome reason. |
attempts | number | Number of dial attempts made. |
callDuration | number | Call length in seconds, null if not connected. |
metadata | object | Per-row custom fields from the uploaded file. |
The stats object
Returned by batchcall.stats. Alongside the fields below, the object carries one numeric key per status bucket (scheduled, running, completed, not connected, …).
| Field | Type | Description |
|---|---|---|
batchId | string | Batch id. |
status | string | Overall batch status. |
total | number | Total number of records. |
Got a Question? Ask us on discord

