Skip to content

Custom Objects & Associations

Custom objects hold data that doesn’t fit on a contact, such as pets or vehicles. Each object has a schema (its key, labels, and fields) and any number of records. An association defines how two kinds of object relate, for example a pet and its owner, and a relation links one record to another under an association.

Base URL: https://services.smbcrm.com · Version header: v3

The endpoints on this page use eight scopes. See Scopes for how to request them.

Scope Allows
objects/schema.readonly List objects and get an object’s schema.
objects/schema.write Update an object’s labels, description, and searchable fields.
objects/record.readonly Search records and get a record.
objects/record.write Create, update, and delete records.
associations.readonly List and get associations.
associations.write Create, update, and delete associations.
associations/relation.readonly Get the relations of a record.
associations/relation.write Create and delete relations.

Every object has a key, and the schema and record endpoints on this page take it in the URL path. A custom object’s key starts with custom_objects., for example custom_objects.pet. Standard objects such as contacts and opportunities have keys too. List objects returns the key of each object in the location. You can also read a custom object’s key on its details page under Settings in the SMBcrm app.

Field keys and the objectKey in field requests use a slightly different prefix, such as custom_object.pet and custom_object.pet.name. See Custom Fields, Values & Tags.

A schema describes an object: its key, labels, description, and fields.

GET/objects/

List the standard and custom objects in a location.

scope objects/schema.readonlyauth Location token or PIT

Returns the standard objects in the location, such as contacts and opportunities, together with your custom objects. Read the key of each entry: the schema and record endpoints on this page take an object key.

Query parameter Type Required Description
locationId string Yes The location ID.
Terminal window
curl "https://services.smbcrm.com/objects/?locationId=<location_id>" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"objects": [
{
"id": "<object_id>",
"standard": false,
"key": "custom_objects.pet",
"labels": { "singular": "Pet", "plural": "Pets" },
"description": "Pets we board and groom",
"locationId": "<location_id>",
"primaryDisplayProperty": "custom_objects.pet.name",
"type": "USER_DEFINED",
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
}
]
}

Every endpoint that returns an object uses this shape:

Field Type Description
id string The schema ID.
standard boolean false for custom objects, true for standard objects such as contacts and opportunities.
key string The object key. Custom object keys start with custom_objects..
labels object The display names: singular and plural.
description string The object’s description.
locationId string The location the object belongs to.
primaryDisplayProperty string The field that identifies a record in the SMBcrm app.
type string USER_DEFINED or SYSTEM_DEFINED.
dateAdded string When the object was added.
dateUpdated string When the object was last updated.
GET/objects/{key}

Get one object's schema, optionally with its fields.

scope objects/schema.readonlyauth Location token or PIT

Returns one object. Add fetchProperties=true to include the object’s fields in the fields array.

Parameter Type Required Description
key string Yes Path parameter. The object key, for example custom_objects.pet.
locationId string Yes Query parameter. The location ID.
fetchProperties string No Query parameter. Send true to include the object’s fields.
Terminal window
curl "https://services.smbcrm.com/objects/custom_objects.pet?locationId=<location_id>&fetchProperties=true" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"object": {
"id": "<object_id>",
"standard": false,
"key": "custom_objects.pet",
"labels": { "singular": "Pet", "plural": "Pets" },
"description": "Pets we board and groom",
"locationId": "<location_id>",
"primaryDisplayProperty": "custom_objects.pet.name",
"type": "USER_DEFINED",
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
},
"cache": false,
"fields": [
{
"id": "<field_id>",
"locationId": "<location_id>",
"name": "Name",
"fieldKey": "custom_object.pet.name",
"objectKey": "custom_object.pet",
"dataType": "TEXT",
"parentId": "<folder_id>",
"showInForms": true,
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
},
{
"id": "<field_id_2>",
"locationId": "<location_id>",
"name": "Age",
"fieldKey": "custom_object.pet.age",
"objectKey": "custom_object.pet",
"dataType": "NUMERICAL",
"parentId": "<folder_id>",
"showInForms": true,
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
}
]
}

object has the fields listed under List objects. cache is true when the response was served from cache. Each entry in fields has these fields:

