Bulk update accounts, contacts, or opportunities
Updates up to 50 existing objects. The request body is keyed by object UUID, and each value is a patch object of field names to updated values. Field names can be either the names the read endpoints return (for example name, industry, first_name, stage_id, amount, close_date, next_steps) or the underlying property_name (company_name, people_first_name, opportunity_stage, opportunity_deal_size, opportunity_close_date, opportunity_next_step); see BulkUpdateInput for the full mapping. Custom fields are keyed by their property_name from custom_field_definitions. Sending both names for the same field in one item is rejected. Each item succeeds or fails on its own: the response lists one result per id with success, statusCode and, on failure, a message naming the rejected field and why. The top-level status is 200 when every item succeeded, 207 when some did, and 422 when none did. For opportunity relationship fields, opportunity_account, opportunity_contact, and opportunity_other_stakeholders use replace semantics: supplying the field clears the existing mapping of that type, then writes the supplied UUID or UUID list. Use null to clear opportunity_account or opportunity_contact; use null or [] to clear opportunity_other_stakeholders. Every supplied account or contact UUID must belong to an existing record in the workspace; an unknown UUID fails that item with 404 and nothing is written for it.
curl --request PATCH \
--url https://api.octolane.com/v1/{object_type}/bulk \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"018f13b3-8239-7ef8-a8f1-93ad10b76110": {
"name": "Acme Enterprise"
}
}
'import requests
url = "https://api.octolane.com/v1/{object_type}/bulk"
payload = { "018f13b3-8239-7ef8-a8f1-93ad10b76110": { "name": "Acme Enterprise" } }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({'018f13b3-8239-7ef8-a8f1-93ad10b76110': {name: 'Acme Enterprise'}})
};
fetch('https://api.octolane.com/v1/{object_type}/bulk', 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.octolane.com/v1/{object_type}/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'018f13b3-8239-7ef8-a8f1-93ad10b76110' => [
'name' => 'Acme Enterprise'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.octolane.com/v1/{object_type}/bulk"
payload := strings.NewReader("{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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.patch("https://api.octolane.com/v1/{object_type}/bulk")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.octolane.com/v1/{object_type}/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"data": "<unknown>"
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}Authorizations
Personal API key. Requests act as the workspace member who created the key, with that member's current access, and stop working when the key is disabled or its creator leaves the workspace.
Path Parameters
Object collection to update.
accounts, contacts, opportunities Body
Object keyed by target object UUID. Maximum 50 keys.
Bulk update payload keyed by object UUID. Accepted field names, read-API name → property_name. Accounts: name→company_name, domain→company_domain, industry→company_industry, description→company_description, founded→company_founded, linkedin→company_linkedin, twitter→company_twitter, twitter_followers→company_twitter_followers, primary_location→company_primary_location, estimated_revenue→company_estimated_revenue, total_fund_raised→company_total_fund_raised, employee_range→company_employee_range, type→company_type. Contacts: name→people_name (split into first and last name), first_name→people_first_name, last_name→people_last_name, account_id→people_account, job_title→people_job_title, seniority→people_seniority, linkedin→people_linkedin, twitter→people_twitter, phone→people_phone, current_company→people_current_company, other_emails→people_other_emails, type→people_type. Opportunities: name→opportunity_name, stage_id→opportunity_stage (moves the opportunity to that stage's pipeline; pipeline_id itself is not writable), amount→opportunity_deal_size (JSON number), probability→opportunity_probability (JSON number), close_date→opportunity_close_date and next_action_date→opportunity_next_action_date (ISO 8601 string or Unix timestamp in seconds or milliseconds), next_steps→opportunity_next_step, owner_id→opportunity_owner, account_id→opportunity_account, contact_id→opportunity_contact, additional_contacts→opportunity_other_stakeholders. Read-only and rejected with a message: ids, interaction timestamps, account logo and tags, and contact email, email_verified and avatar_url. For opportunities, relationship updates are expressed with system field names: opportunity_account for the associated account UUID, opportunity_contact for the primary contact UUID, and opportunity_other_stakeholders for the complete replacement list of additional contact UUIDs. These relationship fields replace the existing mapping for that field instead of appending.
Patch object. For opportunity relationship fields, pass UUID strings for opportunity_account and opportunity_contact, and an array of contact UUID strings for opportunity_other_stakeholders.
Show child attributes
Show child attributes
Was this page helpful?
curl --request PATCH \
--url https://api.octolane.com/v1/{object_type}/bulk \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"018f13b3-8239-7ef8-a8f1-93ad10b76110": {
"name": "Acme Enterprise"
}
}
'import requests
url = "https://api.octolane.com/v1/{object_type}/bulk"
payload = { "018f13b3-8239-7ef8-a8f1-93ad10b76110": { "name": "Acme Enterprise" } }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({'018f13b3-8239-7ef8-a8f1-93ad10b76110': {name: 'Acme Enterprise'}})
};
fetch('https://api.octolane.com/v1/{object_type}/bulk', 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.octolane.com/v1/{object_type}/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'018f13b3-8239-7ef8-a8f1-93ad10b76110' => [
'name' => 'Acme Enterprise'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.octolane.com/v1/{object_type}/bulk"
payload := strings.NewReader("{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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.patch("https://api.octolane.com/v1/{object_type}/bulk")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.octolane.com/v1/{object_type}/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"018f13b3-8239-7ef8-a8f1-93ad10b76110\": {\n \"name\": \"Acme Enterprise\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"data": "<unknown>"
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}{
"success": false,
"message": "Validation failed",
"statusCode": 400
}