# Moving tickets from Zendesk to JSM Cloud

**URL:** <https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672>\
**Category:** General Questions\
**Tags:** cloud-jira, cloud-zendesk\
**Created:** [January 27, 2026, 8:45am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672 "2026-01-27T08:45:16Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![urmo](https://avatars.discourse-cdn.com/v4/letter/u/c5a1d2/32.png) [@urmo](https://community.exalate.com/u/urmo)\
**Post date:** [January 27, 2026, 8:45am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/1 "2026-01-27T08:45:16Z")

</div>

Hi  
Exalate support give idea that community can help 🙂

I have created connection between Zendesk and JSM with plan move all tickets from Zendesk to JSM. Now i have allready set up some connection and i have some fields what i need to get into JSM also. Yes i know that i cant have assignee and reporter because lot of people have left and Atlassian Cloud does not support accountID if there is no license. But i created allready customfields into JSM

## **Zendesk\_Assignee**

{ @key : 16609674611740}

## **Zendesk\_Reporter**

{ @key : 16609674611740}

Right now there is key but how i could get into there e-mail address from orginal user?

Also in zendesk is

- cc\_emails
- email\_cc\_ids
- followers\_ids

How i should write mapping for this e-mail values to get into customfield JSM?

with best  
Urmo

---

<div class="post-metadata">

**Author:** ![Aida](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/aida/32/580_2.png) [@Aida](https://community.exalate.com/u/Aida)\
**Post date:** [January 27, 2026, 8:45am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/2 "2026-01-27T08:45:33Z")

</div>

Great to see you’re making progress with your Zendesk to Jira Service Management (JSM) Cloud migration! You’re right about the assignee/reporter limitations in Atlassian Cloud—if the user doesn’t exist or lacks a license, you can’t set them as the actual assignee/reporter, but you can store their info in custom fields.

To map Zendesk user fields (like assignee, reporter, cc\_emails, etc.) to custom fields in JSM and store their email addresses, you’ll want to extract the email from the Zendesk ticket and set it into your JSM custom field during the sync.

Here’s how you can approach this in your Exalate sync script (on the JSM incoming side):

- For the Zendesk assignee’s email:

```groovy
issue.customFields."Zendesk_Assignee" = replica.assignee?.email

```

- For the Zendesk reporter’s email:

```groovy
issue.customFields."Zendesk_Reporter" = replica.reporter?.email

```

- For cc\_emails (which is usually a list), you can join them into a string or handle as needed:

```groovy
issue.customFields."Zendesk_CC_Emails" = replica.cc_emails?.join(", ")

```

- For email\_cc\_ids or followers\_ids, you’ll need to fetch the corresponding user objects and extract their emails, if available in the replica.

If you want to see more advanced user field mapping examples (including handling cases where emails aren’t available), check out the official documentation:

> **[How to Sync Issue User Fields in Jira Cloud](https://docs.exalate.com/docs/how-to-sync-issue-user-fields-in-jira-cloud)**
>
> This article describes how to synchronize Jira issue fields, that include users.

And for more Zendesk-Jira integration use cases and script ideas:

> **[Jira Zendesk Integration Using Exalate](https://docs.exalate.com/docs/jira-and-zendesk-integration)**
>
> Explore how to set up an advanced Jira Zendesk integration using Exalate, with real-world use cases.

This approach will let you preserve the original user information in your custom fields, even if you can’t set them as the actual assignee/reporter in JSM Cloud.

---

<div class="post-metadata">

**Author:** ![urmo](https://avatars.discourse-cdn.com/v4/letter/u/c5a1d2/32.png) [@urmo](https://community.exalate.com/u/urmo)\
**Post date:** [January 28, 2026, 8:51am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/3 "2026-01-28T08:51:58Z")

</div>

How to get zendesk ticket created time into jira customfield **Zendesk\_createddate**?

---

<div class="post-metadata">

**Author:** ![Dhiren](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/dhiren/32/356_2.png) [@Dhiren](https://community.exalate.com/u/Dhiren)\
**Post date:** [February 2, 2026, 11:27am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/4 "2026-02-02T11:27:22Z")

</div>

Hi @urmo ,

Could you please help me capture the **Zendesk ticket created timestamp** and send it through the replica?

### Preferred (simple) approach

On the **Zendesk outgoing sync** , can you add:

```auto
replica.zendeskCreated = issue.created

```

Once we see `zendeskCreated` in the payload, mapping it on the Jira/JSM incoming side becomes straightforward:

```auto
issue.customFields."Zendesk_createddate".value = replica.zendeskCreated

```

### Fallback (only if the above doesn’t show in payload)

If `issue.created` is not available / not coming through correctly, we can fetch it directly from the Zendesk API, parse it, and then pass it via the replica.

Example:

```auto
def response = httpClient.get("/api/v2/tickets/${ticket.id}.json")
def createdAt = response?.ticket?.created_at // e.g. "2026-02-02T10:15:30Z"
replica.zendeskCreated = createdAt

```

Then we can map the same way on Jira:

```auto
issue.customFields."Zendesk_createddate".value = replica.zendeskCreated

```

If you can add the **simple line first** and confirm whether `zendeskCreated` appears in the outgoing payload, that would be ideal — we may not need the API route at all.

Thanks, Dhiren!

---

<div class="post-metadata">

**Author:** ![urmo](https://avatars.discourse-cdn.com/v4/letter/u/c5a1d2/32.png) [@urmo](https://community.exalate.com/u/urmo)\
**Post date:** [February 3, 2026, 1:08pm UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/5 "2026-02-03T13:08:16Z")

</div>

Hi

I updated Outgoing sync:  
_// Set Zendesk\_follow to a comma-separated list of follower emails, only if the field exists_

_if (issue.customFields.containsKey(‘Zendesk\_follow’)) {_

```
*if (replica.followers instanceof List) {*

    *issue.customFields.'Zendesk_follow'.value = replica.followers.collect { it?.email ?: '' }.findAll { it }.join(', ')*

*} else {*

    *issue.customFields.'Zendesk_follow'.value = ''*

*}*

```

_}_

_// Set Zendesk\_cc to a comma-separated list of CC emails, only if the field exists_

_if (issue.customFields.containsKey(‘Zendesk\_cc’)) {_

```
*if (replica.ccs instanceof List) {*

    *issue.customFields.'Zendesk_cc'.value = replica.ccs.collect { it?.email ?: '' }.findAll { it }.join(', ')*

*} else {*

    *issue.customFields.'Zendesk_cc'.value = ''*

*}*

```

_}_

_// Map other fields as per current configuration_

_replica.summary = issue.summary_

_replica.comments = issue.comments_

_replica.attachments = issue.attachments_

_replica.type = issue.type_

_replica.status = issue.status_

_replica.priority = issue.priority_

_replica.assignee = issue.assignee_

_replica.reporter = issue.reporter_

_replica.key = issue.key_

_replica.labels = issue.labels_

_replica.description = issue.description_

_replica.zendeskCreated = issue.created_

And incoming sync:

_// Helper function to safely set a custom field value if the field exists_

_void setCustomFieldValue(issue, fieldName, value) {_

```
*if (issue.customFields\[fieldName\] != null) {*

    *issue.customFields\[fieldName\].value = value*

*}*

```

_}_

_if (firstSync) {_

```
*issue.projectKey = "ZEN"*

```

_}_

_def defaultUser = nodeHelper.getUserByEmail(“jira-placeholder@lhv.ee”)_

_issue.reporter = nodeHelper.getUserByEmail(replica.requester?.email) ?: defaultUser_

_issue.assignee = nodeHelper.getUserByEmail(replica.assignee?.email) ?: defaultUser_

_// Set custom field Zendesk\_follow to comma-separated emails from followers, or empty string_

_// if (replica.followers instanceof List) {_

_// setCustomFieldValue(issue, “Zendesk\_follow”, replica.followers.collect { it?.email }.findAll { it }.join(“,”))_

_// } else {_

_// setCustomFieldValue(issue, “Zendesk\_follow”, “”)_

_// }_

_// Set summary: use replica.summary if not empty/null, otherwise use replica.key if not empty/null, otherwise default_

_if (replica.summary?.trim()) {_

```
*// Replace all newline characters in the summary with a space*

*issue.summary = replica.summary.replaceAll(/\[\\r\\n\]+/, ' ')*

```

_} else if (replica.key?.trim()) {_

```
*issue.summary = replica.key*

```

_} else {_

```
*issue.summary = 'No summary provided'*

```

_}_

_issue.description = replica.description_

_issue.comments = commentHelper.mergeComments(issue, replica)_

_issue.attachments = attachmentHelper.mergeAttachments(issue, replica)_

_issue.labels = replica.labels_

_issue.type = nodeHelper.getIssueType(replica.type?.name, issue.projectKey) ?: nodeHelper.getIssueType(“Zendesk”, issue.projectKey)_

_def priorityMap = [_

```
*"urgent": "Highest",*

*"high" : "High",*

*"normal": "Medium",*

*"low" : "Low"*

```

_]_

_def priorityName = priorityMap[replica.priority?.name?.toLowerCase()] ?: “Medium”_

_issue.priority = nodeHelper.getPriority(priorityName)_

_// FIX: Improve status mapping to be case-insensitive and include missing statuses_

_def statusMap = [_

```
*"new" : "Open",*

*"open" : "Open", // Added mapping for "open"*

*"pending" : "In Progress",*

*"waiting" : "In Progress",*

*"solved" : "Closed",*

*"rejected" : "Closed",*

*"done" : "Closed"*

```

_]_

_def remoteStatusName = replica.status?.name?.toLowerCase()_

_// Only update status if a valid mapping exists to avoid accidental changes_

_if (statusMap.containsKey(remoteStatusName)) {_

```
*issue.setStatus(statusMap\[remoteStatusName\])*

```

_}_

_// Set custom fields for created date and key_

_issue.customFields.“Zendesk\_createddate”.value = replica.zendeskCreated_

_setCustomFieldValue(issue, “Zendesk\_key”, replica.key)_

_setCustomFieldValue(issue, “Zendesk\_Assignee”, replica.assignee?.email)_

_setCustomFieldValue(issue, “Zendesk\_Reporter”, replica.reporter?.email)_

_setCustomFieldValue(issue, “Zendesk\_CC\_Emails”, replica.cc\_emails?.join(", "))_

_setCustomFieldValue(issue, “Zendesk\_follow”, replica.followers?.join(", "))_

Seems to be that right now we don’t get over _Zendesk\_createddate, Zendesk\_CC\_Emails_ and _Zendesk\_follow._

Maybe there is still some issue what i did wrong in configuration?

with best  
Urmo

---

<div class="post-metadata">

**Author:** ![Dhiren](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/dhiren/32/356_2.png) [@Dhiren](https://community.exalate.com/u/Dhiren)\
**Post date:** [February 11, 2026, 11:42am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/6 "2026-02-11T11:42:19Z")

</div>

Hi Urmo,

The issue is most likely on the Zendesk outgoing side.

Right now you’re trying to set JSM custom fields (`issue.customFields`) in the Zendesk outgoing script — that won’t work. The outgoing script should only populate the **replica** , not custom fields.

Please make sure you’re setting things like followers, CCs and created date on the `replica` (e.g. `replica.zendeskFollowers`, `replica.zendeskCCs`, `replica.zendeskCreated`) and then map those exact fields in the JSM incoming script.

Also double-check that the field names match exactly between outgoing and incoming — at the moment you’re referencing fields in incoming that were never added to the replica.

First step: check the **Replica tab** and confirm those fields are visible there. If they’re not in the replica, they can’t be mapped in JSM.

Let me know what you see there 👍

Thanks,  
Dhiren

---

<div class="post-metadata">

**Author:** ![Dhiren](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/dhiren/32/356_2.png) [@Dhiren](https://community.exalate.com/u/Dhiren)\
**Post date:** [February 17, 2026, 4:41am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/7 "2026-02-17T04:41:45Z")

</div>

Hi @urmo ,

Just following up on my previous comment

Were you able to try my suggestions?

Let me know if you face any issues.

Thanks, Dhiren

---

<div class="post-metadata">

**Author:** ![urmo](https://avatars.discourse-cdn.com/v4/letter/u/c5a1d2/32.png) [@urmo](https://community.exalate.com/u/urmo)\
**Post date:** [February 18, 2026, 9:47am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/8 "2026-02-18T09:47:48Z")

</div>

Hi

I must say that i’m out of ideas how to get followers, CC and zendesk ticket created time over to Jira.

In zendesk created should be behind **created\_at** field - [Tickets](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/) .

outgoing side

```auto
replica.created_at = issue.customFields."Zendesk_createddate"

```

incoming side

```auto
setCustomFieldValue(issue, "Zendesk_createddate", replica.created_at)

```

Still no time coming to Jira.

Same issue with followers and cc values.

outgoing side

```auto
replica.follower_names = issue.customFields."Zendesk_follow"

```

Incoming side

```auto
// Set custom field Zendesk_follow to comma-separated emails from followers, or empty string
if (replica.follower_names instanceof List) {
    def emails = replica.follower_names.collect { it?.email }.findAll { it }.join(",")
    setCustomFieldValue(issue, "Zendesk_follow", emails)
} else {
    setCustomFieldValue(issue, "Zendesk_follow", "")
}

```

outgoing side

```auto
replica.email_ccs = issue.customFields."Zendesk_cc"

```

Incoming side

```auto
setCustomFieldValue(issue, "Zendesk_cc", replica.cc_emails?.join(", "))

```

I’m not sure that fields are correct in zendesk and logic to import into jira also.

With best

Urmo

---

<div class="post-metadata">

**Author:** ![Dhiren](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/dhiren/32/356_2.png) [@Dhiren](https://community.exalate.com/u/Dhiren)\
**Post date:** [February 23, 2026, 6:12am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/9 "2026-02-23T06:12:19Z")

</div>

Hi @urmo ,

I figured out a way already to sync the actual created date of an issue from Zendesk to a custom field in Jira.

It requires httpClient() and can also be used to transfer email, cc, followers etc in the same way.

Here’s an example for you.

ZD Outgoing  
`def response = httpClient.get("/api/v2/tickets/${ticket.id}")`  
`def createdDate = ("${response.ticket.created_at}")`  
`replica."Zendesk Created Date" = createdDate`

Jira Incoming  
`//please note that the custom field used is of type Date Picker`  
`import java.text.SimpleDateFormat;`  
`import java.text.DateFormat;`  
` `  
`def dateCustomFieldValue(replicaCustomField) {`  
` def datePattern = "yyyy-MM-dd"; // define the desired date/time format`  
` String dateString = replicaCustomField`  
` if (dateString) {`  
` dateString = dateString.replaceAll("\"","").trim();`  
` DateFormat formatter = new SimpleDateFormat(datePattern);`  
` date = formatter.parse(dateString);`  
` return new java.sql.Timestamp(date.time);`  
` }`  
`}`  
`issue.customFields."Jira Date Custom".value = dateCustomFieldValue(replica."Zendesk Created Date".values[0])`

Let me know if you face any issues in this.

Thanks, Dhiren

---

<div class="post-metadata">

**Author:** ![urmo](https://avatars.discourse-cdn.com/v4/letter/u/c5a1d2/32.png) [@urmo](https://community.exalate.com/u/urmo)\
**Post date:** [February 23, 2026, 9:29am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/10 "2026-02-23T09:29:01Z")

</div>

Hi

Tnx for helping and now i have time value but how should get cc and followers also to work because i tryd to debug with gemini and i must say it did not help me at all.

Urmo

---

<div class="post-metadata">

**Author:** ![Dhiren](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/dhiren/32/356_2.png) [@Dhiren](https://community.exalate.com/u/Dhiren)\
**Post date:** [February 25, 2026, 9:29am UTC](https://community.exalate.com/t/moving-tickets-from-zendesk-to-jsm-cloud/7672/11 "2026-02-25T09:29:50Z")

</div>

Hi @urmo ,

In my previous example, I showed the usage of httpClient() to fetch information from the Zendesk Ticket which is directly not available on the ticket.

The same logic should work for cc and followers as well.

“follower\_ids” ,“email\_cc\_ids” should be the fields that you should be looking at.

In the ZD outgoing please try something like this

`def response = httpClient.get("/api/v2/tickets/${ticket.id}")`  
`debug.error("${response}")`

This way you can print the entire response, and then you need to simply add the fields to the replica which you would like to send.

You can refer to this doc as well for more info : [Make REST API Calls with HTTP Client | Exalate Docs](https://docs.exalate.com/docs/how-to-make-rest-api-calls-with-the-http-client)

Thanks, Dhiren
