Records
Patch a CRM Record
Update a CRM record by ID via the Zeeg CRM API by sending only the attributes to change; every other field on the record stays untouched.
PATCH
/
crm
/
{objectSlug}
/
{recordId}
Patch a CRM record
curl --request PATCH \
--url https://api.zeeg.me/v2/crm/{objectSlug}/{recordId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"price": 35,
"inventory_count": 80
}
'import requests
url = "https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}"
payload = {
"price": 35,
"inventory_count": 80
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({price: 35, inventory_count: 80})
};
fetch('https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}', 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.zeeg.me/v2/crm/{objectSlug}/{recordId}",
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([
'price' => 35,
'inventory_count' => 80
]),
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.zeeg.me/v2/crm/{objectSlug}/{recordId}"
payload := strings.NewReader("{\n \"price\": 35,\n \"inventory_count\": 80\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"price\": 35,\n \"inventory_count\": 80\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"price\": 35,\n \"inventory_count\": 80\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 200,
"record": {
"id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
"objectSlug": "products",
"attributes": {
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
},
"createdAt": "2025-06-01T10:00:00+00:00",
"updatedAt": "2025-06-01T12:00:00+00:00"
}
}{
"message": "Unauthenticated."
}{
"error": {
"type": "insufficient_scope",
"message": "Your token is missing the required scope: crm:write.",
"error_id": "91ddae71-bb75-4a2a-a0aa-b11dffd1f17b",
"required_scopes": [
"crm:write"
]
}
}{
"success": true,
"message": "<string>",
"status": 123
}{
"message": "The given data was invalid.",
"errors": {
"field_name": [
"The field_name field is required."
]
}
}Partially updates a CRM record. Only the attributes you include in the request body are changed — all other attributes remain exactly as they are.
This updates
Use PATCH when you have the record ID and only want to update certain fields. Use Assert when syncing from an external source or when you don’t have the ID yet.
Response returns the full updated record with all attributes, including the unchanged ones.
Path parameters
| Parameter | Type | Description |
|---|---|---|
objectSlug | string | The slug of the custom CRM object the record belongs to. |
recordId | string (UUID) | The UUID of the record to update. |
Request body
A flat JSON object containing only the attribute slug → value pairs you want to change. Attributes not present in the body are untouched.{
"price": 49,
"in_stock": false
}
price and in_stock only. Every other attribute on the record keeps its current value.
PATCH vs. Assert
PATCH /{objectSlug}/{recordId} | PUT /{objectSlug}?matchingAttribute=... | |
|---|---|---|
| Lookup | By record id | By attribute value |
| Scope | Only provided attributes change | Full body applied (omitted attrs → null on create) |
| Use case | Edit a known record’s specific fields | Sync/upsert from an external system |
Attribute types
The same type rules apply as when creating a record:| Type | Expected value | Example |
|---|---|---|
text | String, max 255 characters | "Updated name" |
number | Integer | 49 |
checkbox | Boolean | false |
date | ISO 8601 date string | "2025-12-31" |
select | Object with an id key | { "id": "opt_abc123" } |
multiselect | Array of option objects | [{ "id": "opt_abc" }] |
relation | Array of related record UUIDs | ["uuid-1", "uuid-2"] |
user | Array of organization member UUIDs | ["member-uuid-1"] |
For
relation and user attributes, PATCH replaces the entire array. To add or remove individual IDs without overwriting the full list, use Update Relation instead.Clearing a value
To explicitly clear an attribute, passnull:
{
"launched_at": null
}
Example: update price and stock status
PATCH /v2/crm/products/c1d2e3f4-a5b6-7890-cdef-123456789012
{
"price": 49,
"inventory_count": 0,
"in_stock": false
}
When to use this endpoint
- Edit forms — a user edits one or a few fields and saves.
- Status updates — flip a single boolean or enum field without touching anything else.
- Partial enrichment — backfill a specific attribute after you’ve gathered more data.
Authorizations
Path Parameters
Slug of the custom CRM object.
UUID of the record to update.
Body
application/json
Flat object of attribute slug → value pairs to update.
Response
OK
Example:
true
Example:
200
A record for a custom CRM object.
Hide child attributes
Hide child attributes
Unique identifier for the record.
Example:
"c1d2e3f4-a5b6-7890-cdef-123456789012"
Slug of the CRM object this record belongs to.
Example:
"products"
Key/value pairs for the custom attributes defined on the object. Keys are attribute slugs.
Example:
{ "sku": "DRESS-001", "price": 29, "inventory_count": 150 }
ISO 8601 timestamp when the record was created.
Example:
"2025-06-01T10:00:00+00:00"
ISO 8601 timestamp when the record was last updated.
Example:
"2025-06-01T12:00:00+00:00"
Last modified on June 11, 2026
⌘I
Patch a CRM record
curl --request PATCH \
--url https://api.zeeg.me/v2/crm/{objectSlug}/{recordId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"price": 35,
"inventory_count": 80
}
'import requests
url = "https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}"
payload = {
"price": 35,
"inventory_count": 80
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({price: 35, inventory_count: 80})
};
fetch('https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}', 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.zeeg.me/v2/crm/{objectSlug}/{recordId}",
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([
'price' => 35,
'inventory_count' => 80
]),
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.zeeg.me/v2/crm/{objectSlug}/{recordId}"
payload := strings.NewReader("{\n \"price\": 35,\n \"inventory_count\": 80\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"price\": 35,\n \"inventory_count\": 80\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeeg.me/v2/crm/{objectSlug}/{recordId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"price\": 35,\n \"inventory_count\": 80\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 200,
"record": {
"id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
"objectSlug": "products",
"attributes": {
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
},
"createdAt": "2025-06-01T10:00:00+00:00",
"updatedAt": "2025-06-01T12:00:00+00:00"
}
}{
"message": "Unauthenticated."
}{
"error": {
"type": "insufficient_scope",
"message": "Your token is missing the required scope: crm:write.",
"error_id": "91ddae71-bb75-4a2a-a0aa-b11dffd1f17b",
"required_scopes": [
"crm:write"
]
}
}{
"success": true,
"message": "<string>",
"status": 123
}{
"message": "The given data was invalid.",
"errors": {
"field_name": [
"The field_name field is required."
]
}
}