Incremental Exports

The endpoints of the incremental export API are for API consumers that want to know what changed in Zendesk Support since they last asked. The API lets you export data without having to pull objects that haven't changed since the last export. It works something like this:

You at 5pm: "Hello Zendesk Support, give me all the tickets that changed since noon."

Zendesk Support: "Sure, here are the tickets that changed since noon up until, and including, 5pm."

You at 7pm: "Okay, now give me the tickets that changed since 5pm."

Zendesk Support: "No problem, here are the tickets that changed since 5pm up until, and including, 7pm."

JSON Format

The exported items are represented as JSON objects. The format depends on the exported resource, but all have the following additional common attributes:

Name Type Read-only Mandatory Comment
end_time date yes no The most recent time present in this result set in Unix epoch time; this should be used as the next start_time
next_page string yes no The URL that should be called to get the next set of results
count integer yes no The number of results returned for the current request

Start Time

The incremental export endpoints take a required start_time parameter expressed as a Unix epoch time. Example:

GET /api/v2/incremental/tickets.json?start_time=1332034771

Requests with a start_time less than 5 minutes old will be rejected.

Side-Loading

The ticket, ticket event, organization, and user incremental export endpoints support side-loading. Add an include request parameter specifying the associations you want to load. Example:

https://{subdomain}.zendesk.com/api/v2/incremental/tickets/sample.json?start_time=1332034771&include=metric_sets

See Side-Loading in the core API docs as well as any specific sideloading information in the endpoint docs below.

Usage Notes

Use this API initially to export a complete list of items from your Zendesk Support instance, then periodically poll the API to incrementally export items that have changed since the previous poll. You shouldn't use this API to repeatedly export complete lists of items.

The API doesn't protect against duplicates if you make requests that cover overlapping periods. The query boils down to searching for items updated after or at your start_time value. The same item can be included in multiple exports if the start time of each request is earlier than the time the item was modified.

Alternatively, you can miss records if you leave gaps between the end_time of the previous request and the start_time of the next.

Polling strategy

To ensure you don't get duplicate records or miss records since the previous export, use the last end_time value of the previous export as the start_time of the next scheduled export. See Pagination below. The end_time value ensures you have seamless coverage without overlaps or gaps between requests.

Excluding deleted tickets

Starting on October 16, 2016, user-provided information in deleted tickets is scrubbed 30 days after deletion. Reporting on deleted tickets remains intact because the ticket record still exists. However, user-provided information (as opposed to system-provided information) is scrubbed with an X for text fields, a 0 for numeric fields, or nothing for fields that didn't have a value. You can exclude these tickets by filtering out any tickets with a "status": "deleted" value.

Excluding system updates

The Incremental Ticket Export endpoint also returns tickets that were updated for reasons not related to ticket events, such as a system update or a database backfill. You can exclude these tickets after getting the results by filtering out any record with an updated_at time that's earlier than the start_time time.

To understand why, it helps to know that the updated_at property is not used for system updates. System updates are recorded by the generated_timestamp property (as are all other ticket updates). The updated_at property is only used for ticket updates that generate a ticket event.

It also helps to know that the endpoint compares the start_time to the updated_at and generated_timestamp values. Therefore, any ticket in the results that was only updated by a system event or a database backfill will have a generated_timestamp that's later than the start_time but an updated_at time that's earlier than the start_time.

Pagination

Unlike other endpoints that return null as the value of the next_page property when reaching the end of the result set, these endpoints return a URL:

"next_page": "https://example.zendesk.com/api/v2/incremental/tickets.json?start_time=1442953046",

The start time is equal to the timestamp of last item in the result set. The URL is meant to be used for the next scheduled export.

When paginating through an incremental export result set, use the count property to determine when to stop. These endpoints return up to 1000 items per page. If count is less than 1000, then stop paginating. Otherwise, use the next_page URL to get the next page of results.

Rate limits

You can make up to 10 requests per minute to these endpoints.

The rate limiting mechanism behaves identically to the one described in Rate Limits in the API introduction. We recommend using the Retry-After header value as described in Catching errors caused by rate limiting.

If you find yourself bumping into the rate limit when testing the API, see Incremental Sample Export below to test the API without getting throttled continuously.

Incremental Ticket Export

GET /api/v2/incremental/tickets.json?start_time={unix_time}

Returns the tickets that changed since the start time. See Usage Notes above.

The results include tickets that were updated by the system. See Excluding system updates.

The endpoint can return records where the updated_at time is earlier than the start_date time. The reason is that the updated_at value is updated only if the ticket update generates a ticket event. Otherwise, the timestamp of the previous update carries over.

Allowed For
  • Admins
Sideloading

See Tickets sideloads. For performance reasons, last_audits sideloads aren't supported.

Using curl
curl https://{subdomain}.zendesk.com/api/v2/incremental/tickets.json?start_time=1332034771 \
  -v -u {email_address}:{password}
