You can provide an endpoint that lets Zendesk Support periodically query for new external resources in the origin system, such as for new comments in Instagram. The queries are known as pull requests or simply pulls. Zendesk Support makes a pull request approximately every 2 minutes.

To enable this feature, you must build a pull endpoint and specify its url in the integration manifest. Example:

"urls": {  "pull_url":"https://omniwear.com/integrations/instagram/pull",  ...}

The endpoint must implement the request and response formats described in this document. Your endpoint is responsible for retrieving the resources in the origin system.

Request format

Zendesk Support makes a request approximately every 2 minutes to the pull_url endpoint specified in your integration manifest. Zendesk Support includes the following query string parameters in the body of each POST request.

Name Type Comment
metadata string Stringified then URL-encoded data about the integration instance. See Metadata and state
state string Stringified then URL-encoded data about the current state. See Metadata and state

Examples

The body of a POST request could contain the following data for an Instagram integration service:

metadata=%7B%5C%22instagram_username%5C%22%3A%5C%22omniwear%5C%22%2C%5C%22instagram_oauth_token%5C%22%3A%5C%22xyzabc%5C%22%7D&state=%7B%5C%22last_message_id%5C%22%3A%5C%2220151210082800-erika%5C%22%7D

The URL-encoded query string is a bit hard to read. The decoded string looks as follows:

