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

# Upload contact list

> Upload a CSV file as a new contact list of a campaign

# Upload contact list

Uploads a CSV file as a new contact list of the campaign — the same as **Add list** in the dashboard. The file is validated right away and imported in the background; use the returned `file_data_id` to follow the import with [Get list import progress](https://docs.talkover.ai/api-reference/endpoints/get-campaign-list-progress).

## Endpoint

```
POST /api/v1/campaigns/{campaign_id}/files
```

## Path parameters

**campaign\_id** `string` *required*

Campaign UUID.

## Request headers

**Authorization** `string` *required*

Bearer token. Format: `Bearer talq_your_environment_token_here`

**Content-Type** `string` *required*

`multipart/form-data`

## Request body

**file** `file` *required*

CSV file (`.csv` or `.txt`). Up to **20,000 rows** and **25 MB**.

## File format

* The file must have a **`to`** column with the phone numbers. In the dashboard the column mapping renames your phone column to `to`; over the API nothing renames it, so send the header as `to`.
* Every other column becomes a variable of the contact, under the header exactly as written: a `Nome` column is `{Nome}` in the agent prompt.
* An optional `source` column tags each contact (defaults to `CSV`). An optional `allow_duplicates` column lets a row in even when the number is already pending in the campaign.
* Numbers on the campaign's do-not-call list, numbers already pending and numbers still in their cooldown are skipped during the import.
* **Debt collection environments** need a phone column (`to`, `phone` or `phone_1`, `phone_2`…) and a document column (`document`, `cpf`, `cnpj`…).

## Examples

```bash theme={null}
curl -X POST "https://app.talkover.ai/api/v1/campaigns/campaign-uuid/files" \
  -H "Authorization: Bearer talq_your_environment_token_here" \
  -F "file=@mailing-2026-11-04.csv"
```

## Response

`202 Accepted` — the list was stored and its import is queued.

```json theme={null}
{
  "success": true,
  "data": {
    "file_data_id": "list-uuid",
    "status": "processing",
    "row_count": 18342,
    "warnings": []
  },
  "message": "File uploaded successfully. Processing in background."
}
```

`warnings` lists columns with empty values (blank, `-`, `N/A`…). They never block the upload.

## Error responses

### 422 — Invalid file

The file was refused and nothing was imported: no `to` column, more than 20,000 rows, empty file, not a CSV, or over 25 MB.

```json theme={null}
{
  "success": false,
  "message": "CSV file must contain a 'to' column with phone numbers",
  "errors": ["CSV file must contain a 'to' column with phone numbers"]
}
```

### 404 — Campaign not found

The campaign does not exist or belongs to another environment.


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