Audits are a read-only history of all updates to a ticket. When a ticket is updated in Zendesk Support, an audit is stored. Each audit represents a single update to the ticket. An update can consist of one or more events. Examples:

  • The value of a ticket field was changed
  • A new comment was added
  • Tags were added or removed
  • A notification was sent

For a complete list, see the Ticket Audit events reference.

Required OAuth scope

The Ticket Audits endpoints require a global "read" scope for OAuth authentication. You can't access the endpoints using the "auditlogs:read" or "tickets:read" scopes.

JSON format

Ticket Audits are represented as JSON objects with the following properties:

NameTypeRead-onlyMandatoryDescription
author_idintegertruefalseThe user who created the audit
created_atstringtruefalseThe time the audit was created
eventsarrayfalsefalseAn array of the events that happened in this audit. See the Ticket Audit events reference
idintegertruefalseAutomatically assigned when creating audits
metadataobjecttruefalseMetadata for the audit, custom and system data
ticket_idintegertruefalseThe ID of the associated ticket
viaobjectfalsefalseDescribes how the object was created. See the Via object reference

Example

{  "author_id": 35436,  "created_at": "2009-07-20T22:55:29Z",  "events": [    {      "attachments": [],      "body": "Thanks for your help!",      "id": 1564245,      "public": true,      "type": "Comment"    },    {      "body": "Ticket #47 has been updated",      "id": 1564246,      "subject": "Your ticket has been updated",      "type": "Notification"    }  ],  "id": 35436,  "metadata": {    "custom": {      "time_spent": "3m22s"    },    "system": {      "ip_address": "184.106.40.75"    }  },  "ticket_id": 47,  "via": {    "channel": "web"  }}

List All Ticket Audits

  • GET /api/v2/ticket_audits
  • GET /api/v2/ticket_audits.json?cursor=fDE1MDE1OTE1MzQuMHx8MTEzMjQ4NDI1MQ%3D%3D

Returns ticket audits. Archived tickets are not included in the response. Use the List Audits for a Ticket endpoint to retrieve audit records for an archived ticket. To learn more about archived tickets, see About archived tickets.

This endpoint should not be used for capturing change data. When continually chasing the tail of a cursor, some records will be skipped. For this use case, use the Incremental Ticket Event Export API.

Pagination

  • Cursor pagination

See Pagination.

Returns a maximum of 100 records per page.

Allowed For

  • Admins

Parameters

NameTypeInRequiredDescription
limitintegerQueryfalseMaximum number of results returned

Code Samples

