---
title: "Import Contacts"
method: POST
path: "/v1/contacts/bulk"
tags: ["contacts"]
---

# Import Contacts

`POST /v1/contacts/bulk`

## Request

- Base URL: `https://api.elaan.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.elaan.io/v1/contacts/bulk`
- Auth: none declared

Create or update up to 500 contacts in one call, matched by `external_id`.

Returns **200 with a per-row report**, not 201: a batch is rarely all one
thing, and a status code cannot say "4,997 created, 3 rejected". Each row
reports created, updated or failed with a reason, so a client can show the
user exactly which lines of their file need fixing.

A field omitted from a row is left as it was; a field sent empty is cleared.
That is what makes an `external_id,email` file safe to import over contacts
that already carry phones and attributes.

## Headers

- `authorization` string, nullable

## Request body

- ImportContactsRequest: A batch of rows to create or update, keyed by `external_id`.
  - `contacts` ContactImportRowRequest[], required: Up to 500 rows. Each is matched to an existing contact by `external_id` and updated, or created if there is none. A field you omit is left as it was; a field you send empty is cleared.
    - `external_id` string, required
    - `emails` string[], nullable
    - `phones` string[], nullable
    - `attributes` object, nullable
    - `language` string, nullable

## Response `200`

Successful Response

- ImportContactsResponse: Per-row outcomes for the batch. A row-level problem (a malformed address, a blank id, the same `external_id` twice) is reported here while every other row still imports. A malformed request *shape* is not: a value of the wrong JSON type, or an unexpected key, is rejected before any row is read and returns 422 for the whole batch. What is checked per row is the content of the strings.
  - `created` integer, required
  - `updated` integer, required
  - `failed` integer, required
  - `rows` ImportRowResultResponse[], required
    - `index` integer, required: The row's position in the submitted `contacts` array, so a client can point at the line of the file the user uploaded.
    - `external_id` string, required
    - `outcome` 'created' | 'updated' | 'failed', required
    - `error` string, nullable: Why the row failed. Null unless outcome is failed.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/elaan/apis/elaan-api.md) · [All operations](https://skmtc.dev/elaan/apis/elaan-api/llms.txt) · [OpenAPI document](https://skmtc.dev/elaan/apis/elaan-api/revisions/c96a7e6399aa?raw)
