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

# Upload Recipients

> Stage a recipient CSV and get the asset id that creating an audience needs 📤

## Endpoint

```json theme={null}
POST https://api.connectly.ai/v1/businesses/{businessId}/upload/audience_csv
```

| Parameter    | Location | Description                 |
| ------------ | -------- | --------------------------- |
| `businessId` | Path     | Your Connectly business ID. |
| `X-API-Key`  | Header   | Your API key.               |

This is the first of the two calls that store a list. It stages the file and returns an asset id; [Create an audience](https://docs.connectly.ai/audiences/manage-audiences) then turns that id into a reusable audience.

<Note>
  This endpoint takes `multipart/form-data`, not JSON, so it is the one call in this API you cannot build from the OpenAPI schema.
</Note>

## Request

Send the CSV as multipart form data under the field name `file`.

| Field  | Required | Description                                      |
| ------ | -------- | ------------------------------------------------ |
| `file` | Yes      | The recipient CSV. Maximum 100MB, UTF-8 encoded. |

```bash theme={null}
curl -X POST \
  'https://api.connectly.ai/v1/businesses/{businessId}/upload/audience_csv' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -F 'file=@recipients.csv;type=text/csv'
```

The file must parse as a CSV and at least one field in the first 50 rows must look like a recipient — an E.164 phone number or a BSUID. A file that parses but names nobody is rejected, so this endpoint cannot be used as general file storage.

## Response

```json theme={null}
{
  "entity": {
    "id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
    "ownerId": "2d503e81-e270-4467-a05f-21a900efbbc1",
    "source": { "channelType": "CHANNEL_TYPE_CONNECTLY" },
    "metadata": { "accessControlType": "ASSET_ACCESS_CONTROL_TYPE_PRIVATE" },
    "filename": "recipients.csv"
  }
}
```

Pass `entity.id` as `csvAssetId` when you create the audience.

<Note>
  The file is stored privately. It is not published to a CDN and is not reachable without your credentials — which is why recipient lists go through this route rather than the general asset upload.
</Note>

## Errors

| Status | Cause                                                                                                                                                |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The upload is not multipart, the `file` field is missing, the file does not parse as a CSV, or no field in the first 50 rows looks like a recipient. |
| `400`  | The file is larger than 100MB.                                                                                                                       |
| `401`  | Missing or invalid API key.                                                                                                                          |
| `429`  | More than 60 uploads in a minute.                                                                                                                    |

## Next step

<Card title="Create an audience" icon="list" href="https://docs.connectly.ai/audiences/manage-audiences">
  Turn the asset id into a stored, reusable recipient list.
</Card>