curl
curl https://{subdomain}.zendesk.com/api/v2/ticket_audits.json?limit=1000 \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/ticket_audits?limit="	method := "GET"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Content-Type", "application/json")	req.Header.Add("Authorization", "Basic <auth-value>") // Base64 encoded "{email_address}/token:{api_token}"
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.zendesk.com/api/v2/ticket_audits")		.newBuilder()		.addQueryParameter("limit", "");String userCredentials = "your_email_address" + "/token:" + "your_api_token";String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("GET", null)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'GET',  url: 'https://example.zendesk.com/api/v2/ticket_audits',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },  params: {    'limit': '',  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.zendesk.com/api/v2/ticket_audits?limit="headers = {	"Content-Type": "application/json",}email_address = 'your_email_address'api_token = 'your_api_token'# Use basic authenticationauth = HTTPBasicAuth(f'{email_address}/token', api_token)
response = requests.request(	"GET",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/ticket_audits")uri.query = URI.encode_www_form("limit": "")request = Net::HTTP::Get.new(uri, "Content-Type": "application/json")email = "your_email_address"api_token = "your_api_token"credentials = "#{email}/token:#{api_token}"encoded_credentials = Base64.strict_encode64(credentials)request["Authorization"] = "Basic #{encoded_credentials}"response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|	http.request(request)end

Example response(s)

200 OK
// Status 200 OK
{  "after_cursor": "MTUwMTYwNzUyMi4wfHwxMzQ3NTMxNjcxfA==",  "after_url": "https://subdomain.zendesk.com/api/v2/ticket_audits.json?cursor=MTUwMTYwNzUyMi4wfHwxMzQ3NTMxNjcxfA%3D%3D&limit=1000",  "audits": [    {      "author_id": 35436,      "created_at": "2011-09-25T22:35:44Z",      "events": [        {          "attachments": [],          "body": "Thanks for your help!",          "id": 1564245,          "public": true,          "type": "Comment"        },        {          "body": "Ticket #47 has been updated",          "id": 1564246,          "subject": "Your ticket has been updated",          "type": "Notification"        },        {          "field_name": "status",          "id": 1564247,          "previous_value": "new",          "type": "Change",          "value": "open"        },        {          "field_name": "custom_status_id",          "id": 1564248,          "previous_value": 1,          "type": "Change",          "value": 123        }      ],      "id": 2127301143,      "metadata": {        "custom": {          "time_spent": "3m22s"        },        "system": {          "ip_address": "184.106.40.75"        }      },      "ticket_id": 123,      "via": {        "channel": "web"      }    }  ],  "before_cursor": "fDE1MDE1NzUxMjIuMHx8MTM0NzM0MzAxMQ==",  "before_url": "https://subdomain.zendesk.com/api/v2/ticket_audits.json?cursor=fDE1MDE1NzUxMjIuMHx8MTM0NzM0MzAxMQ%3D%3D&limit=1000"}

List Audits for a Ticket

  • GET /api/v2/tickets/{ticket_id}/audits

Lists the audits for a specified ticket.

Pagination

  • Cursor pagination (recommended)
  • Offset pagination

See Pagination.

Returns a maximum of 100 records per page.

Note: Audits for Archived Tickets do not support pagination for this endpoint.

Allowed for

  • Agents

Parameters

NameTypeInRequiredDescription
ticket_idintegerPathtrueThe ID of the ticket

Code Samples

curl
curl https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}/audits.json \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/tickets/123456/audits"	method := "GET"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Content-Type", "application/json")	req.Header.Add("Authorization", "Basic <auth-value>") // Base64 encoded "{email_address}/token:{api_token}"
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.zendesk.com/api/v2/tickets/123456/audits")		.newBuilder();String userCredentials = "your_email_address" + "/token:" + "your_api_token";String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("GET", null)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'GET',  url: 'https://example.zendesk.com/api/v2/tickets/123456/audits',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.zendesk.com/api/v2/tickets/123456/audits"headers = {	"Content-Type": "application/json",}email_address = 'your_email_address'api_token = 'your_api_token'# Use basic authenticationauth = HTTPBasicAuth(f'{email_address}/token', api_token)
response = requests.request(	"GET",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/tickets/123456/audits")request = Net::HTTP::Get.new(uri, "Content-Type": "application/json")email = "your_email_address"api_token = "your_api_token"credentials = "#{email}/token:#{api_token}"encoded_credentials = Base64.strict_encode64(credentials)request["Authorization"] = "Basic #{encoded_credentials}"response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|	http.request(request)end

Example response(s)

200 OK
// Status 200 OK
{  "audits": [    {      "author_id": 5246746,      "created_at": "2011-09-25T22:35:44Z",      "events": [        {          "attachments": [],          "body": "This is a new private comment",          "html_body": "<p>This is a new private comment</p>",          "id": 2127301148,          "public": false,          "type": "Comment"        },        {          "field_name": "status",          "id": 2127301163,          "previous_value": "new",          "type": "Change",          "value": "open",          "via": {            "channel": "rule",            "source": {              "from": {                "id": 35079792,                "title": "Assign to first responder"              },              "rel": "trigger",              "to": {}            }          }        },        {          "field_name": "custom_status_id",          "id": 2127301164,          "previous_value": 1,          "type": "Change",          "value": 123,          "via": {            "channel": "rule",            "source": {              "from": {                "id": 22472716,                "title": "Assign to first responder"              },              "rel": "trigger",              "to": {}            }          }        }      ],      "id": 2127301143,      "metadata": {        "custom": {},        "system": {          "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1",          "ip_address": "76.218.201.212",          "location": "San Francisco, CA, United States"        }      },      "ticket_id": 666,      "via": {        "channel": "web"      }    }  ],  "count": 1,  "next_page": null,  "previous_page": null}

Count Audits for a Ticket

  • GET /api/v2/tickets/{ticket_id}/audits/count

Returns an approximate count of audits for a specified ticket. If the count exceeds 100,000, the count will return a cached result. This cached result will update every 24 hours.

The count[refreshed_at] property is a timestamp that indicates when the count was last updated.

Note: When the count exceeds 100,000, count[refreshed_at] may occasionally be null. This indicates that the count is being updated in the background, and count[value] is limited to 100,000 until the update is complete.

Allowed for

  • Agents

Parameters

NameTypeInRequiredDescription
ticket_idintegerPathtrueThe ID of the ticket

Code Samples

curl
curl https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}/audits/count.json \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/tickets/123456/audits/count"	method := "GET"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Content-Type", "application/json")	req.Header.Add("Authorization", "Basic <auth-value>") // Base64 encoded "{email_address}/token:{api_token}"
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.zendesk.com/api/v2/tickets/123456/audits/count")		.newBuilder();String userCredentials = "your_email_address" + "/token:" + "your_api_token";String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("GET", null)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'GET',  url: 'https://example.zendesk.com/api/v2/tickets/123456/audits/count',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.zendesk.com/api/v2/tickets/123456/audits/count"headers = {	"Content-Type": "application/json",}email_address = 'your_email_address'api_token = 'your_api_token'# Use basic authenticationauth = HTTPBasicAuth(f'{email_address}/token', api_token)
response = requests.request(	"GET",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/tickets/123456/audits/count")request = Net::HTTP::Get.new(uri, "Content-Type": "application/json")email = "your_email_address"api_token = "your_api_token"credentials = "#{email}/token:#{api_token}"encoded_credentials = Base64.strict_encode64(credentials)request["Authorization"] = "Basic #{encoded_credentials}"response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|	http.request(request)end

Example response(s)

200 OK
// Status 200 OK
{  "count": {    "refreshed_at": "2020-04-06T02:18:17Z",    "value": 18  }}

Show Audit

  • GET /api/v2/tickets/{ticket_id}/audits/{ticket_audit_id}

Allowed for

  • Agents

Parameters

NameTypeInRequiredDescription
ticket_audit_idintegerPathtrueThe ID of the ticket audit
ticket_idintegerPathtrueThe ID of the ticket

Code Samples

curl
curl https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}/audits.json \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143"	method := "GET"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Content-Type", "application/json")	req.Header.Add("Authorization", "Basic <auth-value>") // Base64 encoded "{email_address}/token:{api_token}"
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143")		.newBuilder();String userCredentials = "your_email_address" + "/token:" + "your_api_token";String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("GET", null)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'GET',  url: 'https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143"headers = {	"Content-Type": "application/json",}email_address = 'your_email_address'api_token = 'your_api_token'# Use basic authenticationauth = HTTPBasicAuth(f'{email_address}/token', api_token)
response = requests.request(	"GET",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143")request = Net::HTTP::Get.new(uri, "Content-Type": "application/json")email = "your_email_address"api_token = "your_api_token"credentials = "#{email}/token:#{api_token}"encoded_credentials = Base64.strict_encode64(credentials)request["Authorization"] = "Basic #{encoded_credentials}"response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|	http.request(request)end

Example response(s)

200 OK
// Status 200 OK
{  "audit": {    "author_id": 5246746,    "created_at": "2011-09-25T22:35:44Z",    "events": [      {        "attachments": [],        "body": "This is a new private comment",        "html_body": "<p>This is a new private comment</p>",        "id": 2127301148,        "public": false,        "type": "Comment"      },      {        "field_name": "status",        "id": 2127301163,        "previous_value": "new",        "type": "Change",        "value": "open",        "via": {          "channel": "rule",          "source": {            "from": {              "id": 22472716,              "title": "Assign to first responder"            },            "rel": "trigger",            "to": {}          }        }      },      {        "field_name": "custom_status_id",        "id": 2127301164,        "previous_value": 1,        "type": "Change",        "value": 123,        "via": {          "channel": "rule",          "source": {            "from": {              "id": 22472716,              "title": "Assign to first responder"            },            "rel": "trigger",            "to": {}          }        }      }    ],    "id": 2127301143,    "metadata": {      "custom": {},      "system": {        "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1",        "ip_address": "76.218.201.212",        "location": "San Francisco, CA, United States"      }    },    "ticket_id": 666,    "via": {      "channel": "web"    }  }}

Change a Comment From Public To Private

  • PUT /api/v2/tickets/{ticket_id}/audits/{ticket_audit_id}/make_private

Allowed for

  • Agents

Parameters

NameTypeInRequiredDescription
ticket_audit_idintegerPathtrueThe ID of the ticket audit
ticket_idintegerPathtrueThe ID of the ticket

Code Samples

curl
curl https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}/audits/{ticket_audit_id}/make_private.json \  -v -u {email_address}/token:{api_token} -X PUT -d '{}' -H "Content-Type: application/json"
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143/make_private"	method := "PUT"	req, err := http.NewRequest(method, url, nil)
	if err != nil {		fmt.Println(err)		return	}	req.Header.Add("Content-Type", "application/json")	req.Header.Add("Authorization", "Basic <auth-value>") // Base64 encoded "{email_address}/token:{api_token}"
	client := &http.Client {}	res, err := client.Do(req)	if err != nil {		fmt.Println(err)		return	}	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)	if err != nil {		fmt.Println(err)		return	}	fmt.Println(string(body))}
Java
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143/make_private")		.newBuilder();RequestBody body = RequestBody.create(MediaType.parse("application/json"),		"""""");String userCredentials = "your_email_address" + "/token:" + "your_api_token";String basicAuth = "Basic " + java.util.Base64.getEncoder().encodeToString(userCredentials.getBytes());
Request request = new Request.Builder()		.url(urlBuilder.build())		.method("PUT", body)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'PUT',  url: 'https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143/make_private',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },};
axios(config).then(function (response) {  console.log(JSON.stringify(response.data));}).catch(function (error) {  console.log(error);});
Python
import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143/make_private"headers = {	"Content-Type": "application/json",}email_address = 'your_email_address'api_token = 'your_api_token'# Use basic authenticationauth = HTTPBasicAuth(f'{email_address}/token', api_token)
response = requests.request(	"PUT",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/tickets/123456/audits/2127301143/make_private")request = Net::HTTP::Put.new(uri, "Content-Type": "application/json")email = "your_email_address"api_token = "your_api_token"credentials = "#{email}/token:#{api_token}"encoded_credentials = Base64.strict_encode64(credentials)request["Authorization"] = "Basic #{encoded_credentials}"response = Net::HTTP.start uri.hostname, uri.port, use_ssl: true do |http|