---
title: "Import CRM contacts in bulk"
url: "https://docs.signnow.com/docs/contacts/operations/post-v2-crm-contacts-import"
type: "endpoint"
section: "contacts"
slug: "contacts/operations/post-v2-crm-contacts-import"
method: "POST"
path: "/v2/crm/contacts/import"
operation_id: "post-v2-crm-contacts-import"
authorization: "bearer"
---

# Import CRM contacts in bulk

`POST /v2/crm/contacts/import`

This endpoint allows users to import contacts from a CSV file into the authenticated user account. Users can map CSV columns to contact fields and configure how duplicate contacts are handled.

**Notes:**
* The CSV file must contain a header row. Data rows start from line 2.
* Rows where the email value is missing or invalid are skipped and reported under `failed`.
* Rows with invalid non-email fields (phone, address, etc.) are still created with those fields set to `null` and reported as `created_partial`.
* CSV separator is auto-detected from the header row (supported: `,`, `;`, `\t`, `|`).
* Phone country codes are auto-detected from the phone number format (e.g., `+1` → `US`, `+44` → `GB`).
* If `duplicates` is not specified and duplicate contacts (by email) already exist, a `409 Conflict` is returned.

**Sample CSV**

```csv
First Name,Last Name,Email,Phone,Company Name,Job Title,Country,Street Address,Apartment,City,State,ZIP Code,Description
John,Smith,john@example.com,5551234567,Sample Company,Manager,US,17 Station St,Suite 101,Brookline,Massachusetts,02445,This is a sample contact to demonstrate how the columns should be filled out. Don't forget to remove this contact before importing your contacts.
```

> Values in `mapping[...]` must exactly match the column headers in your CSV (case-sensitive, including spaces and punctuation). Set an optional `mapping[...]` to `null` to skip a field.


## Authorization

bearer

## Form Data Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `file` | string | Yes | CSV file to import. Maximum size: 5 MB. Maximum rows: 3000 (excluding header). |
| `duplicates` | string | No | Duplicate handling strategy. Allowed values: `skip`, `replace`. If omitted, the request returns `409 Conflict` when contacts with matching emails already exist. |
| `mapping[email]` | string | Yes | Maps the contact email to a CSV column. The value is the column header name in your CSV. Required. Email values in the column must be valid and cannot end with `@no.reply`. Example value: `Email`. |
| `mapping[first_name]` | string | No | Maps the contact first name to a CSV column. The value is the column header name. Maximum 128 characters. Example value: `First Name`. |
| `mapping[last_name]` | string | No | Maps the contact last name to a CSV column. The value is the column header name. Maximum 128 characters. Example value: `Last Name`. |
| `mapping[description]` | string | No | Maps the contact description to a CSV column. The value is the column header name. Maximum 408 characters. Example value: `Description`. |
| `mapping[phone]` | string | No | Maps the contact phone number to a CSV column. The value is the column header name. Phone values must contain 10–15 digits; country code is auto-detected from the format. Example value: `Phone`. |
| `mapping[company][name]` | string | No | Maps the company name to a CSV column. The value is the column header name. Maximum 128 characters. Example value: `Company Name`. |
| `mapping[company][job_title]` | string | No | Maps the contact job title to a CSV column. The value is the column header name. Maximum 128 characters. Example value: `Job Title`. |
| `mapping[address][country]` | string | No | Maps the contact country to a CSV column. The value is the column header name. Country values must use ISO 2-character codes. Required when `mapping[address][zip_code]` is provided. Example value: `Country`. |
| `mapping[address][street]` | string | No | Maps the street address to a CSV column. The value is the column header name. Maximum 255 characters. Example value: `Street Address`. |
| `mapping[address][apartment]` | string | No | Maps the apartment / unit to a CSV column. The value is the column header name. Maximum 255 characters. Example value: `Apartment`. |
| `mapping[address][city]` | string | No | Maps the city to a CSV column. The value is the column header name. Maximum 128 characters. Example value: `City`. |
| `mapping[address][state]` | string | No | Maps the state to a CSV column. The value is the column header name. United States only. Maximum 128 characters. Example value: `State`. |
| `mapping[address][zip_code]` | string | No | Maps the zip code to a CSV column. The value is the column header name. Maximum 10 characters. Requires `mapping[address][country]` to be provided. Example value: `ZIP Code`. |

