The Zendesk REST API provides many object types for storing and managing your customer data, from tickets, users, organizations, and more. However, it can't provide every possible object type that your organization might need. For example, you might want to associate each new ticket with a retail store to get a better picture of the customer and of the store.
Use the Custom Objects API to define a new object type in Zendesk, then create objects from the new object type. A custom object can be just about anything, including service contracts, products, households, or customer visits. The API lets you create, read, update, or delete the objects.
You can use your custom objects in your integrations or with the Zendesk Apps framework to extend existing Zendesk product functionality.
This guide shows you how to create and use custom objects with the Zendesk API. The example takes an IT team that maintains the computers of company employees. The IT team wants to include details about each computer in the support tickets that employees submit when they have trouble with one of them. You can define a new computer object type in Zendesk, then create an object for each computer to store details about each one. You can also associate computers with tickets to monitor their reliability.
Topics covered:
- Enabling custom objects
- Defining a custom object type
- Adding objects
- Modeling your data
- Associating related objects
- Retrieving related objects
- Putting it all together
Enabling custom objects
Custom objects are available on all Zendesk Suite plans. If you're interested in becoming a Zendesk developer partner, you can convert a trial account into a sponsored Zendesk Support account. See Getting a trial or sponsored account for development.
Custom objects must be enabled by an administrator in Zendesk Support. If you're not an admin, ask one to enable them for you.
To enable custom objects in your account
-
In Zendesk Support, click the Zendesk Products icon (
) in the top bar, then select Admin Center on the lower side of the pop-up box.
-
On the Admin Center home page, click the Sunshine icon (
) in the sidebar.
The Custom Objects and Relationships page opens:
-
Click Activate Custom Objects.
Defining a custom object type
At its most basic, an object type consists of a key and a schema that describes the data. The key is the name you want to use to identify the object type. Example: "computer".
After discussions with the IT team, you agree to define an object type for all the personal computers (PCs) in the company. Each PC should be represented as an object record with the following very basic properties:
Name | Type | Mandatory | Comment |
---|---|---|---|
id | string | yes | Unique identifier assigned to the computer by IT |
model | string | no | Make and model of the computer |
is_laptop | boolean | no | Whether or not the computer is is_laptop |
These details make up your schema. Notice that the schema doesn't contain any PC information. It just describes that information. To learn more, see Creating a schema for a custom object.
To create the "pc" object type, include the schema in a POST request to the following endpoint:
POST /api/sunshine/objects/types
Try it yourself
-
Save the following JSON object in a file named pc_object_type.json.
{ "data": { "key": "pc", "schema": { "properties": { "id": { "type": "string", "description": "Unique identifier assigned to the computer by IT" }, "model": { "type": "string", "description": "Make and model of the computer" }, "is_laptop": { "type": "boolean", "description": "Whether or not the computer is a laptop" } }, "required": ["id", "model"] } } }
The
data
object consists of akey
and aschema
. You'll use thekey
to identify the object type in other endpoints. For example, when you create a pc object record later in this tutorial, you'll set thetype
to "pc" as follows:{ "data": { "type": "pc", "attributes": { "id": "ASSET-2018pc32", "model": "Apple MacBook Pro", "is_laptop": true } } }
Your key must meet the following requirements:
* Be unique
* Only contain alphanumeric characters (a-z, 0-9), underscores (\_) and dashes (-)
* Have a minimum of 2 characters and maximum of 32 characters
The system changes all uppercase characters in the key to lowercase.
-
In your command-line interface, navigate to the folder containing pc_object_type.json.
-
Paste the following cURL command into your command-line interface and press Enter.
curl https://{subdomain}.zendesk.com/api/sunshine/objects/types \ -d @pc_object_type.json \ -H "Content-Type: application/json" \ -v -u {email_address}:{password} -X POST
Make sure to replace the placeholder values with your own.
Windows users: Replace the line-continuation backslashes (\) in this and the other examples with caret () characters.
Example response:
{ "data": { "key": "pc", "schema": { "properties": { "id":{ "type": "string", "description": "Unique name assigned to the computer by IT" }, "model": { "type": "string", "description": "Make and model of the computer" }, "is_laptop": { "type": "boolean", "description": "Whether or not the computer is a laptop" } }, "required": ["id","model"] }, "created_at":"2018-10-28T18:13:26.003Z", "updated_at":"2018-10-28T18:13:26.003Z" } }
To learn more, see Create Object Type in the API docs.
Adding object records
Once the pc object type is created in your Zendesk Support instance, you can use the Zendesk API to create, read, update, and delete individual pc object records. Object records are nothing more than data objects with defined properties.
The first task is to create an object record for each PC. You can use the Create Object Record endpoint:
POST /api/sunshine/objects/records
The data you include in the request is defined by the object type you defined, which for the pc type consists of attributes named "id", "model", and "is_laptop". Example:
{
"data": {
"type": "pc",
"attributes": {
"id": "ASSET-2018pc32",
"model": "Apple MacBook Pro",
"is_laptop": true
}
}
}
The objects are stored in the Zendesk infrastructure. You can use the Zendesk API to access them.
- If you want to use the data, you can use several different GET endpoints to retrieve your objects. See the Object Records API docs.
- If your IT team makes a change to the PC, you can use the Update Object Record endpoint to update the object for that PC in Zendesk.
- If IT gets rid of the PC, you can use the Delete Object Record endpoint.
- If IT adds another PC, you can use the Create Object Record endpoint.
Try it yourself
-
Save the following JSON object in a file named obj_pc.json:
{ "data": { "type": "pc", "attributes": { "id": "ASSET-2018pc32", "model": "Apple MacBook Pro", "is_laptop": true } } }
You must specify "pc" as the object type.
-
In your command-line interface, navigate to the folder containing obj_pc.json and run the following cURL command:
curl https://{subdomain}.zendesk.com/api/sunshine/objects/records \ -d @obj_pc.json \ -H "Content-Type: application/json" \ -v -u {email_address}:{password} -X POST
Replace the placeholder values with your own.
The response will include an id for the object record:
{ "data": { "type": "pc", "id": "5d0daa84-aec0-11e7-9a70-416881d66b6d", ... } }
Don't confuse the object record id (
"id":"5d0daa84..."
) with the id attribute in your custom object ("id":"ASSET-2018pc32"
).
You can use the object record id to make a GET request for the object, as follows:
curl https://{subdomain}.zendesk.com/api/sunshine/objects/records/5d0daa84-aec0-11e7-9a70-416881d66b6d \
-v -u {email_address}:{password}
To learn more, see Create Object Record and Show Object Record in the API docs.
Modeling your data
After adding pc objects to your Zendesk Support instance, you can establish relationships with other objects in Zendesk to use the data in more meaningful ways. For example, information about a particular PC is not very useful to an IT manager unless it's associated with tickets that employees submitted about the PC.
Custom objects support several relationship types:
-
One-to-one - Both object types can have only one object on either side of the relationship. For example, a ticket would only be associated with a unique PC, and a PC would only be associated with a unique ticket. This isn't a viable option in the IT department example. The number of pc objects would have to equal the number of ticket objects.
-
One-to-many - Each object of the first object type relates to none, one, or many objects of the second object type. For example, a PC can be associated with none, one, or many tickets.
-
Many-to-many - Each object of the first object type relates to none, one, or many objects of the second object type, and each object of the second object type relates to none, one, or many objects of the first object type. You define a many-to-many relationship type with two one-to-many relationship types.
A relationship type can be between:
- two custom object types (between "pc" and "office_location" object types, for example)
- one custom object type and any of the following Zendesk object types: tickets, users, articles, organizations, groups, or chats
- two Zendesk object types
To define a relationship type, you make a POST request to the Create Relationship Type endpoint:
POST /api/sunshine/relationships/types
Defining a relationship type doesn't create an association between two specific objects. It just describes the relationship record. To associate two objects, you must create a relationship record between the two objects. That's covered later in Associating related objects.
Try it yourself
For the IT department, you decide to define a one-to-many relationship type between PCs and tickets. Each ticket can be associated with only one PC, but each PC can be associated with many tickets.
-
Save the following JSON object in a file named relationship_type.json.
{ "data": { "key": "pc_has_many_tickets", "source": "pc", "target": ["zen:ticket"] } }
Choose a unique
key
value (here, "pc_has_many_tickets") for each relationship type you define.The square brackets around the target
["zen:ticket"]
sets the "many" side of the one-to-many relationship type. Omit the brackets to define a one-to-one relationship type.The definition reads as follows: A PC can be associated with many tickets, but a ticket can be associated with only one PC.
Use the 'zen:' prefix to specify one of the Zendesk object types. Examples:
* "zen:ticket"
* "zen:user"
* "zen:article"
* "zen:organization"
* "zen:group"
* "zen:chat"
* "zen:lead"
* "zen:contact"
* "zen:deal"
**Note**: You can't modify the relationship type once it's created. You'll need to delete it and create another one. See [Relationship Types](https://developer.zendesk.com/rest_api/docs/sunshine/relationship_types) in the API docs.
-
In your command-line interface, navigate to the folder containing relationship_type.json and run the following cURL command:
curl https://{subdomain}.zendesk.com/api/sunshine/relationships/types \ -d @relationship_type.json \ -H "Content-Type: application/json" \ -v -u {email_address}:{password} -X POST
Replace the placeholder values with your own.
To learn more, see Create Relationship Type in the API docs.
Once you've defined a relationship type, you can start associating related objects.
Associating related objects
You associate an object of one object type to an object of another object type by creating a relationship record (not to be confused with a relationship type). For your IT department, you can create a relationship record between a particular ticket and a particular PC.
A relationship record consists of the ids of the two related objects and their relationship type. The record doesn't contain any actual object data. Instead, you use the ids in the relationship record to retrieve the related data (covered in Retrieving related objects later).
A relationship record is governed by a relationship type you created. So far you created a one-to-many type named "pc_has_many_tickets" where each ticket can be associated with only one PC, but each PC can be associated with many tickets.
To create a relationship record, make a POST request to the Create Relationship Record endpoint:
POST /api/sunshine/relationships/records
The JSON object you include in the request must specify the relationship type, as well as the ids of the source
and target
objects. Example:
{
"data": {
"relationship_type": "pc_has_many_tickets",
"source": "1c771ee0-2c3f-11e7-bf60-e5c3f630b5aa",
"target": "zen:ticket:35437746"
}
}
For "relationship_type"
, you must specify the key you chose when creating the relationship type -- in this case "pc_has_many_tickets".
Note: Once created, you can't modify the relationship record because of the underlying relationship type. You must delete the relationship record and create another one.
Try it yourself
-
Find or create a test ticket in your Zendesk Support instance. Example:
{ "ticket": { "id": 35437746, "subject": "My computer is on fire!", ... } }
-
Get the id of the related pc object in your Zendesk Support instance. Example:
{ "data": { "type": "pc", "id": "5d0daa84-aec0-11e7-9a70-416881d66b6d", "attributes": {"id":"ASSET-2018pc32","model":"Apple MacBook Pro","is_laptop":true}, ... } }
See Object Records in the API docs for the various GET requests you can make.
-
Save the following JSON in a file named relationship_record.json, replacing the ids with your own:
{ "data": { "relationship_type": "pc_has_many_tickets", "source": "5d0daa84-aec0-11e7-9a70-416881d66b6d", "target": "zen:ticket:35437746" } }
The example creates a relationship record between a particular PC and a particular ticket. The source and target ids should correspond to the source and target object types in the relationship record type -- in this case, pc id and ticket id.
-
In your command-line interface, navigate to the folder containing relationship_record.json and run the following command:
curl https://{subdomain}.zendesk.com/api/sunshine/relationships/records \ -d @relationship_record.json \ -H "Content-Type: application/json" \ -v -u {email_address}:{password} -X POST
Example response:
{ "data": { "id": "5d3484b5-aec6-11e7-9a70-a12d6a7d800c", "relationship_record_type": "pc_has_many_tickets", "source": "5d0daa84-aec0-11e7-9a70-416881d66b6d", "target": "zen:ticket:35437746", "created_at": "2018-09-28T21:52:22.709Z" } }
Retrieving related objects
Use the List Relationship Records by Object Record endpoint to retrieve the relationship records:
GET /api/sunshine/objects/records/{resource_id}/relationships/{relationship_type_key}
For example, to get all the related tickets for the PC with the id of "5d0daa84-aec0-11e7-9a70-416881d66b6d", you'd make the following GET request:
curl https://{subdomain}.zendesk.com/api/sunshine/objects/records/5d0daa84-aec0-11e7-9a70-416881d66b6d/relationships/pc_has_many_tickets \
-v -u {email_address}:{password}
Example response:
{
"data": [
{
"id": "c5477230-2e98-11e7-acd9-9dbd5d6450d8",
"target": "zen:ticket:35438118",
"ref": "/api/v2/tickets/35438118"
},
{
"id": "5d3484b5-aec6-11e7-9a70-a12d6a7d800c",
"target": "zen:ticket:35437746",
"ref": "/api/v2/tickets/35437746"
}
],
"links": {
"previous":null,
"next":null
}
}
Putting it all together
You can use your custom objects and relationship records to solve real-world problems, to improve existing processes, or simply to get a better picture of your customers. For example, you could use the pc objects to build a Zendesk app that shows details about a computer to the agent working on a ticket.
One approach to building this app would be to add a dropdown list to the ticket form in Help Center that lets users select a PC when they submit a ticket. When designing the ticket field, you'd use the object ids of the pcs as the option values (or "tags", in Zendesk terms). For example, "5d0daa84-aec0-11e7-9a70-416881d66b6d". You could then build a sidebar app in the agent interface to display the computer details. The app would take the option value from the ticket to make an API request to get the computer details.
The app could also make an API request to create a relationship record between the PC and the ticket when the agent changes the ticket status from New to Open. You could then use the Zendesk API in your system to generate reliability reports that list all the tickets for each PC.
25 Comments
Hello,
We recently started using the custom resources feature. For now we are mainly testing it and checking if it's something that would improve how we manage information without a big overhead.
One of the possibilities we see would be to use custom resources with Insights. Is any information from custom resources being carried through to Insights?
Thank you,
Hi Ignacio,
Thanks for your comment. Currently we do not load Custom Resources data into the Insights product, but this is something we are actively exploring and hope to offer in the future. We understand that this will be a particularly valuable integration so it is a top priority for us as we continue to integrate this new feature more deeply into our platform. Stay tuned!
Hi,
I am very interested in this feature to improve our internal efficiency by bringing information (like computers) into Zendesk with a customer resource.
One thing which I am missing, but am very interested in, is to make a relationship between a Zendesk Ticket and a Help Center post. This is currently only possible at ticket creation (in the Via property), but not at a later stage.
As I am missing the post object in this article, as well as the relationship API documentation, I am asking if this will be implemented.
Is there an option to retrieve an object from an external data source?
E.g. Device Serial ABC1234 --> Look up in an external database?
Hello,
In this article, it is specified that a many-to-many relationship is possible, however I am not finding how. If I attempt to submit a request to the API to create a relation which I believe would handle that (source and target are arrays), I get returned an error saying "Cannot create a relationship type where both source and target are arrays".
Also, is there a feature request page for having Custom Resources loaded into Insights? That function could greatly benefit our company as well.
Thank you,
Hello Matt, to represent many-to-many relationships, you need to create multiple relationship types that go in both directions. Let me know if that doesn't work for you for some reason.
I'm not sure about the Insights question yet, someone will follow up about that.
Jason,
I am not sure I follow. I know in an SQL database, I would have to use an intermediary table. Take the following example, if I want a many-to-many relationship between the Zendesk type ticket and a custom object named "location", I would have to do the following:
Then any time I want to associate a ticket to a location or an additional location, I would need to do the following:
Can you let me know if I'm on the right track, or completely off base?
Thanks,
Matt
Hi Matt, I think you are on the right track, but I'm not sure you need the `location_ticket` object, unless it's holding additional properties about the relationship. You should be able to create a one-to-many relationship between location -> zen:ticket as well as a one-to-many relationship between zen:ticket -> location. Then when you need to associate a ticket to a location, you would create a ticket -> location relationship for the ticket, and a corresponding location -> ticket relationship if you want to know all tickets associated with a location.
Okay,
I think that has me on the right track. I'll test a few things later in our sandbox and see how it goes.
Thank you for your advice.
Under Associating related objects it states:
"A relationship record is governed by a relationship type you created. So far you created a one-to-many type named "pc_has_many_tickets" where each ticket can be associated with only one PC, but each PC can be associated with many tickets."
I'm not seeing this behavior in my tests. The API will let me create multiple relationship records using different PC source IDs with the same "zen:ticket" target. The same applies if I define a one-to-one relationship type. It seems that the single or many schema only affects the number of targets a source can be linked to, but not vice versa. Is this true, or am I doing something wrong?
Hi Jason, when you create multiple relationships with different PC source IDs, you are creating *different* relationships for each PC. The same is true for one-to-one: each relationship is a separate relationship. The difference between one-to-one and one-to-many is that the target field in the one-to-many relationship type is an array. Whereas the target field in the one-to-one is a single ID.
You should not be able to create multiple relationships with the *same* PC source ID in either the one-to-one or the one-to-many example.
Does that help?
Hello,
How can I add a drop down to a ticket form and populate it with custom objects that are related to the requester. I created a ticket field and associated the custom objects to the employee, just have been struggling on how to populate the custom objects into the drop down.
Is this possible?
Hi Matthew,
I think you could achieve this using an app. I don't believe there is anything baked in that you could use.
More info on the ticket apps can be found here.
https://developer.zendesk.com/apps/docs/support-api/ticket_sidebar
You would basically want activate on the app.activated function to retrieve your list for the user and then populate the app with the data from the custom object that you want.
Anyone have an example application that is pulling related Objects on a user?
url: '/api/sunshine/objects/records/zen:user:' + id + '/related/object_record_name',
Hi Matt,
Do you have a question about using our List Related Object Records API? You'll want to use the relationship type in the url to return related records. For example, my test account has a user_has_many_devices relationship type. The url I used to get a user's device objects was the following:
https://z3nt.zendesk.com/api/sunshine/objects/records/zen:user:1274575738/related/user_has_many_devices
Best,
Chris
@Christopher I was just curious if anyone had best practices around using handlebar for displaying several attributes on several objects from the array. More of a curiosity if anyone was doing that in any sidebar apps.
Hi Charles,
Am new to zendesk. I was trying updating a Custom Business object using the below command
curl https://d3v-tcs2sumansupport.zendesk.com/api/sunshine/objects/records/09ee1515-cda0-11e9-b4d2-4dfc0c9cbf37 -d '{"data": {"attributes": {"model": "Asus K53s Laptop"}}}' -H "Content-Type: application/merge-patch+json" -X PATCH -v -u suman.sahaxxxx.com:XXXXXXXXXX
but am getting the below 400 error. Can you help understand the syntax error that I have.
Hi Suman,
Looks like you're on Windows. The Windows command line doesn't support single quotes and a few other bits that sometime appear in cURL commands. Here's some info on getting around the issue: https://develop.zendesk.com/hc/en-us/articles/360001068567-Installing-and-using-cURL#curl_win.
Thanks Charles...I too figured that out...Appreciate your reply though...Have a good day... :)
Can anybody let me know, how to pull data stored as attributes of sunshine object in java script?
E.g. : Created Sunshine custom object 'pc' with 3 attributes 'id', 'model' & 'is_laptop'. Also, created the relation 'pc_has_many_tickets' with "source": "pc"and "target": ["zen:ticket"].
Then, using curl I have also filled in attributes values for my ticket# 7 ( say id as '55eer43cv', model as 'Apple MacBook Pro', and is_laptop as 'true').
Now, I want to fetch the value stored in java script for a particular ticket ( say ticket# 7 in this case) and expose it in zendesk app in html like we did for any normal ticket object.
I tried to test the retrieval code using v2 REPL where,
zafClient.get('ticket.id') --> getting value ,
zafClient.get('pc.id') --> not getting value, getting error.
I already have all the information I need (for now) in Zendesk but want to use this information to create a custom - Customer Profile app - similar to the "User Data" app.
I want to be able to customise how the information is presented based on the customer profile data such as - If customer is VIP - set the profile window border to Navy Blue for example/
Can you please point me in the right direction?
Hi Gary Kester! Since the app is just an iframe, you can design this however you would like with whatever languages you're utilizing and whatever logic you'd like to use. We don't have a specific tutorial on how to do what you're looking to accomplish, but a front-end dev should be able to get this working for you!
Thank you
Is there any way to access sunshine custom object data from within a ticket body - either via macro or preferably a placeholder?
Adam Grohs, I don't think that's possible. You could write a custom app to insert text into the body of the editor but that would be the only way I know of to get it in there at this time. Sounds like a good idea though so you may want to put in a feature request.
Please sign in to leave a comment.