Recent searches
No recent searches
How to import tickets into Zendesk using the API
Posted Jan 02, 2023
I recently moved our brand in a multibrand Zendesk instance to our own instance.
We use our closed tickets as a knowledge base (did we have this error already? etc.), so we needed to import a lot of our existing tickets. About 99% of the tickets are in the closed state, so that got a lot of attention while figuring out how to migrate.
On Zendesk's own recommendation, I initially evaluated Helpdesk Migration as a service to import all of our tickets. I quickly came to the conclusion that while they offer an interesting service, we'd rather do it ourselves, because we had some special requirements.
So, I started to collect all of the requirements:
- export and import tickets and all of their associated objects, starting at the release date of our last supported release of the product we support using Zendesk.
- Since we cross-linked Zendesk tickets with our development issue tracker (JIRA), we required that the Zendesk tickets in the new instance can be identified knowing their ID in the old instance.
- there are some data security concerns, so we have to be able to map certain requesters, submitters, collaborators and followers to anonymous accounts.
- The imported tickets need to be high fidelity copies of the originals, including screenshots, images, attachments etc. etc.
That's the gist of it.
Researching the topics, I found a few special situations in the API:
- while it offers a ticket import endpoint with a special mode for closed tickets which does not fire triggers for those tickets, it always requires that requesters and submitters are active, not suspended. So, if you have tickets created by ex-employees who have been suspended after leaving the company, the API will balk.
- the API cannot handle empty comment bodies. It is easy to generate such a comment by sending a mail with an attachment, but no text to the Zendesk instance. So, it is more restrictive that the Zendesk client and server software.
- there is no mention of inline attachments (screenshots and images, for instance) in the API documentation. Fact is, while they have a link to the storage backend, those attachments have no attachment record.
- getting attachments onto a ticket works a bit different than downloading them: You upload the file, then get a token back for the upload (among other things). Note that that token is different from the token in the URL for the attachment (these are available in two flavors, branded (mapped_content_url; https://yoursubdomain.yourdomain.tld/..) and unbranded (content_url; https://yourZDaccount.zendesk.com/..) and have the relative path "./attachments/token/<token>/?name=<attachmentfilename.type>".
- you cannot re-cross-link merged tickets because the API does not offer some kind of ticket ID reservation which would be needed to implement this mapping (you need to have both ticket IDs available when commiting the first ticket, but you cannot have the ID of the second ticket at that time).
- There seems to be no support for side conversations in the import ticket endpoint at this time. So, either convert them to (internal) comments, or forget about them.
So, lots of things to consider.
There are some highlights as well, though: While the API documentation states that you need to upload the attachments with a suitable ContentType, in fact, it will check your content and return a suitable ContentType - at least as far as I can tell. Nice one!
I opted to use JSON as the exchange format for all but the attachments themselves.
You can do all the exports before starting the imports. You can interlace, if you are so inclined.
I came up with the following sequence:
-
export tickets and their comments resulting in ticket.json and comments.json per ticket in a directory tree export/<timestamp>/tickets/<ticketId>.
While exporting the tickets, gather all
- user Ids (requester, submitter, CCs, followers, collaborators, authors, ...)
- organization IDs
- group IDs
- ticket field IDs
- ticket form IDs
- dynamic content items -
export
- design objects (ticket fields, forms, dynamic content, ...)
- master data (users, groups, organizations)
- attachments (both inline and "normal") -
set up the new instance
- create the help center
- import or create design elements, always creating mapping tables (export ID, import ID) as csv files -
fill the gaps: if you deleted users, groups, organizations involved in the tickets, you need a strategy to cope with this. Either you recreate these missing objects, or you map them to dummy objects.
Now, we're ready for the tickets:
-
upload all attachments
-
upload the tickets
These last two steps seem so simple, however, there's lots of details. This is when things like "requester needs to be active" help you make the migration a bit more, well, some may call it, interesting.
There's a lot to cover here when it comes to attachments and their URLs in the exported tickets. I found a lot of unexpected URLs (content_url instead of mapped_content_url and vice versa) in the content, and also some special cases (even attachment URLs from 3rd party Zendesk domains). However, it's up to you to generate a more consistent handling in your import code.
And then, there's some fine points that might be out of the migrator's control. In my case, Zendesk balked that it cannot parse the JSON. Well, the JSON I generated off those Powershell objects has been syntactically correct, however, I handed over the Powershell object directly, as I have done for all the imports and exports before. Well, saving the JSON and then feeding it to Zendesk worked without problems. So, good luck in that case, but a bit scary.
Final thoughts
I started to migrate on the last weekend before Christmas, intending to finish everything by Sunday evening.
On New Year's eve, I finally finished things up...
I have implemented the migration code using Powershell core and bash scripts on a Linux OS. Powershell has been what I used to work with the Zendesk API before moving from Windows to Linux, and I didn't want to rewrite all the code right before the migration.
Would I do it that way again? Being in the consultancy business, the answer is obvious: It depends.
I would certainly like Zendesk to expand their API documenation a bit, including an example or two with non-trivial tickets, e.g. including inline and normal attachments etc.
I also suggested to Zendesk to either document or lift the API restrictions mentioned above.
Hope this helps others in a similar quest.
Yours truly
Peter
2
8 comments
Gary Beichler
Hi Peter Hochstrasser. Thanks for this detailed post! A lot of great information here. We're planning on expanding our developer documentation to cover data migration in more detail later this year and next. I'll make a note to cover the examples you suggested, among other things. Thanks again!
0
Peter Hochstrasser
Looking forward to it, Gary Beichler.
0
Abdelhameed Khaled
Hello I have a tiny problem I wander if you can help or guide me with it.
I have csv of tickets I want to import so I follow these steps :
1- convert the csv into json
2-use Zendesk API to create many tickets
the problem is that for custom ticket fields it should be in this json format
I don't know how to create a CSV template to be converted into this format or if there is any way to workaround this issue to import the custom ticket fields as well
0
Peter Hochstrasser
Hi Abdelhameed Khaled
It's all a matter of sequence.
In your case, first create the environment, like custom fields, only then import the tickets.
You can easily find the IDs of these fields once they are created, and it's simple to substitute it in your JSON creation.
0
Gauri Pandit
Hello, your document is helping alot in my transition to Zendesk. Can you elaborate more on how you worked with the attachments? Able to work with attachments for single ticket but got stuck when working on bulk attachments. Is it even possible to do that? If yes, can you elaborate?
0
Peter Hochstrasser
Hi Gauri Pandit
I migrated from Zendesk to Zendesk, which made some things a bit simpler.
What do you mean by "bulk attachments"?
In Zendesk, you have an arbitrary number of attachments per comment and thus per ticket.
There's a difference between inline attachments (images) and "attached at the end" attachments - data files, text files or what not. The difference is where their descriptor is stored: Inline attachments are not part of the "attachments" array.
May I suggest that you "manually migrate" a few tickets with attachments?
Just create a new Zendesk ticket that looks like and contains all the content elements of the original ticket in your source system. Then, export their JSON structure to find out what needs to be generated, and how things are really stored. Then, the creation of your import code will be a lot easier.
As you saw before, I really imported all attachments before I imported a single ticket. That makes things simpler when importing the tickets themselves.
Yours truly
Peter
1
Peter Hochstrasser
Hi Gary Beichler
Any news from the API documentation regarding attachments?
0
Gauri Pandit
Thanks for the reply!
By Attachments I mean the inline attachments, images. So, I don't have to create a token for these attachments? Any tips, documentation or examples related to inline attachments?
0