metadata={\"instagram_username\":\"omniwear\",\"instagram_oauth_token\":\"xyzabc\"}&state={\"last_message_id\":\"20151210082800-erika\"}

If your integration service doesn't use Zendesk Support to store state, the pull request could look as follows:

https://omniwear.com/integrations/instagram/pull?metadata=%7B%5C%22integration_service_info_id%5C%22%3A%5C%22123%5C%22%7D&state=

Decoded string:

metadata={\"integration_service_info_id\":\"123\"}&state=

Response format

Send a response with the following JSON object containing an ordered array of up to 200 external resources. Zendesk Support will process them in order.

Name Type Max chars Mandatory Comments
external_resources array yes Array of external resources, up to a maximum of 200. See external_resources array below
state string 5000 no Stringified data about the new state. If not returned, the pre-existing state value is retained. See Metadata and state.
metadata_needs_update boolean no Should the Zendesk Support administrator be asked to revisit the UI for the integration account to reset the metadata?
metadata string 5000 no Stringified data about the integration instance. See Metadata and state

external_resources array

Each external resource in the array consists of an object with the following properties:

Name Type Max chars Mandatory Comments
external_id string 255 yes Unique identifier of the external resource (string). May not include leading or trailing whitespace. Must be ASCII characters
internal_note boolean no If true, the message is an internal note. If false, the message is a public comment. Defaults to false
message string 65535 yes Text to be converted to a ticket or comment
html_message string 65535 no HTML version of message
parent_id string 511 no Unique identifier of the external resource for which this is a response. Used to choose the correct thread. Responses may include parent_id or thread_id, but not both. See Conversation threads
thread_id string 511 no Arbitrary identifier of the thread to which this item should belong. Responses may include parent_id or thread_id, but not both. See Conversation threads
created_at datetime yes When the resource was created in the origin system, as an RFC 3339 format date-time. Example: '2015-09-08T22:48:09Z'
author object yes See author object below
display_info array no Array of integration-specific data used by apps to modify the agent UI. See display_info object below
allow_channelback boolean no If false, prevents the agent from making additional comments on the message in the Zendesk Support interface
fields array no Array of objects describing a ticket field. See field object below.
file_urls array no Array of files to be imported into Zendesk Support. See file urls below.

author object

Name Type Max chars Mandatory Comments
external_id string 255 yes Unique identifier of the user in the origin service. May not include leading or trailing whitespace.
name string 255 no If not supplied, defaults to external id
image_url string 255 no URL to an image for the user
locale string 255 no The user's locale. Must be one of the Zendesk Support supported locales.
fields array no Array of objects describing a user field. See field object below.

display_info object

Name Type Max chars Mandatory Comments
type string 255 yes Globally unique type identifier defined by the integration service. Examples: a GUID or URI
data object 65535 yes JSON data containing display hints

field object

The field object contains a field ID and value. When Zendesk Support makes a new ticket or user on behalf of the integration service, Zendesk will attempt to set a field values for the item as specified by this object. When creating a comment on an existing ticket, Zendesk Support will ignore the field objects.

The field object looks as follows:

Name Comments
id The ID of the field to be specified. A string for system fields, or a string or integer for custom fields.
value The value to be assigned to the field

The ID may refer to a system field. If so, the following values are supported for tickets:

ID Value
subject Subject of the ticket to be created
status Status of the ticket to be created (e.g. 'open'.) Value should be a recognized Zendesk Support status string.
type Type of the ticket to be created (e.g. 'question'.) Value should be a recognized Zendesk Support type string.
priority Priority of the ticket to be created (e.g. 'high'.) Value should be a recognized Zendesk Support priority string.
group ID of the Zendesk Support group to which the ticket should be assigned
assignee ID of the Zendesk Support user to which the ticket should be assigned
tags Array of tag strings to be applied to the ticket

In addition, the following values are supported for users:

ID Value
notes Notes on the user
details Details about the user

Alternatively, the ID may refer to a custom field. If so, it may refer to the custom field by ID or name:

ID Description Value
any integer The ID of the custom field to be set The value to apply to the custom field (allowed values will differ from field to field)
any string The name of the custom field to be set The value to apply to the custom field (allowed values will differ from field to field)

file urls

The file urls array contains URLs to files that will be attached to the Zendesk Support ticket or comment. File URLs are subject to a number of limitations:

  • URLs must be HTTPS
  • URLs may be relative URLs. If relative, they will be resolved relative to the manifest URL for the integration service.
  • Files must be hosted on the same subdomain as the manifest
  • A maximum of 10 files per external resource are supported
  • The maximum size of a file varies from Zendesk Support account to account
  • File downloads are subject to timeouts. Zendesk imposes a timeout on the total conversion process, including API calls and file downloads. This implies that slow API calls will restrict the time available to perform downloads.

When Zendesk imports an external resource, it performs a POST request to each of the file URLs. The body of the request is a JSON object containing the integration instance metadata at the key "metadata" (see Metadata and state). File download failures are not fatal -- they do not stop the import process. A failure to download and process a file does not affect the processing of other files for the same external resource.

Example

{  "external_resources":[    {      "external_id": "20151210083000-amy",      "message":     "Please help. My printer is on fire.",      "html_message": "Please help. <b>My printer is on fire.</b>",      "created_at":  "2015-09-08T22:48:09Z",      "author": {        "external_id": "a2466",        "name":        "Amy",        "image_url":   "https://scontent.cdninstagram.com/hphotos-xap1/t51.2885-19/s150x150/12424615_209564492716268_42714239_a.jpg",        "locale":     "de",        "fields": [          { "notes": "A virgo who loves long walks on the beach" }        ]      },      "display_info": [{        "type": "omniwear.com/integrations/instagram/display/comment/v1",        "data": "{\"priority\": \"high\"}"      }],      "allow_channelback": false    },    {      "external_id": "20151210083200-bob",      "internal_note": true,      "message":     "There is no sand, blanket or fire extinguisher near by.",      "created_at":  "2015-09-08T22:48:12Z",      "parent_id":   "20151210083000-amy",      "author": {        "external_id": "a2466",        "name":        "Amy",        "image_url":   "https://scontent.cdninstagram.com/hphotos-xap1/t51.2885-19/s150x150/12424615_209564492716268_42714239_a.jpg",      },      "display_info": [{        "type": "omniwear.com/integrations/instagram/display/comment/v1",        "data": "{\"priority\": \"medium\"}"      }],      "allow_channelback": false    }  ],  "state": "{\"last_message_id\":\"20151210083200-bob\"}"}

Conversation threads

Zendesk Support uses parent_id or thread_id to link multiple resources in the external system into conversation threads, which are roughly synonymous with tickets. Integration services can send either argument, or neither. Supplying both is not supported.

  • parent_id This describes a ‘reply to’ relationship.

Example: Frank sends an email to Bob. This email has ID 123. Bob replies to Frank. His reply has ID 234. When sending data about Bob's email to Zendesk Support, the external_id is '234', and the parent_id is '123'

  • thread_id This allows the integration service to designate multiple external resources the same Zendesk Support ticket.

For example, if the customer wants all external resources where the word ‘Endgame’ appears inside the same ticket, the integration service can give ‘thread_endgame’ as the thread_id to all external resources that match the description. Zendesk Support will put all of them into the same ticket.

If there is no parent_id and no thread_id, the external resource becomes a new ticket in Zendesk Support.

If there is a parent_id and Zendesk Support already has a ticket that includes content from that parent, the external resource becomes a comment of that ticket. If Zendesk Support hasn’t seen the parent_id before, the external resource becomes a new ticket.

If there is a thread_id and Zendesk Support already has a ticket for that thread_id, the external resource becomes a comment on that ticket. If Zendesk Support hasn’t seen the thread_id before, the external resource becomes a new ticket.

When Zendesk Support creates a new thread for an external resource that does not have a thread_id, the ID of the new thread will be the external_id of the resource. For example, suppose Zendesk Support processes the following data:

{"external_id": "234", "parent_id": "123", "message": "Hey, what's up?"}

and Zendesk Support has not seen item 123. it will create a new ticket for "Hey, what's up?", and the thread_id will be “234”.

If Zendesk Support subsequently processes the following:

{"external_id": "345", "thread_id": "234", "message": "Not much, you?"}

then Zendesk Support will create a comment on the ticket for "Not much, you?"

Duplicated items

If Zendesk Support receives an external resource with an external_id that it has already seen, it ignores the duplicated or modified external resource. Integration services may freely resend external resources when there is any communication failure.

However, sending the same resources multiple times not only makes the API payload bigger, it also means Zendesk Support needs to do more work to de-duplicate the resources. For performance reasons, it is highly recommended that integration services send each external resource exactly once in normal operation.

Zendesk Support also recognizes external resources that were created by channelback. An integration service does not need to have any logic for distinguishing external resources created by Zendesk Support versus any other external resources. See the channelback response format for more information.

Recognized error responses

There are 2 kinds of errors when handling channel integration.

  • Recoverable - These are errors like throttled or timeout errors. Zendesk Support will retry up to 5 times and will continue polling when the next cycle comes. The following response codes are treated as recoverable errors: Request Timeout (408), Internal Server Error (500), Bad Gateway (502), Service Unavailable (503), and Gateway Timeout (504)

  • Irrecoverable - This includes errors like authentication or version-no-longer-supported errors. Example: 401 Unauthorized. Zendesk Support will stop communicating with the integration service. Zendesk Support will contact the administrator and ask them to upgrade or reauthorize the integration service.

Concurrency

Zendesk Support makes polling calls sequentially. Integration services generally do not need to worry about concurrent polling or channelback requests within a particular instance. However, timeouts or network errors could create scenarios where multiple requests are processed by the integration service for a single integration instance concurrently.

Timeout

Zendesk Support sets a 20-second timeout when pulling content from an integration service. If a pull call times out, Zendesk Support will send the same pull state argument the next time it polls.

Idempotency

Zendesk Support periodically makes API calls to the integration service. Those calls may fail due to network issues or other problems. Zendesk Support will handle failures, and retry failed calls as appropriate. If the integration service is idempotent, then these retries will assure that Zendesk Support receives all content.

Zendesk doesn’t require that the integration service API be strictly idempotent. Repeated calls with the same arguments don’t need to result in exactly the same response. To prevent missing external resources, each response to a repeated call should contain all external resources returned by the earlier response (but could contain more).

Integration services that store state locally need to be careful to make sure external resources are not dropped due to a state change on the integration service. For example, suppose the integration service keeps track of the timestamp of the most recently returned external resource timestamp. It resets this timestamp each time it returns data to Zendesk Support. Subsequent responses include only external resources created after that timestamp. If the integration service returns external resources, but Zendesk Support fails to record them, those external resources will be lost forever. Zendesk suggests that an integration service store a version or timestamp in Zendesk Support state data rather than locally. That way, when Zendesk Support retries a call, the integration service knows which external resources are not yet in Zendesk Support.