The audit log shows various changes in a Zendesk account since the account was created. Records of these changes are saved indefinitely and you can view the entire change history. For more information, see Viewing the audit log for changes in Zendesk help.

The Audit Logs endpoints are only available on the Enterprise plan.

JSON format

Audit Logs are represented as JSON objects with the following properties:

NameTypeRead-onlyMandatoryDescription
actionstringtruefalseType of change made. Possible values are "create", "destroy", "exported", "login", and "update"
action_labelstringtruefalseLocalized string of action field
actor_idintegertruefalseid of the user or system that initiated the change
actor_namestringtruefalseName of the user or system that initiated the change
change_descriptionstringtruefalseThe description of the change that occurred
created_atstringtruefalseThe time the audit got created
idintegertruefalseThe id automatically assigned upon creation
ip_addressstringtruefalseThe IP address of the user doing the audit
source_idintegertruefalseThe id of the item being audited
source_labelstringtruefalseThe name of the item being audited
source_typestringtruefalseItem type being audited. Typically describes the system where the change was initiated. Possible values vary based on your account's Zendesk products and activity. Common values include "apitoken", "rule", "ticket", "user", and "zendesk/app_market/app". The "rule" value is used for automations, macros, triggers, views, and other automated business rules
urlstringtruefalseThe URL to access the audit log

Example

{  "action": "update",  "action_label": "Updated",  "actor_id": 1234,  "actor_name": "Sameer Patel",  "change_description": "Role changed from Administrator to End User",  "created_at": "2012-03-05T11:32:44Z",  "id": 498483,  "ip_address": "209.119.38.228",  "source_id": 3456,  "source_label": "John Doe",  "source_type": "user",  "url": "https://company.zendesk.com/api/v2/audit_logs/498483.json"}

List Audit Logs

  • GET /api/v2/audit_logs

Allowed For

  • Admins on accounts that have audit log access

Pagination

  • Cursor pagination (recommended)
  • Offset pagination

See Pagination.

Returns a maximum of 100 records per page.

Parameters

NameTypeInRequiredDescription
filter[action]stringQueryfalseFilter audit logs by the action
filter[actor_id]integerQueryfalseFilter audit logs by the actor id
filter[created_at]stringQueryfalseFilter audit logs by the time of creation. When used, you must specify filter[created_at] twice in your request, first with the start time and again with an end time
filter[ip_address]stringQueryfalseFilter audit logs by the ip address
filter[source_id]integerQueryfalseFilter audit logs by the source id. Requires filter[source_type] to also be set
filter[source_type]stringQueryfalseFilter audit logs by the source type. For example, user or rule
sortstringQueryfalseCursor pagination only. Sort audit logs. Default is sort=-created_at
sort_bystringQueryfalseOffset pagination only. Sort audit logs. Default is sort_by=created_at
sort_orderstringQueryfalseOffset pagination only. Sort audit logs. Default is sort_order=desc

Code Samples

curl
curl -g 'https://helpdesk.zendesk.com/api/v2/audit_logs.json?filter[source_type]=user&filter[source_id]=123' \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/audit_logs?filter[action]=&filter[actor_id]=&filter[created_at]=&filter[ip_address]=&filter[source_id]=&filter[source_type]=&sort=&sort_by=&sort_order="	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/audit_logs")		.newBuilder()		.addQueryParameter("filter[action]", "")		.addQueryParameter("filter[actor_id]", "")		.addQueryParameter("filter[created_at]", "")		.addQueryParameter("filter[ip_address]", "")		.addQueryParameter("filter[source_id]", "")		.addQueryParameter("filter[source_type]", "")		.addQueryParameter("sort", "")		.addQueryParameter("sort_by", "")		.addQueryParameter("sort_order", "");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/audit_logs',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },  params: {    'filter[action]': '',    'filter[actor_id]': '',    'filter[created_at]': '',    'filter[ip_address]': '',    'filter[source_id]': '',    'filter[source_type]': '',    'sort': '',    'sort_by': '',    'sort_order': '',  },};
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/audit_logs?filter[action]=&filter[actor_id]=&filter[created_at]=&filter[ip_address]=&filter[source_id]=&filter[source_type]=&sort=&sort_by=&sort_order="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/audit_logs")uri.query = URI.encode_www_form("filter[action]": "", "filter[actor_id]": "", "filter[created_at]": "", "filter[ip_address]": "", "filter[source_id]": "", "filter[source_type]": "", "sort": "", "sort_by": "", "sort_order": "")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_logs": [    {      "action": "update",      "actor_id": 1234,      "actor_name": "Sameer Patel",      "change_description": "Role changed from Administrator to End User",      "created_at": "2012-03-05T11:32:44Z",      "id": 498483,      "ip_address": "209.119.38.228",      "source_id": 3456,      "source_label": "John Doe",      "source_type": "user",      "url": "https://company.zendesk.com/api/v2/audit_logs/498483.json"    }  ]}

