curl --request POST \
--url https://{subdomain}.conveyour.com/api/custom/records/add \
--header 'Content-Type: application/json' \
--header 'x-conveyour-token: <api-key>' \
--data '
[
{
"external_id": "<string>",
"obj_id": "<string>"
}
]
'const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify([{external_id: '<string>', obj_id: '<string>'}])
};
fetch('https://{subdomain}.conveyour.com/api/custom/records/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify([{external_id: '<string>', obj_id: '<string>'}])
};
fetch('https://{subdomain}.conveyour.com/api/custom/records/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{subdomain}.conveyour.com/api/custom/records/add"
payload = [
{
"external_id": "<string>",
"obj_id": "<string>"
}
]
headers = {
"x-conveyour-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.conveyour.com/api/custom/records/add",
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([
[
'external_id' => '<string>',
'obj_id' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-conveyour-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "ok",
"message": "2 Records processed",
"data": [
{
"external_id": "vin-123",
"status": "created"
},
{
"external_id": "vin-456",
"status": "updated"
}
]
}{
"status": "failed",
"message": "Lacking necessary permission add_contacts",
"data": {
"permission": "add_contacts"
}
}{
"status": "failed",
"message": "<string>"
}Bulk create records
Creates or updates multiple records at once (bulk upsert). The request body is a raw JSON array of flat record objects — not wrapped in an object. Maximum 100 records per call. Records are upserted by external_id. external_id is required on every record in the batch. A record without it is rejected with { "external_id": "MISSING", "status": "error", "errors": ["Missing required external_id"] } — the rest of the batch still processes.
Bulk create/upsert records (raw array body, max 100)
Permission: Requires manage_custom_objects or manage_custom_records. Denials read Manage Custom Records.
Sending anything other than a top-level JSON array returns Records input is not a JSON array — with HTTP 200, so check status. Exceeding 100 records returns HTTP 429 with Currently supporting a maximum of 100 records per add request.
curl --request POST \
--url https://{subdomain}.conveyour.com/api/custom/records/add \
--header 'Content-Type: application/json' \
--header 'x-conveyour-token: <api-key>' \
--data '
[
{
"external_id": "<string>",
"obj_id": "<string>"
}
]
'const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify([{external_id: '<string>', obj_id: '<string>'}])
};
fetch('https://{subdomain}.conveyour.com/api/custom/records/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {'x-conveyour-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify([{external_id: '<string>', obj_id: '<string>'}])
};
fetch('https://{subdomain}.conveyour.com/api/custom/records/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{subdomain}.conveyour.com/api/custom/records/add"
payload = [
{
"external_id": "<string>",
"obj_id": "<string>"
}
]
headers = {
"x-conveyour-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.conveyour.com/api/custom/records/add",
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([
[
'external_id' => '<string>',
'obj_id' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-conveyour-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"status": "ok",
"message": "2 Records processed",
"data": [
{
"external_id": "vin-123",
"status": "created"
},
{
"external_id": "vin-456",
"status": "updated"
}
]
}{
"status": "failed",
"message": "Lacking necessary permission add_contacts",
"data": {
"permission": "add_contacts"
}
}{
"status": "failed",
"message": "<string>"
}Authorizations
Your API key token. Contacts endpoints require a Server-only — Full API key — see Authentication.
Query Parameters
The ID of the Custom Object type to scope these records to. Can also be passed in each record object as obj_id.
Team scope for the request, as one or more team ObjectIds. The brackets are required: PHP keeps only the last value for a repeated plain key, so teams=A&teams=B silently resolves to B alone. On requests with a JSON body you may send teams (no brackets) in the body instead.
Values that are not valid ObjectIds are silently ignored — a mistyped team ID behaves as if no team was sent. See the teams section of the API conventions guide.
Body
Response
Success.
The common response envelope shared by all ConveYour endpoints.