> ## 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 a campaign calling list as CSV with the agent, variable mapping, country code, campaign window and call settings, and get the list_id to start it with.

# Upload Campaign Contact List

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>;

Nothing is dialled yet: start the campaign with [Start campaign (number pool)](/api-reference/calling/campaigns/start-campaign-v2) or [Start campaign](/api-reference/calling/campaigns/start-campaign). The `list_id` is also the campaign's ID in [Get all campaigns](/api-reference/calling/campaigns/get-all-campaigns), call history and analytics (`bulk_list_id`).

## The CSV

One header row, then one row per contact. Every outbound agent has the variables `mobile_number` and `callee_name`, so the file needs a column for each, plus one for every other variable the agent's prompt uses. Write phone numbers without the country code; `country_code` applies to the whole list.

```text theme={null}
callee_name,mobile_number,amount_due,due_date
Priya Sharma,9876543210,4500,12 October
Rahul Verma,9876540123,1200,15 October
```

[Calling list](/documentation/deploy/campaigns/calling-list) has the full file rules.

## Fields

`campaign_start_time` and `campaign_end_time` are read in `call_config.call_time.timezone`, and the start must be in the future. Without `remove_invalid_rows`, a row that fails validation fails the whole upload with `400`, and the uploader is emailed the errors. 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`.

`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`; both can be sent.

`variables_map` for the CSV above:

```json theme={null}
{"callee_name": "callee_name", "mobile_number": "mobile_number", "amount_due": "amount_due", "due_date": "due_date"}
```

`call_config` is a JSON string with the daily window calls may be placed in and how failed calls are retried. Retry waits are in minutes.

```json theme={null}
{
  "call_time": { "call_start_time": "09:00", "call_end_time": "18:00", "timezone": "Asia/Kolkata" },
  "call_retry_config": { "retry_count": 2, "retry_busy": 30, "retry_not_picked": 30, "retry_failed": 30 }
}
```

## Response

```json theme={null}
{
  "message": "Contacts imported successfully!",
  "list_id": "123e4567-e89b-12d3-a456-426614174000",
  "total_rows": 100,
  "successful_rows": 98,
  "failed_rows": 2
}
```

<RelatedTopics items={[["Run a campaign by API", "/documentation/deploy/campaigns/campaigns-by-api#with-the-api"]]} />


## OpenAPI

````yaml post /campaign/save
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/save:
    post:
      tags:
        - campaign
      summary: Upload Campaign Contact List
      description: >-
        Uploads a contact list for a campaign. Accepts a CSV file and campaign
        configuration as form data.
      operationId: uploadCampaignContactList
      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
                - call_config
                - country_code
                - campaign_start_time
                - campaign_end_time
                - campaign_name
                - file
              properties:
                variables_map:
                  type: string
                  description: (Required) JSON string mapping variable names to columns
                  example:
                    callee_name: Name
                    company_name: Company
                agent_id:
                  type: string
                  description: (Required) Unique identifier for the agent
                  example: 00000000-0000-4000-8000-0000000000a1
                call_config:
                  type: string
                  description: (Required) JSON string of call configuration
                  example:
                    idle_timeout_warning: 10
                    max_call_length: 300
                country_code:
                  type: string
                  description: >-
                    (Required) Phone number country code (e.g., +91 for India,
                    +1 for US)
                  example: '+91'
                campaign_start_time:
                  type: string
                  description: >-
                    (Required) Start time for the campaign (DD/MM/YYYY, HH:MM
                    format)
                  example: 18/10/2025, 09:00
                campaign_end_time:
                  type: string
                  description: >-
                    (Required) End time for the campaign (DD/MM/YYYY, HH:MM
                    format)
                  example: 18/10/2025, 21:05
                campaign_name:
                  type: string
                  description: (Required) Name of the campaign.
                  example: Q1 Sales Campaign
                file:
                  type: string
                  format: binary
                  description: (Required) CSV file containing the contact list.
                  example: contacts.csv
                remove_invalid_rows:
                  type: boolean
                  description: >-
                    (Optional) When true, invalid rows are left out. When false,
                    any invalid row fails the whole upload with 400 and the
                    uploader is emailed the errors.
                  default: false
                  example: false
                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: Contact list uploaded and campaign saved successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Contacts imported successfully!
                  list_id:
                    type: string
                    description: ID of the created campaign list
                    example: 123e4567-e89b-12d3-a456-426614174000
                  custom_args_values:
                    type: array
                    description: Array of custom variables for each contact
                    items:
                      type: object
                    example:
                      - callee_name: John Doe
                        company_name: XYZ Corp
                        mobile_number: '+1234567890'
                  total_rows:
                    type: integer
                    description: Total number of rows in uploaded CSV
                    example: 100
                  successful_rows:
                    type: integer
                    description: Number of successfully processed rows
                    example: 98
                  failed_rows:
                    type: integer
                    description: Number of rows that failed validation
                    example: 2
        '400':
          description: Bad Request - Invalid input or file.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Invalid file format.
        '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.
        '500':
          description: Internal Server Error.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: An unexpected error occurred. Please try again later.

````

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