> ## 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.

> ## Agent Instructions
> To search or read these docs, connect the Ringg docs MCP server at https://docs.ringg.ai/mcp (no key needed; tools search_ringg_ai and query_docs_filesystem_ringg_ai) instead of browsing pages one by one. Setup for each client: https://docs.ringg.ai/resources/mcp-server/docs-mcp-server/mcp-for-ai-assistants.md
> The dashboard labels agents "Assistants"; these docs say "agent". Both mean the same object, identified by agent_id.
> API base URL: https://prod-api.ringg.ai/ca/api/v0. Send the workspace API key in the X-API-KEY header, from server-side code only.
> Placing a call dials a real phone number and spends credits. Confirm the number with the user before calling.
> To act on a Ringg workspace (place calls, edit agents, read transcripts), use the separate Ringg workspace MCP server at https://mcp.ringg.ai/mcp: https://docs.ringg.ai/resources/mcp-server/workspace-mcp-server/overview.md

# Upload large campaign CSV (Beta)

> Upload a calling list for validation in the background, and get the bulk_list_id you poll for status and then start calls with.

export const RelatedTopics = ({items}) => <div className="not-prose mt-12">
    <div className="text-sm font-medium text-gray-500 dark:text-zinc-400 mb-3">Related topics</div>
    <div className="flex flex-col gap-2.5">
      {items.map(([title, href]) => <a key={href} href={href} className="flex items-center gap-2.5 text-sm text-gray-700 hover:text-gray-950 dark:text-zinc-300 dark:hover:text-white">
          <Icon icon="file-text" size={16} color="currentColor" />
          {title}
        </a>)}
    </div>
  </div>;

The calling window, retries and caller numbers are not sent here; they go with [Start large campaign calls](/api-reference/calling/large-campaigns/make-large-campaign-calls-async).

The flow: upload → poll [upload status](/api-reference/calling/large-campaigns/get-large-campaign-upload-status) until it is `draft` → [start calls](/api-reference/calling/large-campaigns/make-large-campaign-calls-async).

## Fields

The CSV follows the same rules as for [Upload campaign contact list](/api-reference/calling/campaigns/upload-campaign-contact-list#the-csv). A list may have up to 100 rows by default, and up to 5,000 once Company details are saved in the dashboard; a longer list returns `402`. Contact Ringg for a higher limit.

* Invalid rows never fail this upload: the valid rows load and the invalid ones are left out. With `remove_invalid_rows` off, the uploader is also emailed the invalid rows.
* `transliterate_fields` is a JSON array of the agent's own variable names, not CSV headers, whose values are transliterated into the agent's language. Each must be mapped in `variables_map`, and `mobile_number` is not allowed. `transliterate_callee_name=true` is the same as adding `callee_name`.

```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="EMI reminders - October"' \
  --form 'country_code="+91"' \
  --form 'variables_map="{\"mobile_number\":\"mobile_number\",\"callee_name\":\"callee_name\"}"' \
  --form 'remove_invalid_rows="true"' \
  --form "file=@emi-reminders.csv"
```

## Response

```json theme={null}
{
  "message": "CSV uploaded successfully. Processing in background.",
  "bulk_list_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "verifying",
  "total_rows": 5000,
  "campaign_name": "EMI reminders - October"
}
```

`total_rows` counts the rows in the file, not counting fully blank rows. Valid and invalid counts come from [upload status](/api-reference/calling/large-campaigns/get-large-campaign-upload-status) once validation finishes.

Store `bulk_list_id`. It is the campaign's ID in every later call, in call history and in analytics.

<RelatedTopics items={[["Calling list", "/documentation/deploy/campaigns/calling-list"], ["Run a campaign by API", "/documentation/deploy/campaigns/campaigns-by-api#large-campaign-flow"]]} />


## OpenAPI

````yaml post /campaign/upload-csv
openapi: 3.0.0
info:
  title: Ringg AI API Documentation
  description: >-
    The Ringg AI REST API. Base URL https://prod-api.ringg.ai/ca/api/v0; send
    your workspace API key in the X-API-KEY header from server-side code only.
    Requests and responses are JSON.
  version: 2.0.0
  contact:
    name: Ringg AI support
    email: admin@ringg.ai
    url: https://docs.ringg.ai
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 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. Uploads a campaign list and checks it in the background,
        creating a draft bulk list. Works for lists of any size up to the
        workspace's row limit.
      operationId: uploadCampaignCsvBeta
      parameters:
        - name: X-API-KEY
          in: header
          description: (Required) Your Ringg AI API key.
          required: true
          schema:
            type: string
            example: rg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      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 agent variable names to CSV
                    columns.
                  example: '{"mobile_number":"Mobile Number","callee_name":"Name"}'
                agent_id:
                  type: string
                  description: (Required) Agent ID used to validate campaign variables.
                  example: 00000000-0000-4000-8000-0000000000a1
                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: >-
                    (Optional) Invalid rows never fail this upload: valid rows
                    load and invalid rows are left out. When false, the uploader
                    is emailed the invalid rows; true skips that email.
                  default: false
                  example: true
                transliterate_callee_name:
                  type: boolean
                  description: >-
                    (Optional) Transliterate `callee_name` into the agent's
                    language. Same as adding `callee_name` to
                    `transliterate_fields`. A row whose name cannot be
                    transliterated is dropped as invalid.
                  default: false
                  example: false
                transliterate_fields:
                  type: string
                  description: >-
                    (Optional) JSON string array of the agent's own variable
                    names (not CSV headers) whose values are transliterated into
                    the agent's language, for example ["callee_name"]. Each must
                    be mapped in `variables_map`; `mobile_number` is refused
                    with 400. The original value stays available as
                    `original_<field>`. Combined with
                    `transliterate_callee_name` when both are sent.
                  example: '["callee_name"]'
      responses:
        '200':
          description: >-
            CSV accepted. The list is checked in the background; poll Get
            Campaign Upload Status.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: CSV uploaded successfully. Processing in background.
                  bulk_list_id:
                    type: string
                    example: 123e4567-e89b-12d3-a456-426614174000
                  status:
                    type: string
                    example: verifying
                  total_rows:
                    type: integer
                    description: Rows in the file, not counting fully blank rows.
                    example: 5000
                  campaign_name:
                    type: string
                    example: Renewal reminders - large upload
                example:
                  message: CSV uploaded successfully. Processing in background.
                  bulk_list_id: 123e4567-e89b-12d3-a456-426614174000
                  status: verifying
                  total_rows: 5000
                  campaign_name: Renewal reminders - large upload
        '400':
          description: Bad Request - Invalid input.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Invalid CSV file or variable mapping.
        '401':
          description: Unauthorized - Invalid or missing authentication.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Invalid credentials
        '402':
          description: >-
            Payment Required - The list has more rows than the workspace may
            upload: 100 by default, 5,000 once Company details are saved.
            Contact Ringg for a higher limit.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: You can only upload up to 100 contacts.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.