> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ringg.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload large campaign CSV (Beta)

> Upload a 5,000+ row campaign CSV for asynchronous processing.

<Warning>
  This endpoint is beta. Use it only when large-campaign access is enabled for your workspace. For most campaigns, use [Upload campaign contact list](/api-reference/endpoint/campaign/upload-campaign-contact-list) and then [Start campaign](/api-reference/endpoint/campaign/start-campaign).
</Warning>

`POST /campaign/upload-csv` starts the beta large-campaign flow. It accepts a large CSV and campaign configuration, then returns a `bulk_list_id` that you use for status polling, balance checking, and async call scheduling.

## Endpoint

```text theme={null}
POST /campaign/upload-csv
```

## When to use

Use this endpoint for CSVs with 5,000 or more rows. It lets Ringg process and validate the upload asynchronously instead of making the initial upload request wait for the full import.

## Request guidance

Send `multipart/form-data`. Use the same CSV template and campaign fields as the standard `POST /campaign/save` flow.

| Field                       | Required | Notes                                                        |
| --------------------------- | -------- | ------------------------------------------------------------ |
| `file`                      | Yes      | CSV file with `Mobile Number` and assistant variable columns |
| `agent_id`                  | Yes      | Assistant that will handle the campaign calls                |
| `campaign_name`             | Yes      | Human-readable campaign name                                 |
| `country_code`              | Yes      | Dialing prefix, such as `+91` or `+1`                        |
| `variables_map`             | Yes      | JSON string mapping assistant variables to CSV columns       |
| `campaign_start_time`       | Yes      | Campaign start time in `DD/MM/YYYY, HH:MM` format            |
| `campaign_end_time`         | Yes      | Campaign end time in `DD/MM/YYYY, HH:MM` format              |
| `call_config`               | Yes      | JSON string for call window, retry, and call limit settings  |
| `remove_invalid_rows`       | No       | Set to `true` to skip invalid rows when supported            |
| `transliterate_callee_name` | No       | Set to `true` when callee names should be transliterated     |

```bash theme={null}
curl --request POST "https://prod-api.ringg.ai/ca/api/v0/campaign/upload-csv" \
  --header "X-API-KEY: $RINGG_API_KEY" \
  --form 'agent_id="your-agent-id"' \
  --form 'campaign_name="Renewal reminders - large batch"' \
  --form 'country_code="+91"' \
  --form 'variables_map="{\"mobile_number\":\"Mobile Number\",\"callee_name\":\"Name\"}"' \
  --form 'campaign_start_time="18/10/2026, 09:00"' \
  --form 'campaign_end_time="18/10/2026, 18:00"' \
  --form 'call_config="{\"call_time\":{\"call_start_time\":\"09:00\",\"call_end_time\":\"18:00\",\"timezone\":\"Asia/Kolkata\"}}"' \
  --form "file=@contacts-5000-plus.csv"
```

<Info>
  Do not set `Content-Type` manually in browser or Node `FormData` clients. Let the client include the multipart boundary.
</Info>

## Response guidance

Persist the returned `bulk_list_id`. It identifies the uploaded list for every later beta endpoint.

```json theme={null}
{
  "bulk_list_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "uploaded",
  "message": "CSV upload accepted for processing"
}
```

## Next step

Poll [Get large campaign upload status](/api-reference/endpoint/campaign/get-large-campaign-upload-status) until the upload is processed. Do not check balance or start calls until processing is complete.


## OpenAPI

````yaml post /campaign/upload-csv
openapi: 3.0.0
info:
  title: Ringg AI API Documentation
  description: >-
    This is the documentation for the Ringg AI APIs. The Ringg AI API follows
    RESTful principles, making it intuitive and easy to integrate with your
    applications. All API requests should be made to the base URL. The API
    accepts and returns data in JSON format. Ensure your requests include the
    appropriate Content-Type header for POST and PATCH requests.
  version: 2.0.0
servers:
  - url: https://prod-api.ringg.ai/ca/api/v0
security: []
tags:
  - name: workspace
    description: Endpoints for managing your workspace.
  - name: agent
    description: Endpoints for managing assistants (agents).
  - name: calling
    description: Endpoints for making and managing calls.
  - name: campaign
    description: Endpoints for managing campaigns.
  - name: analytics
    description: Endpoints for accessing call analytics and performance metrics.
  - name: termination
    description: Endpoints for terminating active calls using different methods.
  - name: knowledgebase
    description: Endpoints for managing knowledge bases.
paths:
  /campaign/upload-csv:
    post:
      tags:
        - campaign
      summary: Upload Campaign CSV (Beta)
      description: >-
        Beta endpoint for large campaigns of 5k+ rows. Uploads and validates a
        CSV asynchronously, creating a draft bulk list.
      operationId: uploadCampaignCsvBeta
      parameters:
        - name: X-API-KEY
          in: header
          description: (Required) Your Ringg AI API key.
          required: true
          schema:
            type: string
            example: 7251cb4b-3373-43a4-844c-b27a1d45e0c9
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - variables_map
                - agent_id
                - country_code
                - campaign_name
                - file
              properties:
                variables_map:
                  type: string
                  description: >-
                    (Required) JSON string mapping assistant variable names to
                    CSV columns.
                  example: '{"mobile_number":"Mobile Number","callee_name":"Name"}'
                agent_id:
                  type: string
                  description: (Required) Assistant ID used to validate campaign variables.
                  example: 830f767a-397e-4b39-82ff-235cd344e2f9
                country_code:
                  type: string
                  description: (Required) Phone number country code, for example +91 or +1.
                  example: '+91'
                campaign_name:
                  type: string
                  description: (Required) Name of the campaign draft.
                  example: Renewal reminders - large upload
                file:
                  type: string
                  format: binary
                  description: (Required) CSV file containing campaign contacts.
                remove_invalid_rows:
                  type: boolean
                  description: >-
                    When true, invalid rows are removed instead of failing the
                    upload.
                  default: false
                  example: true
                transliterate_callee_name:
                  type: boolean
                  description: >-
                    When true, callee names are transliterated for the assistant
                    language.
                  default: false
                  example: false
      responses:
        '200':
          description: CSV upload accepted for asynchronous validation.
          content:
            application/json:
              schema:
                type: object
                properties:
                  bulk_list_id:
                    type: string
                    example: 123e4567-e89b-12d3-a456-426614174000
                  status:
                    type: string
                    example: verifying
                  campaign_name:
                    type: string
                    example: Renewal reminders - large upload
                  total_callees:
                    type: integer
                    example: 5000
                  invalidated_rows_count:
                    type: integer
                    example: 12
                  invalidated_rows_csv_url:
                    type: string
                    nullable: true
                    example: https://storage.example.com/invalid-rows.csv
                example:
                  bulk_list_id: 123e4567-e89b-12d3-a456-426614174000
                  status: verifying
                  campaign_name: Renewal reminders - large upload
                  total_callees: 0
                  invalidated_rows_count: 0
                  invalidated_rows_csv_url: null
        '400':
          description: Bad Request - Invalid input.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: Invalid CSV file or variable mapping.
        '401':
          description: Unauthorized - Invalid or missing authentication.

````