Example Response

See Tickets for a detailed example.

Status: 200 OK

{
  "end_time": 1383685952,
  "next_page": "https://{subdomain}.zendesk.com/api/v2/incremental/tickets.json?start_time=1383685952",
  "count": 1,
  "tickets": [
    {
      "url": "https://{subdomain}.zendesk.com/api/v2/tickets/1.json",
      "id": 2,
      "created_at": "2012-02-02T04:31:29Z",
      "generated_timestamp": 1390362285
      ...
     },
     ...
  ]
}

Incremental Ticket Event Export

GET /api/v2/incremental/ticket_events.json?start_time={unix_time}

Returns a stream of changes that occurred on tickets. Each event is tied to an update on a ticket and contains all the fields that were updated in that change.

You can include comments in the event stream by using the comment_events sideload. See Sideloading below. If you don't specify the sideload, any comment present in the ticket update is described only by Boolean comment_present and comment_public object properties in the event's child_events array. The comment itself is not included.

Allowed For
  • Admins
Sideloading

The endpoint supports the comment_events sideload. Any comment present in the ticket update is listed as an object in the event's child_events array. Example:

"child_events": [
  {
    "id": 91048994488,
    "via": {
      "channel": "api",
      "source": {"from":{},"to":{},"rel":null}},
    "via_reference_id":null,
    "type": "Comment",
    "author_id": 5031726587,
    "body": "This is a comment",
    "html_body": "<div class="zd-comment"><p dir="auto">This is a comment</p>",
    "public": true,
    "attachments": [],
    "audit_id": 91048994468,
    "created_at": "2009-06-25T10:15:18Z",
    "event_type": "Comment"
  },
  ...
],
...
Using curl
curl https://{subdomain}.zendesk.com/api/v2/incremental/ticket_events.json?start_time=1332034771 \
   -v -u {email_address}:{password}
Example Response
Status: 200 OK

{
  "ticket_events": [
    {
      "id": 1717,
      "ticket_id": 27,
      "timestamp": 138561439,
      "updater_id": -1,
      "via": "Email",
      "child_events": [
        {
          "via": "Email",
          "via_reference_id": 2,
          "status": "solved"
        }
      ]
    },
   ...
  ]
  "next_page": "http://{subdomain}.zendesk.com/api/v2/incremental/ticket_events.json?start_time=1389078385",
  "count": 1000,
  "end_time": 1389078385
}

Incremental Organization Export

GET /api/v2/incremental/organizations.json?start_time={unix_time}

Allowed For
  • Admins
Sideloading

See Organizations sideloads.

Using curl
curl https://{subdomain}.zendesk.com/api/v2/incremental/organizations.json?start_time=1332034771 \
  -v -u {email_address}:{password}
Example Response

See Organizations for a detailed example.

Status: 200 OK

{
  "organizations": [
    {
      "url": "https://{subdomain}.zendesk.com/api/v2/organizations/11.json",
      "id": 11,
      "name": "Dev",
      "tags": ['awesome_customer'],
      ....
      "organization_fields": {
        "numeric_field": 12345,
      }
    }
  ]
  "next_page": "https://{subdomain}.zendesk.com/api/v2/incremental/organizations.json?start_time=1383685952",
  "count": 1,
  "end_time": 1383685952,
}

Incremental User Export

GET /api/v2/incremental/users.json?start_time={unix_time}

Allowed For
  • Admins
Sideloading

See Users sideloads.

Using curl
curl https://{subdomain}.zendesk.com/api/v2/incremental/users.json?start_time=1332034771 \
  -v -u {email_address}:{password}
Example Response

See Users for a detailed example.

Status: 200 OK

{
  "users": [
    {
      "id": 11,
      "url": "http://{subdomain}.zendesk.com/api/v2/users/11.json",
      "name": "Agent Extraordinaire",
      ...
      "user_fields": {
        "field1": 0,
        "field2": 'value2'
      }
    }
  ]
  "next_page": "http://{subdomain}.zendesk.com/api/v2/incremental/users.json?start_time=1383685952",
  "count": 1,
  "end_time": 1383685952
}

Incremental Sample Export

GET /api/v2/incremental/{item}/sample.json

where {item} is the resource requested, such as tickets, users, or organizations.

Use this endpoint to test the incremental export format. It's more relaxed in terms of rate limiting, but only returns up to 50 records. Otherwise, it's identical to the above APIs.

Using curl
curl https://{subdomain}.zendesk.com/api/v2/incremental/tickets/sample.json?start_time=1332034771 \
 -v -u {email_address}:{password}

Incremental Ticket Metric Event Export

See List Ticket Metric Events.

NPS Incremental Export

See NPS Incremental Exports in the NPS API docs.

Incremental Article Export

See List Articles in the Help Center API docs.