Field Type Description
id string The field ID.
name string The field name.
fieldKey string The field key, for example custom_object.pet.name.
objectKey string The key of the object the field belongs to.
dataType string One of TEXT, LARGE_TEXT, NUMERICAL, PHONE, MONETORY, CHECKBOX, SINGLE_OPTIONS, MULTIPLE_OPTIONS, DATE, TEXTBOX_LIST, FILE_UPLOAD, or RADIO.
parentId string The ID of the folder the field sits in.
showInForms boolean Whether the field appears in forms.
description string The field’s description.
placeholder string The field’s placeholder text.
options array The choices for option fields. Each has a key and a label, and RADIO options can also have a url.
allowCustomOption boolean On RADIO fields, whether a record can hold a value that isn’t one of the options.
acceptedFormats string On file upload fields, the allowed format: .pdf, .docx, .doc, .jpg, .jpeg, .png, .gif, .csv, .xlsx, .xls, or all.
maxFileLimit number On file upload fields, the maximum number of files.
locationId string The location the field belongs to.
dateAdded string When the field was added.
dateUpdated string When the field was last updated.
PUT/objects/{key}

Update an object's labels, description, and searchable fields.

scope objects/schema.writeauth Location token or PIT

Changes an object’s labels and description, and sets which fields record search matches against. locationId and searchableProperties are required. On a standard object, this endpoint updates the searchable fields.

Parameter Type Required Description
key string Yes Path parameter. The object key, for example custom_objects.pet.
locationId string Yes Body field. The location ID.
searchableProperties array of strings Yes Body field. The field keys that record search matches against. Use the fieldKey values from Get an object.
labels object No Body field. The display names: singular and plural.
description string No Body field. The object’s description.
Terminal window
curl -X PUT https://services.smbcrm.com/objects/custom_objects.pet \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"locationId": "<location_id>",
"labels": { "singular": "Pet", "plural": "Pets" },
"description": "Pets we board and groom",
"searchableProperties": ["custom_object.pet.name"]
}'
200 OK
{
"object": {
"id": "<object_id>",
"standard": false,
"key": "custom_objects.pet",
"labels": { "singular": "Pet", "plural": "Pets" },
"description": "Pets we board and groom",
"locationId": "<location_id>",
"primaryDisplayProperty": "custom_objects.pet.name",
"type": "USER_DEFINED",
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:10:00.000Z"
}
}

A record is one entry in an object, such as one pet. The record endpoints work on custom objects and on the standard Business object. In each path, schemaKey is the object key, for example custom_objects.pet.

A record’s properties is an object that holds the field values. Each key is a field name, which is the last part of the field’s fieldKey: the field custom_object.pet.name is name in properties. The value format depends on the field type:

Field type Value
TEXT, LARGE_TEXT A string.
PHONE A string in international format, for example +15125550142.
NUMERICAL A number.
MONETORY An object with currency and value, for example { "currency": "default", "value": 100 }.
DATE A string in YYYY-MM-DD format.
MULTIPLE_OPTIONS An array of strings.
FILE_UPLOAD An array of objects, each with a url.
TEXTBOX_LIST One key per option, written as <field name>.<option key>, each with a string value.
POST/objects/{schemaKey}/records

Create a record in a custom object.

scope objects/record.writeauth Location token or PIT

Adds a record to an object. locationId and properties are required.

Parameter Type Required Description
schemaKey string Yes Path parameter. The object key, for example custom_objects.pet.
locationId string Yes Body field. The location ID.
properties object Yes Body field. The field values, keyed by field name.
Terminal window
curl -X POST https://services.smbcrm.com/objects/custom_objects.pet/records \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"locationId": "<location_id>",
"properties": {
"name": "Buddy",
"age": 4
}
}'
201 Created
{
"record": {
"id": "<record_id>",
"owner": [],
"followers": [],
"properties": {
"name": "Buddy",
"age": 4
},
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
}
}

Every endpoint that returns a single record uses this shape:

Field Type Description
id string The record ID. Use it to get, update, and delete the record and to link it with a relation.
owner array of strings The user ID of the record’s owner. It holds at most one ID and applies to custom objects only. See Users.
followers array of strings The user IDs of the record’s followers, up to 10.
properties object The field values, keyed by field name.
dateAdded string When the record was added.
dateUpdated string When the record was last updated.
POST/objects/{schemaKey}/records/search

Search the records of an object by its searchable fields.

