curl --request POST \
--url https://api.reply.io/v3/contacts/import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"items": [
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"company": "Acme"
},
{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Smith",
"company": "Globex"
}
],
"options": {
"overwriteExisting": false,
"skipExisting": true,
"detectTimeZone": true,
"listIds": [
10,
20
]
}
}
'import requests
url = "https://api.reply.io/v3/contacts/import"
payload = {
"items": [
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"company": "Acme"
},
{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Smith",
"company": "Globex"
}
],
"options": {
"overwriteExisting": False,
"skipExisting": True,
"detectTimeZone": True,
"listIds": [10, 20]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: [
{email: 'john@example.com', firstName: 'John', lastName: 'Doe', company: 'Acme'},
{
email: 'jane@example.com',
firstName: 'Jane',
lastName: 'Smith',
company: 'Globex'
}
],
options: {
overwriteExisting: false,
skipExisting: true,
detectTimeZone: true,
listIds: [10, 20]
}
})
};
fetch('https://api.reply.io/v3/contacts/import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reply.io/v3/contacts/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'items' => [
[
'email' => 'john@example.com',
'firstName' => 'John',
'lastName' => 'Doe',
'company' => 'Acme'
],
[
'email' => 'jane@example.com',
'firstName' => 'Jane',
'lastName' => 'Smith',
'company' => 'Globex'
]
],
'options' => [
'overwriteExisting' => false,
'skipExisting' => true,
'detectTimeZone' => true,
'listIds' => [
10,
20
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reply.io/v3/contacts/import"
payload := strings.NewReader("{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.reply.io/v3/contacts/import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/contacts/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"id": 12345,
"status": "created",
"error": null
},
{
"id": 12346,
"status": "updated",
"error": null
},
{
"id": null,
"status": "failed",
"error": "Email is required"
}
],
"added": 1,
"updated": 1,
"skipped": 0,
"failed": 1
}Import contacts
contacts:write scope (or a broader one that includes it).
Use this endpoint when you need to add or update many contacts in one call — for example when syncing contacts from another system. Each item uses the same fields as the contact update model. Use options to control deduplication, list assignment, and other import behavior: which keys identify an existing contact (email plus any of LinkedIn URL, phone, name, company, or custom fields), whether matched contacts are overwritten or skipped, whether previously deleted contacts are restored, and which lists or sequence the imported contacts are added to. The response reports how many contacts were added, updated, skipped, or failed, with a per-item outcome.
curl --request POST \
--url https://api.reply.io/v3/contacts/import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"items": [
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"company": "Acme"
},
{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Smith",
"company": "Globex"
}
],
"options": {
"overwriteExisting": false,
"skipExisting": true,
"detectTimeZone": true,
"listIds": [
10,
20
]
}
}
'import requests
url = "https://api.reply.io/v3/contacts/import"
payload = {
"items": [
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"company": "Acme"
},
{
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Smith",
"company": "Globex"
}
],
"options": {
"overwriteExisting": False,
"skipExisting": True,
"detectTimeZone": True,
"listIds": [10, 20]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: [
{email: 'john@example.com', firstName: 'John', lastName: 'Doe', company: 'Acme'},
{
email: 'jane@example.com',
firstName: 'Jane',
lastName: 'Smith',
company: 'Globex'
}
],
options: {
overwriteExisting: false,
skipExisting: true,
detectTimeZone: true,
listIds: [10, 20]
}
})
};
fetch('https://api.reply.io/v3/contacts/import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reply.io/v3/contacts/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'items' => [
[
'email' => 'john@example.com',
'firstName' => 'John',
'lastName' => 'Doe',
'company' => 'Acme'
],
[
'email' => 'jane@example.com',
'firstName' => 'Jane',
'lastName' => 'Smith',
'company' => 'Globex'
]
],
'options' => [
'overwriteExisting' => false,
'skipExisting' => true,
'detectTimeZone' => true,
'listIds' => [
10,
20
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reply.io/v3/contacts/import"
payload := strings.NewReader("{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.reply.io/v3/contacts/import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/contacts/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n {\n \"email\": \"john@example.com\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"company\": \"Acme\"\n },\n {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"company\": \"Globex\"\n }\n ],\n \"options\": {\n \"overwriteExisting\": false,\n \"skipExisting\": true,\n \"detectTimeZone\": true,\n \"listIds\": [\n 10,\n 20\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"id": 12345,
"status": "created",
"error": null
},
{
"id": 12346,
"status": "updated",
"error": null
},
{
"id": null,
"status": "failed",
"error": "Email is required"
}
],
"added": 1,
"updated": 1,
"skipped": 0,
"failed": 1
}Authorizations
Authenticate every request with a Bearer token. Pass your Reply API key in the
Authorization header:
Authorization: Bearer <your-api-key>
Get your API key from the Reply dashboard: Settings → API Key.
Body
Import contacts by providing an array of contact objects with optional import settings
Response
Contacts import processed successfully
Summary of a processed contacts import request with per-item results