Access Logs

The access log is a 90-day record of events that captures what an agent or admin has accessed in your account without necessarily updating, creating, or deleting anything. The access log is your record of read and write events for your account.

The Advanced Data Privacy and Protection (ADPP) add-on is required to use this API.

The Access Logs API can return two kinds of identifiers for the resources accessed: a REST API path or a GraphQL query. The log also provides additional information, including:

  • timestamp
  • query parameters
  • the HTTP method used, such as GET or POST
  • the user id of the user who made the request
  • the IP address of the user who made the request

You can filter the access logs based on when the event happened, or based on objects or users within a specified time frame. The examples below show all filters, but that's not required. You can specify as many filters as needed.

Filtering by objects

filter[start]: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ
filter[end]: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ
filter[path]: URL path of the object, excluding query parameters


Filtering by users

filter[start]: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ
filter[end]: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ
filter[user_id]: User id


Filtering by time stamps

filter[start]: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ
filter[end]`: UTC time stamp in the format of yyyy-mm-ddThh:mm:ssZ


JSON format

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

graphqlobjecttruefalseOptional details if the request was a GraphQL query
idstringtruetrueUnique identifier for the access log
ip_addressstringtruetrueIP address of the user who made the request
methodstringtruetrueHTTP method of the request. Possible values: "GET", "POST", "PUT", "DELETE"
statusnumbertruetrueHTTP status code of the response
timestampstringtruetrueISO 8601 formatted string representing the time of the request
urlstringtruetrueURL of the request
user_idnumbertruetrueID of the user who made the request

List Access Logs

  • GET /api/v2/access_logs

Returns a list of access logs for the given query parameters.

Allowed For

  • Admins


  • Cursor pagination

Rate Limits

Requests are rate limited to 50 requests per minute.

The API doesn't follow the same rate limiting conventions as other Zendesk APIs. Responses don't include x-rate-limits and x-rate-limit-remaining headers. The API does return a 429 status code when the limit is reached but doesn't include a retry-after header. Instead it returns a ratelimit-reset header that specifies a date-time.


filter[after]stringQueryfalseCursor value received as part of the previous request. Used to get next set of results
filter[end]stringQueryfalseOnly return logs created before this timestamp
filter[path]stringQueryfalseSpecific url path excluding query params to filter by
filter[size]numberQueryfalseMaximum number of results to return. Default value is 1000 and the maximum allowed value is 2500
filter[start]stringQueryfalseOnly return logs created after this timestamp
filter[user_id]numberQueryfalseSpecific user id to filter by

Code Samples

curl --request GET[after]=01H6PWD1WQFC6EYJCJWFJ59EVE&filter[end]=2022-03-21T00%3A00%3A00Z&filter[path]=%2Fapi%2Fv2%2Fusers%2Fsearch&filter[size]=100&filter[start]=2022-03-20T00%3A00%3A00Z&filter[user_id]=1234567890 \--header "Content-Type: application/json" \-u username:password
import (	"fmt"	"io"	"net/http")
func main() {	url := "[after]=01H6PWD1WQFC6EYJCJWFJ59EVE&filter[end]=2022-03-21T00%3A00%3A00Z&filter[path]=%2Fapi%2Fv2%2Fusers%2Fsearch&filter[size]=100&filter[start]=2022-03-20T00%3A00%3A00Z&filter[user_id]=1234567890"	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 "username:password"
	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))}
import com.squareup.okhttp.*;OkHttpClient client = new OkHttpClient();HttpUrl.Builder urlBuilder = HttpUrl.parse("")		.newBuilder()		.addQueryParameter("filter[after]", "01H6PWD1WQFC6EYJCJWFJ59EVE")		.addQueryParameter("filter[end]", "2022-03-21T00:00:00Z")		.addQueryParameter("filter[path]", "/api/v2/users/search")		.addQueryParameter("filter[size]", "100")		.addQueryParameter("filter[start]", "2022-03-20T00:00:00Z")		.addQueryParameter("filter[user_id]", "1234567890");
Request request = new Request.Builder()		.url(		.method("GET", null)		.addHeader("Content-Type", "application/json")		.addHeader("Authorization", Credentials.basic("your-email", "your-password"))		.build();Response response = client.newCall(request).execute();
var axios = require('axios');
var config = {  method: 'GET',  url: '',  headers: {	'Content-Type': 'application/json',	'Authorization': 'Basic <auth-value>', // Base64 encoded "username:password"  },  params: {    'filter[after]': '01H6PWD1WQFC6EYJCJWFJ59EVE',    'filter[end]': '2022-03-21T00%3A00%3A00Z',    'filter[path]': '%2Fapi%2Fv2%2Fusers%2Fsearch',    'filter[size]': '100',    'filter[start]': '2022-03-20T00%3A00%3A00Z',    'filter[user_id]': '1234567890',  },};
axios(config).then(function (response) {  console.log(JSON.stringify(;}).catch(function (error) {  console.log(error);});
import requests
url = "[after]=01H6PWD1WQFC6EYJCJWFJ59EVE&filter[end]=2022-03-21T00%3A00%3A00Z&filter[path]=%2Fapi%2Fv2%2Fusers%2Fsearch&filter[size]=100&filter[start]=2022-03-20T00%3A00%3A00Z&filter[user_id]=1234567890"headers = {	"Content-Type": "application/json",}
response = requests.request(	"GET",	url,	auth=('<username>', '<password>'),	headers=headers)
require "net/http"uri = URI("")uri.query = URI.encode_www_form("filter[after]": "01H6PWD1WQFC6EYJCJWFJ59EVE", "filter[end]": "2022-03-21T00:00:00Z", "filter[path]": "/api/v2/users/search", "filter[size]": "100", "filter[start]": "2022-03-20T00:00:00Z", "filter[user_id]": "1234567890")request =, "Content-Type": "application/json")request.basic_auth "username", "password"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
{  "access_logs": [    {      "id": "01H6PWD1WQFC6EYJCJWFJ59EVE",      "ip_address": "",      "method": "POST",      "status": 200,      "timestamp": "2020-01-01T13:01:26Z",      "url": "/api/v2/search?query=foobar",      "user_id": 123    },    {      "graphql": {        "operation_name": "ticket",        "operation_type": "QUERY",        "query": "query ticket($id: ID!, $includeSkills: Boolean = false, $includeCustomFields: Boolean = false, $includeUserCustomFields: Boolean = false, $includeConversationAuthenticated: Boolean = false) { ticket(id: $id) { id assignee { user { id name __typename }...",        "variables": "{\"id\":\"1\"}"      },      "id": "01H9KB1CDRX2RVDS7E2R4YJ0TS",      "ip_address": "",      "method": "POST",      "status": 200,      "timestamp": "2023-09-05T18:52:50Z",      "url": "/graphql",      "user_id": 321    }  ],  "links": {    "next": "https://<subdomain>[start]=2020-01-01T00:00:00Z&filter[end]=2020-01-02T00:00:00Z&filter[user_id]=123&page[size]=100&page[after]=xxx"  },  "meta": {    "after_cursor": "xxxxxxxxx",    "has_more": true  }}
400 Bad Request
// Status 400 Bad Request
{  "errors": [    {      "detail": "max allowed page size is 2500",      "title": "Malformed query params"    }  ]}
401 Unauthorized
// Status 401 Unauthorized
{  "errors": [    {      "detail": "Please use valid credentials",      "title": "Authentication failed"    }  ]}
403 Forbidden
// Status 403 Forbidden
{  "errors": [    {      "detail": "You must have administrator privileges",      "title": "Authorization failed"    }  ]}
429 Too Many Requests
// Status 429 Too Many Requests
{  "errors": [    {      "detail": "Use RateLimit-Reset header to backoff on retries",      "title": "Too many requests"    }  ]}
500 Internal Server Error
// Status 500 Internal Server Error
{  "errors": [    {      "detail": "Failed to process request",      "title": "Internal Service Error"    }  ]}