scope objects/record.readonlyauth Location token or PIT

Finds records in one object. query is matched against the object’s searchable fields, which you set with Update an object. To search one field, put its name before the value, as in name:Buddy. All five body fields are required.

page and pageLimit set the page and its size. searchAfter is a cursor: send an empty array on the first request, or the searchAfter value of the last record you received to continue after it.

Parameter Type Required Description
schemaKey string Yes Path parameter. The object key, for example custom_objects.pet.
locationId string Yes Body field. The location ID.
page number Yes Body field. The page number.
pageLimit number Yes Body field. The number of records per page.
query string Yes Body field. The search text, for example name:Buddy.
searchAfter array Yes Body field. The pagination cursor. Send [] for the first page.
Terminal window
curl -X POST https://services.smbcrm.com/objects/custom_objects.pet/records/search \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"locationId": "<location_id>",
"page": 1,
"pageLimit": 10,
"query": "name:Buddy",
"searchAfter": []
}'
200 OK
{
"records": [
{
"id": "<record_id>",
"owner": [],
"followers": [],
"properties": {
"name": "Buddy",
"age": 4
},
"createdAt": "2026-10-08T15:04:00.000Z",
"updatedAt": "2026-10-08T15:04:00.000Z",
"locationId": "<location_id>",
"objectId": "<object_id>",
"objectKey": "custom_objects.pet",
"createdBy": {
"channel": "WEB_USER",
"createdAt": "2026-10-08T15:04:00.000Z",
"source": "PUBLIC_API",
"sourceId": "<user_id>"
},
"lastUpdatedBy": {
"channel": "WEB_USER",
"createdAt": "2026-10-08T15:04:00.000Z",
"source": "PUBLIC_API",
"sourceId": "<user_id>"
},
"searchAfter": [1791471840000, "<record_id>"]
}
],
"total": 1
}

total is the total number of records. Search results name the timestamps createdAt and updatedAt, where the other record endpoints use dateAdded and dateUpdated. Each record also carries these fields:

Field Type Description
objectId string The ID of the object schema the record belongs to.
objectKey string The key of the object the record belongs to.
createdBy object Who created the record: channel, createdAt, source, and sourceId (a user or resource ID).
lastUpdatedBy object Who last updated the record, with the same four fields.
searchAfter array The cursor for continuing a search after this record.
GET/objects/{schemaKey}/records/{id}

Get one record by ID.

scope objects/record.readonlyauth Location token or PIT
Parameter Type Required Description
schemaKey string Yes Path parameter. The object key, for example custom_objects.pet.
id string Yes Path parameter. The record ID.
Terminal window
curl https://services.smbcrm.com/objects/custom_objects.pet/records/<record_id> \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"record": {
"id": "<record_id>",
"owner": ["<user_id>"],
"followers": [],
"properties": {
"name": "Buddy",
"age": 4
},
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:04:00.000Z"
}
}
PUT/objects/{schemaKey}/records/{id}

Update the field values of a record.

scope objects/record.writeauth Location token or PIT

Changes the values on an existing record. Send locationId in the query string and the new values in a properties object in the body.

Parameter Type Required Description
schemaKey string Yes Path parameter. The object key, for example custom_objects.pet.
id string Yes Path parameter. The record ID.
locationId string Yes Query parameter. The location ID.
properties object Yes Body field. The field values to set, keyed by field name.
Terminal window
curl -X PUT "https://services.smbcrm.com/objects/custom_objects.pet/records/<record_id>?locationId=<location_id>" \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"age": 5
}
}'
200 OK
{
"record": {
"id": "<record_id>",
"owner": ["<user_id>"],
"followers": [],
"properties": {
"name": "Buddy",
"age": 5
},
"dateAdded": "2026-10-08T15:04:00.000Z",
"dateUpdated": "2026-10-08T15:12:00.000Z"
}
}
DELETE/objects/{schemaKey}/records/{id}

Delete a record by ID.

scope objects/record.writeauth Location token or PIT
Parameter Type Required Description
schemaKey string Yes Path parameter. The object key, for example custom_objects.pet.
id string Yes Path parameter. The record ID.
Terminal window
curl -X DELETE https://services.smbcrm.com/objects/custom_objects.pet/records/<record_id> \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"id": "<record_id>",
"success": true
}

