Records
Create a CRM Record
Create a new record in a custom Zeeg CRM object by slug, setting typed attribute values that are validated on submit, and get back a generated record UUID
POST
/
crm
/
{objectSlug}
Create a CRM record
curl --request POST \
--url https://api.zeeg.me/v2/crm/{objectSlug} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
}
'import requests
url = "https://api.zeeg.me/v2/crm/{objectSlug}"
payload = {
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
}
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({sku: 'DRESS-001', price: 29, inventory_count: 150})
};
fetch('https://api.zeeg.me/v2/crm/{objectSlug}', 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}",
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([
'sku' => 'DRESS-001',
'price' => 29,
'inventory_count' => 150
]),
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}"
payload := strings.NewReader("{\n \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\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.zeeg.me/v2/crm/{objectSlug}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeeg.me/v2/crm/{objectSlug}")
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 \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 201,
"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": "aebc5278-0f03-4786-b0a4-1611a594db18",
"required_scopes": [
"crm:write"
]
}
}{
"message": "The given data was invalid.",
"errors": {
"field_name": [
"The field_name field is required."
]
}
}Creates a new record for a custom CRM object and returns it with a generated UUID.
Use
Option IDs for
Path parameter
| Parameter | Type | Description |
|---|---|---|
objectSlug | string | The slug of the custom CRM object to create a record in (e.g. products, deals). The object must exist. |
Request body
Pass a flat JSON object where each key is an attribute slug and each value is the attribute value. You only need to include attributes you want to set — omitted attributes default tonull.
{
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150,
"in_stock": true,
"launched_at": "2025-06-01",
"category": { "id": 12 }
}
GET /v2/crm/objects/{slug} to discover the available attribute slugs and their types before writing records.
Attribute types
Values are validated against the type defined on the object. Passing the wrong type returns a400 error.
| Type | Expected value | Example |
|---|---|---|
text | String, max 255 characters | "DRESS-001" |
number | Integer | 29 |
checkbox | Boolean | true or false |
date | ISO 8601 date string | "2025-06-01" |
select | Object with an id key matching a valid option ID | { "id": 12 } |
multiselect | Array of objects, each with an id key | [{ "id": 12 }, { "id": 13 }] |
relation | Array of record UUIDs from the related object | ["c1d2e3f4-...", "a2b3c4d5-..."] |
user | Array of organization member UUIDs | ["member-uuid-1"] |
select and multiselect attributes are returned when you fetch the object schema via GET /v2/crm/objects/{slug}.
Unique attributes
If an attribute is marked asisUnique, submitting a value that already exists on another record returns a 400 error. Check for uniqueness constraints in the object schema before creating records in bulk.
Minimal record creation
You can create a record with no attributes at all — useful when you want to allocate an ID first and fill in data later:{}
When to use this endpoint
- Single record creation — a user fills a form and submits a new product, deal, or custom entry.
- One-off imports — create a small number of known records programmatically.
- Initial seeding — populate a new object with a handful of records before bulk operations.
For bulk imports where records may already exist, prefer Assert (upsert) instead. It creates when no match is found and updates when one is found — eliminating the need to pre-check for duplicates.
Authorizations
Path Parameters
Slug of the custom CRM object.
Body
application/json
Flat object of attribute slug → value pairs.
Response
Created
Example:
true
Example:
201
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 July 11, 2026
⌘I
Create a CRM record
curl --request POST \
--url https://api.zeeg.me/v2/crm/{objectSlug} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
}
'import requests
url = "https://api.zeeg.me/v2/crm/{objectSlug}"
payload = {
"sku": "DRESS-001",
"price": 29,
"inventory_count": 150
}
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({sku: 'DRESS-001', price: 29, inventory_count: 150})
};
fetch('https://api.zeeg.me/v2/crm/{objectSlug}', 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}",
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([
'sku' => 'DRESS-001',
'price' => 29,
'inventory_count' => 150
]),
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}"
payload := strings.NewReader("{\n \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\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.zeeg.me/v2/crm/{objectSlug}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zeeg.me/v2/crm/{objectSlug}")
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 \"sku\": \"DRESS-001\",\n \"price\": 29,\n \"inventory_count\": 150\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 201,
"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": "aebc5278-0f03-4786-b0a4-1611a594db18",
"required_scopes": [
"crm:write"
]
}
}{
"message": "The given data was invalid.",
"errors": {
"field_name": [
"The field_name field is required."
]
}
}