## Responses

### 201

Contacts imported successfully.

**Example** (`Import succeeded`)

```json
{
  "data": {
    "failed": {
      "rows": [
        5,
        12,
        27
      ],
      "count": 3
    },
    "created": 45,
    "created_partial": {
      "rows": [
        8,
        19
      ],
      "count": 2
    }
  }
}
```

### 400

* Missing or incorrect bearer token.
* Incorrect `mapping` type.
* The `mapping` is empty.
* The `file` is missing or larger than 5 MB.
* Incorrect `file` type.
* Incorrect file extension.

**Example** (`Incorrect `file` type`)

```json
{
  "errors": [
    {
      "code": 27405153,
      "message": "The `file` type is invalid."
    }
  ]
}
```

**Example** (`The `mapping` is empty`)

```json
{
  "errors": [
    {
      "code": 27405149,
      "message": "The `mapping` value can not be empty."
    }
  ]
}
```

**Example** (`Incorrect `mapping` type`)

```json
{
  "errors": [
    {
      "code": 27405148,
      "message": "The `mapping` should be of type array."
    }
  ]
}
```

**Example** (`Incorrect file extension`)

```json
{
  "errors": [
    {
      "code": 27405155,
      "message": "The allowed file extension is .csv."
    }
  ]
}
```

**Example** (`Missing or incorrect bearer token`)

```json
{
  "errors": [
    {
      "code": 1537,
      "message": "invalid_token"
    }
  ]
}
```

**Example** (`The `file` is missing or larger than 5 MB`)

```json
{
  "errors": [
    {
      "code": 27405152,
      "message": "The `file` is required and maximum allowed file size is 5 MB."
    }
  ]
}
```

### 409

Returned when the `duplicates` parameter is not set and contacts with matching emails already exist.

**Example** (`Duplicate contacts found`)

```json
{
  "errors": [
    {
      "code": 27405161,
      "message": "Duplicate contacts found"
    }
  ]
}
```

### 422

* Incorrect `mapping` value.
* Incorrect `duplicates` value.
* The `file` exceeds 5 MB.
* The `file` exceeds 3000 lines.
* The `file` is empty.
* The email column is missing in the file.
* Some mapping columns are missing in the file.
* Unable to import contacts.

**Example** (`The `file` is empty`)

```json
{
  "errors": [
    {
      "code": 27405157,
      "message": "File can not be empty"
    }
  ]
}
```

**Example** (`The `file` exceeds 5 MB`)

```json
{
  "errors": [
    {
      "code": 27405154,
      "message": "The maximum allowed file size is 5 MB"
    }
  ]
}
```

**Example** (`Incorrect `mapping` value`)

```json
{
  "errors": [
    {
      "code": 27405150,
      "message": "The `mapping` value is invalid"
    }
  ]
}
```

**Example** (`Unable to import contacts`)

```json
{
  "errors": [
    {
      "code": 27405160,
      "message": "Unable to import contacts. Please, try again later"
    }
  ]
}
```

**Example** (`Incorrect `duplicates` value`)

```json
{
  "errors": [
    {
      "code": 27405151,
      "message": "Duplicates should be [\"skip\", \"replace\"]"
    }
  ]
}
```

**Example** (`The `file` exceeds 3000 lines`)

```json
{
  "errors": [
    {
      "code": 27405156,
      "message": "The maximum allowed file size is 3000 lines"
    }
  ]
}
```

**Example** (`The email column is missing in the file`)

```json
{
  "errors": [
    {
      "code": 27405158,
      "message": "Column with email is required"
    }
  ]
}
```

**Example** (`Some mapping columns are missing in the file`)

```json
{
  "errors": [
    {
      "code": 27405159,
      "message": "Columns from mapping are missed in file"
    }
  ]
}
```

## Code Examples

> Replace `$SIGNNOW_ACCESS_TOKEN` and any `{placeholder}` values before running.

### cURL

```bash
curl -X POST \
  "https://api.signnow.com/v2/crm/contacts/import" \
  -H "Authorization: Bearer $SIGNNOW_ACCESS_TOKEN" \
  -H "Content-Type: application/json"
```

---
*Full reference: https://docs.signnow.com/docs/contacts/operations/post-v2-crm-contacts-import*
