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.

NameTypeComment
metadatastringStringified then URL-encoded data about the integration instance. See Metadata and state
statestringStringified 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.

NameTypeMax charsMandatoryComments
external_resourcesarrayyesArray of external resources, up to a maximum of 200. See external_resources array below
statestring5000noStringified data about the new state. If not returned, the pre-existing state value is retained. See Metadata and state.
metadata_needs_updatebooleannoShould the Zendesk Support administrator be asked to revisit the UI for the integration account to reset the metadata?
metadatastring5000noStringified 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:

NameTypeMax charsMandatoryComments
external_idstring255yesUnique identifier of the external resource (string). May not include leading or trailing whitespace. Must be ASCII characters
internal_notebooleannoIf true, the message is an internal note. If false, the message is a public comment. Defaults to false
messagestring65535yesText to be converted to a ticket or comment
html_messagestring65535noHTML version of message
parent_idstring511noUnique 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_idstring511noArbitrary 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_atdatetimeyesWhen the resource was created in the origin system, as an RFC 3339 format date-time. Example: '2015-09-08T22:48:09Z'
authorobjectyesSee author object below
display_infoarraynoArray of integration-specific data used by apps to modify the agent UI. See display_info object below
allow_channelbackbooleannoIf false, prevents the agent from making additional comments on the message in the Zendesk Support interface
fieldsarraynoArray of objects describing a ticket field. See field object below.
file_urlsarraynoArray of files to be imported into Zendesk Support. See file urls below.

author object

NameTypeMax charsMandatoryComments
external_idstring255yesUnique identifier of the user in the origin service. May not include leading or trailing whitespace.
namestring255noIf not supplied, defaults to external id
image_urlstring255noURL to an image for the user
localestring255noThe user's locale. Must be one of the Zendesk Support supported locales.
fieldsarraynoArray of objects describing a user field. See field object below.

display_info object

NameTypeMax charsMandatoryComments
typestring255yesGlobally unique type identifier defined by the integration service. Examples: a GUID or URI
dataobject65535yesJSON 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:

NameComments
idThe ID of the field to be specified. A string for system fields, or a string or integer for custom fields.
valueThe value to be assigned to the field

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

IDValue
subjectSubject of the ticket to be created
statusStatus of the ticket to be created (e.g. 'open'.) Value should be a recognized Zendesk Support status string.
typeType of the ticket to be created (e.g. 'question'.) Value should be a recognized Zendesk Support type string.
priorityPriority of the ticket to be created (e.g. 'high'.) Value should be a recognized Zendesk Support priority string.
groupID of the Zendesk Support group to which the ticket should be assigned
assigneeID of the Zendesk Support user to which the ticket should be assigned
tagsArray of tag strings to be applied to the ticket

In addition, the following values are supported for users:

IDValue
notesNotes on the user
detailsDetails 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:

IDDescriptionValue
any integerThe ID of the custom field to be setThe value to apply to the custom field (allowed values will differ from field to field)
any stringThe name of the custom field to be setThe 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.