Batch upsert objects
Upsert up to 1000 custom objects in one request. Idempotent and safely retryable. By DEFAULT each item REPLACES that object’s entire attributes blob, so an item carrying only the fields you want to change DELETES every other attribute on that object. To add or change a subset across many objects, pass mode: 'merge' — it overlays the keys you send and leaves the rest untouched, with no need to read each object first. Pass createMissing: false to update only objects that already exist; anything unmatched comes back in skipped rather than being created.
curl --request POST \
--url https://www.useboom.ai/api/v1/cdp/custom-objects/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"items": [
{
"type": "<string>",
"externalId": "<string>",
"displayName": "<string>",
"attributes": {}
}
],
"mode": "replace",
"createMissing": true
}
'import requests
url = "https://www.useboom.ai/api/v1/cdp/custom-objects/batch"
payload = {
"items": [
{
"type": "<string>",
"externalId": "<string>",
"displayName": "<string>",
"attributes": {}
}
],
"mode": "replace",
"createMissing": True
}
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: [
{
type: '<string>',
externalId: '<string>',
displayName: '<string>',
attributes: {}
}
],
mode: 'replace',
createMissing: true
})
};
fetch('https://www.useboom.ai/api/v1/cdp/custom-objects/batch', 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://www.useboom.ai/api/v1/cdp/custom-objects/batch",
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' => [
[
'type' => '<string>',
'externalId' => '<string>',
'displayName' => '<string>',
'attributes' => [
]
]
],
'mode' => 'replace',
'createMissing' => true
]),
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://www.useboom.ai/api/v1/cdp/custom-objects/batch"
payload := strings.NewReader("{\n \"items\": [\n {\n \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\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://www.useboom.ai/api/v1/cdp/custom-objects/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.useboom.ai/api/v1/cdp/custom-objects/batch")
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 \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\n}"
response = http.request(request)
puts response.read_body{
"summary": {
"total": 0,
"created": 0,
"updated": 0,
"failed": 0,
"skipped": 0
},
"errors": [
{
"index": 0,
"error": {
"code": "<string>",
"message": "<string>"
},
"externalId": "<string>"
}
],
"skipped": [
"<string>"
]
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Authorizations
Organization API key, sent as Authorization: Bearer boom_org_....
Body
Custom objects to upsert.
1 - 1000 elementsShow child attributes
Show child attributes
How attributes is applied. 'replace' (default) swaps the whole blob — any stored attribute you leave out is DELETED. 'merge' overlays the keys you send onto the stored ones and leaves the rest untouched, which is what you want when adding or changing a subset.
replace, merge When false, objects that do not already exist are skipped and reported in skipped instead of being created. Use it when working from a list that may not match, so a bad id enriches nothing rather than inventing an object.
Was this page helpful?
curl --request POST \
--url https://www.useboom.ai/api/v1/cdp/custom-objects/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"items": [
{
"type": "<string>",
"externalId": "<string>",
"displayName": "<string>",
"attributes": {}
}
],
"mode": "replace",
"createMissing": true
}
'import requests
url = "https://www.useboom.ai/api/v1/cdp/custom-objects/batch"
payload = {
"items": [
{
"type": "<string>",
"externalId": "<string>",
"displayName": "<string>",
"attributes": {}
}
],
"mode": "replace",
"createMissing": True
}
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: [
{
type: '<string>',
externalId: '<string>',
displayName: '<string>',
attributes: {}
}
],
mode: 'replace',
createMissing: true
})
};
fetch('https://www.useboom.ai/api/v1/cdp/custom-objects/batch', 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://www.useboom.ai/api/v1/cdp/custom-objects/batch",
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' => [
[
'type' => '<string>',
'externalId' => '<string>',
'displayName' => '<string>',
'attributes' => [
]
]
],
'mode' => 'replace',
'createMissing' => true
]),
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://www.useboom.ai/api/v1/cdp/custom-objects/batch"
payload := strings.NewReader("{\n \"items\": [\n {\n \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\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://www.useboom.ai/api/v1/cdp/custom-objects/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.useboom.ai/api/v1/cdp/custom-objects/batch")
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 \"type\": \"<string>\",\n \"externalId\": \"<string>\",\n \"displayName\": \"<string>\",\n \"attributes\": {}\n }\n ],\n \"mode\": \"replace\",\n \"createMissing\": true\n}"
response = http.request(request)
puts response.read_body{
"summary": {
"total": 0,
"created": 0,
"updated": 0,
"failed": 0,
"skipped": 0
},
"errors": [
{
"index": 0,
"error": {
"code": "<string>",
"message": "<string>"
},
"externalId": "<string>"
}
],
"skipped": [
"<string>"
]
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}