Show Audit Log

  • GET /api/v2/audit_logs/{audit_log_id}

Allowed For

  • Admins on accounts that have audit-log access

Parameters

NameTypeInRequiredDescription
audit_log_idintegerPathtrueThe ID of the audit log

Code Samples

curl
curl https://helpdesk.zendesk.com/api/v2/audit_logs/{audit_log_id}.json \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/audit_logs/498483"	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/audit_logs/498483")		.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/audit_logs/498483',  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/audit_logs/498483"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/audit_logs/498483")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_log": {    "action": "update",    "actor_id": 1234,    "actor_name": "Sameer Patel",    "change_description": "Role changed from Administrator to End User",    "created_at": "2012-03-05T11:32:44Z",    "id": 498483,    "ip_address": "209.119.38.228",    "source_id": 3456,    "source_label": "John Doe",    "source_type": "user",    "url": "https://company.zendesk.com/api/v2/audit_logs/498483.json"  }}

Export Audit Logs

  • POST /api/v2/audit_logs/export

Allowed For

  • Admins on accounts that have audit log access

Parameters

NameTypeInRequiredDescription
filter[action]stringQueryfalseFilter audit logs by the action
filter[actor_id]integerQueryfalseFilter audit logs by the actor id
filter[created_at]stringQueryfalseFilter audit logs by the time of creation. When used, you must specify filter[created_at] twice in your request, first with the start time and again with an end time
filter[ip_address]stringQueryfalseFilter audit logs by the ip address
filter[source_id]integerQueryfalseFilter audit logs by the source id. Requires filter[source_type] to also be set.
filter[source_type]stringQueryfalseFilter audit logs by the source type. For example, user or rule

Limits

This endpoint has its own rate limit that is different from the account wide rate limit. When calls are made to this endpoint, this limit will be consumed and you will get a 429 Too Many Requests response code if the allocation is exhausted.

Headers

API responses include usage limit information in the headers for this endpoint.

Zendesk-RateLimit-audit-logs-export: total={number}; remaining={number}; resets={number}

Within this header, “Total” signifies the initial allocation, “Remaining” indicates the remaining allowance for the current interval, and “Resets” denotes the wait time in seconds before the limit refreshes. You can see the Total, and Interval values in the below table.

Details

The rate limit is one per minute per account. If you exceed this, you'll receive the following error: "Rate limit for Audit log CSV Export exceeded. Please wait 1 minute and try again."

Rate LimitsScopesIntervalSandboxTrialDefault

"Default" applies to all Zendesk suite and support plans. Please refer to the general account limits for more information.

Code Samples

curl
curl https://helpdesk.zendesk.com/api/v2/audit_logs/export.json \  -v -u {email_address}/token:{api_token}
Go
import (	"fmt"	"io"	"net/http")
func main() {	url := "https://example.zendesk.com/api/v2/audit_logs/export?filter[action]=&filter[actor_id]=&filter[created_at]=&filter[ip_address]=&filter[source_id]=&filter[source_type]="	method := "POST"	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/audit_logs/export")		.newBuilder()		.addQueryParameter("filter[action]", "")		.addQueryParameter("filter[actor_id]", "")		.addQueryParameter("filter[created_at]", "")		.addQueryParameter("filter[ip_address]", "")		.addQueryParameter("filter[source_id]", "")		.addQueryParameter("filter[source_type]", "");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("POST", body)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", basicAuth)		.build();Response response = client.newCall(request).execute();
Nodejs
var axios = require('axios');
var config = {  method: 'POST',  url: 'https://example.zendesk.com/api/v2/audit_logs/export',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "{email_address}/token:{api_token}"  },  params: {    'filter[action]': '',    'filter[actor_id]': '',    'filter[created_at]': '',    'filter[ip_address]': '',    'filter[source_id]': '',    'filter[source_type]': '',  },};
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/audit_logs/export?filter[action]=&filter[actor_id]=&filter[created_at]=&filter[ip_address]=&filter[source_id]=&filter[source_type]="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(	"POST",	url,	auth=auth,	headers=headers)
print(response.text)
Ruby
require "net/http"require "base64"uri = URI("https://example.zendesk.com/api/v2/audit_logs/export")uri.query = URI.encode_www_form("filter[action]": "", "filter[actor_id]": "", "filter[created_at]": "", "filter[ip_address]": "", "filter[source_id]": "", "filter[source_type]": "")request = Net::HTTP::Post.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)

202 Accepted
// Status 202 Accepted
null