id is the ID of the deleted record, and success is true when the deletion worked.

An association defines how two kinds of object relate. It has a unique key, the key of each of its two objects, and a label for each side. A pet-and-owner association, for example, links the custom_objects.pet object to contact, with the labels pet and owner. The association doesn’t link any particular records yet. You do that with relations.

Associations you create have the type USER_DEFINED. Built-in associations have the type SYSTEM_DEFINED. An association has these fields:

Field Type Description
id string The association ID.
locationId string The location the association belongs to.
key string The association’s unique key.
firstObjectKey string The key of the first object, for example custom_objects.pet.
firstObjectLabel string The label for the first object’s side of the association.
secondObjectKey string The key of the second object, for example contact.
secondObjectLabel string The label for the second object’s side of the association.
associationType string USER_DEFINED or SYSTEM_DEFINED.
GET/associations/

List the associations in a location.

scope associations.readonlyauth Location token or PIT

Returns the associations in the location. locationId, skip, and limit are all required.

Query parameter Type Required Description
locationId string Yes The location ID.
skip number Yes The number of associations to skip.
limit number Yes The number of associations to return.
Terminal window
curl "https://services.smbcrm.com/associations/?locationId=<location_id>&skip=0&limit=20" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
GET/associations/{associationId}

Get one association by ID.

scope associations.readonlyauth Location token or PIT

Works for both USER_DEFINED and SYSTEM_DEFINED associations.

Parameter Type Required Description
associationId string Yes Path parameter. The association ID.
Terminal window
curl https://services.smbcrm.com/associations/<association_id> \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"id": "<association_id>",
"locationId": "<location_id>",
"key": "pet_owner",
"firstObjectKey": "custom_objects.pet",
"firstObjectLabel": "pet",
"secondObjectKey": "contact",
"secondObjectLabel": "owner",
"associationType": "USER_DEFINED"
}
GET/associations/key/{key_name}

Get a standard or custom association by its key.

scope associations.readonlyauth Location token or PIT

Looks an association up by its key. For an association you created, that is the key you sent when you created it.

Parameter Type Required Description
key_name string Yes Path parameter. The association’s key.
locationId string Yes Query parameter. The location ID.
Terminal window
curl "https://services.smbcrm.com/associations/key/pet_owner?locationId=<location_id>" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
GET/associations/objectKey/{objectKey}

Find the associations that involve an object.

scope associations.readonlyauth Location token or PIT

Pass the key of a contact, opportunity, or custom object to find its associations.

Parameter Type Required Description
objectKey string Yes Path parameter. The object key, for example custom_objects.pet.
locationId string No Query parameter. The location ID.
Terminal window
curl "https://services.smbcrm.com/associations/objectKey/custom_objects.pet?locationId=<location_id>" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
POST/associations/

Create an association between two objects.

scope associations.writeauth Location token or PIT

Defines a new association. It supports contact to contact, contact to custom object, and business to contact. All six body fields are required, and key must be unique.

Body field Type Required Description
locationId string Yes The location ID.
key string Yes The association’s unique key.
firstObjectKey string Yes The key of the first object, for example custom_objects.pet.
firstObjectLabel string Yes The label for the first object’s side of the association.
secondObjectKey string Yes The key of the second object, for example contact.
secondObjectLabel string Yes The label for the second object’s side of the association.
Terminal window
curl -X POST https://services.smbcrm.com/associations/ \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"locationId": "<location_id>",
"key": "pet_owner",
"firstObjectKey": "custom_objects.pet",
"firstObjectLabel": "pet",
"secondObjectKey": "contact",
"secondObjectLabel": "owner"
}'
201 Created
{
"id": "<association_id>",
"locationId": "<location_id>",
"key": "pet_owner",
"firstObjectKey": "custom_objects.pet",
"firstObjectLabel": "pet",
"secondObjectKey": "contact",
"secondObjectLabel": "owner",
"associationType": "USER_DEFINED"
}

Keep the id. You pass it as associationId when you create a relation.

PUT/associations/{associationId}

Change the labels of an association.

scope associations.writeauth Location token or PIT

Updates the two labels. Nothing else on the association changes. Both labels are required.

