POST
/
v1
/
orgs
/
{org_id}
/
workspaces
/
{workspace_id}
/
campaigns
/
{campaign_id}
/
cohorts
/
upload
Upload Cohort
curl --request POST \
  --url https://apps.sarvam.ai/api/scheduling/v1/orgs/{org_id}/workspaces/{workspace_id}/campaigns/{campaign_id}/cohorts/upload \
  --header 'Content-Type: multipart/form-data' \
  --header 'X-API-Key: <api-key>' \
  --form 'name=April Batch 1' \
  --form cohort_file='@example-file' \
  --form cohort_transformation_file='@example-file'
{
  "name": "<string>",
  "cohort_id": "<string>",
  "status": "processing",
  "source_type": "pre_signed_url",
  "created_by": "<string>",
  "created_at": "2023-11-07T05:31:56Z",
  "updated_at": "2023-11-07T05:31:56Z",
  "result": {
    "total_records": 123,
    "valid_records": 123,
    "rejected_records": 123
  },
  "updated_by": "<string>"
}

Overview

A cohort is a batch of users uploaded as a CSV along with a transformation config (JSON) that maps your CSV columns to phone numbers and agent variables. Uploading a cohort triggers background processing that validates each row and queues calls for valid records.
{
  "phone_number": { "column_name": "mobile" },
  "user_identifier": { "column_name": "customer_id", "required": true },
  "app_variables": {
    "customer_name": { "column_name": "name" },
    "loan_amount": { "column_name": "amount" }
  },
  "app_overrides": {
    "initial_language_name": { "column_name": "language" }
  }
}

Validation

Blocking — rejects the entire upload:
  • All referenced column_name values must exist as CSV headers
  • CSV must have at least one data row
  • app_overrides keys must be one of: initial_bot_message, initial_state_name, initial_language_name
  • For agent campaigns: app_variables keys must match the agent’s declared variables
Row-level — row is rejected, the rest continue:
  • Phone number must be valid (normalized to E.164)
  • Required columns must be non-empty
  • Formatting functions (if configured) must succeed
Rejected rows are collected into a downloadable CSV with an appended rejected_reason column.

Statuses

StatusDescription
processingUpload queued and being validated
completedProcessing finished; call queue populated
failedProcessing failed (upload-level error, not row-level)

Rejected records

Once status is completed, always check result.rejected_records. Poll:
GET /campaigns/{id}/cohorts/{cohort_id}
If result.rejected_records > 0, download the file to see which rows failed and why, then fix the data and re-upload:
GET /campaigns/{id}/cohorts/{cohort_id}/files?file_type=rejected_records
Rejected users will not be called. Catching and re-uploading them before the campaign goes live ensures maximum coverage.

Authorizations

X-API-Key
string
header
required

Path Parameters

org_id
string
required
workspace_id
string
required
campaign_id
string
required

Body

multipart/form-data
name
string
required

Name of the resource

Example:

"April Batch 1"

cohort_file
file
required

CSV file containing the cohort data

cohort_transformation_file
file
required

JSON file defining how CSV columns map to agent variables

Response

Successful Response

Cohort metadata including processing status and result counts.

name
string
required

Name of the resource

cohort_id
string
required

Unique identifier for the cohort

status
enum<string>
required

Current status

Available options:
processing,
completed,
failed
source_type
enum<string>
required

How the cohort was uploaded

Available options:
pre_signed_url,
file_upload
created_by
string
required

User who created this resource

created_at
string<date-time>
required

Timestamp when the resource was created (ISO 8601)

updated_at
string<date-time>
required

Timestamp when the resource was last updated (ISO 8601)

result
CohortResult · object

Processing result with record counts

updated_by
string | null

User who last updated this resource