Custom objects (KObjects)
Model orders, bookings, devices and other records from your systems with Klasses and KObjects, and attach them to customer timelines.
Custom objects bring records from your systems into Kustomer as first-class data. An e-commerce order, a flight booking, a subscription or a smart-home device can live on the customer's timeline, power search and workflows, and show up in agent views.
Two concepts work together:
- A Klass is a type, with a name, icon, color and typed attributes. For example,
ecomm-order. - A KObject is one record of that type, such as order
#4417for Jane Doe.
Diagram source
flowchart LR K["Klass<br/><code>ecomm-order</code><br/>icon, color, attributes"] -. defines .-> O1["KObject<br/>Order #4417"] K -. defines .-> O2["KObject<br/>Order #4502"] O1 --> C[Customer<br/>Jane Doe] O2 --> C C --> T[(Timeline)] O1 --> T O2 --> T
Choose a KObject or a custom attribute
Define a Klass
Apps usually ship their Klasses in the app definition, so they're installed consistently in every org. You can also create one directly:
post/v1/klasses
{
"name": "ecomm-order",
"displayName": "Order",
"icon": "basket",
"color": "#64943E"
}nameis the system name used in API paths. It must be unique in the org and use only letters, digits,_and-(up to 255 characters). Prefix it with your app or company name, such asecomm-order, to avoid collisions.iconis a Material Design Icons name such asbasket,truck-outlineorairplane.coloris any CSS color.
Then give the attributes types and display names by setting metadata for the Klass:
put/v1/metadata/{resource}
curl -X PUT "https://acme.api.kustomerapp.com/v1/metadata/kobject.ecomm-order" \
-H "Authorization: Bearer $KUSTOMER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"orderNumberStr": { "displayName": "Order number" },
"orderStatusStr": { "displayName": "Status", "enumeration": ["placed", "shipped", "delivered", "returned"] },
"totalPriceNum": { "displayName": "Total" },
"orderedAt": { "displayName": "Ordered" },
"trackingUrl": { "displayName": "Tracking link" }
}
}'The suffix on each name (Str, Num, At, Url) sets its type. See Custom attributes for every suffix and option.
Create KObjects
Create a KObject under the customer it belongs to:
post/v1/customers/{id}/klasses/{name}
curl -X POST "https://acme.api.kustomerapp.com/v1/customers/$CUSTOMER_ID/klasses/ecomm-order" \
-H "Authorization: Bearer $KUSTOMER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Order #4417",
"description": "2 items · Express shipping",
"externalId": "order-4417",
"custom": {
"orderNumberStr": "4417",
"orderStatusStr": "shipped",
"totalPriceNum": 129.9,
"orderedAt": "2026-10-18T09:12:00Z",
"trackingUrl": "https://track.example.com/1Z999"
},
"data": { "lineItems": [{ "sku": "TEE-BLK-M", "qty": 2 }] },
"tags": ["express"]
}'titlestringrequired- The headline shown on the timeline card.
descriptionstring- A second line of context.
externalIdstring- Your ID for the record. Use it to find and update the record later.
customobject- Typed attributes defined in the Klass metadata. These are searchable and appear in views and workflows.
dataobject- Free-form JSON for anything else, such as line items. Use it for data you display in a KView, not for data you search on.
imagesobject[]- Images to show on the record.
iconstring- Overrides the Klass icon for this record.
customerstring- The customer ID, when you create through
/v1/klasses/{name}. companystring- The company ID, for records that belong to a company.
tagsstring[]- Tags.
You can also create a KObject at /v1/klasses/{name} with customer or company in the body, or load many at once with the bulk endpoint.
Read and update
get/v1/klasses/{name}/externalId={externalId}
put/v1/klasses/{name}/{id}
get/v1/customers/{id}/klasses/{name}
A typical sync looks up by externalId, then creates or updates:
async function upsertOrder(customerId: string, order: Order) {
const body = JSON.stringify({
title: `Order #${order.number}`,
externalId: `order-${order.number}`,
custom: { orderNumberStr: order.number, orderStatusStr: order.status, totalPriceNum: order.total },
})
const found = await fetch(`${base}/v1/klasses/ecomm-order/externalId=order-${order.number}`, { headers })
if (found.status === 404) {
return fetch(`${base}/v1/customers/${customerId}/klasses/ecomm-order`, { method: 'POST', headers, body })
}
const { data } = await found.json()
return fetch(`${base}/v1/klasses/ecomm-order/${data.id}`, { method: 'PUT', headers, body })
}Show KObjects to agents
KObjects appear on the customer timeline automatically, using the Klass icon, color, title and description. For a richer layout, such as a table of line items with a "Track package" button, build a KView for the Klass.
Limits
- A single client can create up to 120 KObjects per customer per minute. Records with
importedAtare exempt. - Custom string attributes (
Str) hold up to 1,024 characters.
The end-to-end orders integration guide puts all of this together.