Parameter Type Required Description
associationId string Yes Path parameter. The association ID.
firstObjectLabel string Yes Body field. The new label for the first object’s side.
secondObjectLabel string Yes Body field. The new label for the second object’s side.
Terminal window
curl -X PUT https://services.smbcrm.com/associations/<association_id> \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"firstObjectLabel": "pet",
"secondObjectLabel": "guardian"
}'
200 OK
{
"id": "<association_id>",
"locationId": "<location_id>",
"key": "pet_owner",
"firstObjectKey": "custom_objects.pet",
"firstObjectLabel": "pet",
"secondObjectKey": "contact",
"secondObjectLabel": "guardian",
"associationType": "USER_DEFINED"
}
DELETE/associations/{associationId}

Delete a user-defined association and all of its relations.

scope associations.writeauth Location token or PIT

Only USER_DEFINED associations can be deleted.

Parameter Type Required Description
associationId string Yes Path parameter. The association ID.
Terminal window
curl -X DELETE https://services.smbcrm.com/associations/<association_id> \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
200 OK
{
"deleted": true,
"id": "<association_id>",
"message": "Association deleted successfully"
}

A relation links two records under an association. Records go in the order the association lists its objects: firstRecordId is a record of the association’s first object, and secondRecordId is a record of its second object. For a pet-and-owner association with the pet first, firstRecordId is the pet record’s ID and secondRecordId is the contact’s ID. A contact’s record ID is its contact ID. See Contacts. An association can also use the Business object as one side, so business records can be linked too.

POST/associations/relations

Link two records under an association.

scope associations/relation.writeauth Location token or PIT

All four body fields are required.

Body field Type Required Description
locationId string Yes The location ID.
associationId string Yes The ID of the association to link the records under.
firstRecordId string Yes The ID of the record of the association’s first object.
secondRecordId string Yes The ID of the record of the association’s second object.
Terminal window
curl -X POST https://services.smbcrm.com/associations/relations \
-H "Authorization: Bearer <token>" \
-H "Version: v3" \
-H "Content-Type: application/json" \
-d '{
"locationId": "<location_id>",
"associationId": "<association_id>",
"firstRecordId": "<pet_record_id>",
"secondRecordId": "<contact_id>"
}'

A successful call returns 201 Created.

GET/associations/relations/{recordId}

List the relations a record belongs to.

scope associations/relation.readonlyauth Location token or PIT

Returns the relations that include a record. Pass a custom object record’s ID or a contact’s ID in the path. locationId, skip, and limit are required. Add associationIds to limit the result to specific associations. To delete a relation, pass its id as relationId to Delete a relation.

Parameter Type Required Description
recordId string Yes Path parameter. The record ID.
locationId string Yes Query parameter. The location ID.
skip number Yes Query parameter. The number of relations to skip.
limit number Yes Query parameter. The number of relations to return.
associationIds array of strings No Query parameter. Only return relations that belong to these associations.
Terminal window
curl "https://services.smbcrm.com/associations/relations/<record_id>?locationId=<location_id>&skip=0&limit=20" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
DELETE/associations/relations/{relationId}

Remove the link between two records.

scope associations/relation.writeauth Location token or PIT

Removes one relation.

Parameter Type Required Description
relationId string Yes Path parameter. The relation ID.
locationId string Yes Query parameter. The location ID.
Terminal window
curl -X DELETE "https://services.smbcrm.com/associations/relations/<relation_id>?locationId=<location_id>" \
-H "Authorization: Bearer <token>" \
-H "Version: v3"
ID Where it comes from Where you use it
Object key List objects The path of every schema and record endpoint, firstObjectKey and secondObjectKey on associations, and the object field endpoints.
Record id Create, search, or get a record Get, update, and delete a record. firstRecordId and secondRecordId on a relation, and recordId when you get a record’s relations.
Contact ID Contacts A relation’s firstRecordId or secondRecordId when the association’s object is contact.
Association id List or create an association Update and delete an association, and associationId on a relation.
User ID in owner and followers Users The owner and followers shown on a record.
  • Custom Fields, Values & Tags: add and change the fields on a custom object.
  • Contacts: contacts are the most common association target, and a contact’s ID is its record ID in a relation.
  • Users: look up the user IDs that appear in owner and followers.
  • Scopes: the full list of scopes your token can request.
  • Errors & Troubleshooting: status codes and error response shapes.