Zendesk API OAuth scopes: A complete developer guide

Stevia Putri
Written by

Stevia Putri

Reviewed by

Stanley Nicholas

Last edited February 27, 2026

Expert Verified

Banner image for Zendesk API OAuth scopes: A complete developer guide

When you're building integrations with Zendesk, controlling what your application can and cannot do is critical. OAuth scopes act as permission gates, letting you specify exactly which parts of the Zendesk API your application can access.

Unlike API tokens, which grant broad access to your entire Zendesk account, OAuth scopes let you follow the principle of least privilege. You request only the permissions you need, nothing more. This makes your integrations more secure and easier to audit.

In this guide, we'll walk through everything you need to know about Zendesk API OAuth scopes: what they are, which ones are available, how to implement them, and best practices for keeping your integrations secure.

OAuth scopes controlling API access permissions through granular permission gates
OAuth scopes controlling API access permissions through granular permission gates

What are Zendesk API OAuth scopes?

OAuth scopes in Zendesk are permission declarations that control access to API resources. When you create an OAuth token, you specify scopes that determine what actions your application can perform: reading tickets, writing to user records, managing help center content, and so on.

Think of scopes as keys to specific rooms in a building. Instead of having a master key that opens every door (like an API token), you request keys only for the rooms you need to enter. If your integration only needs to read ticket data, you request read or tickets:read scope. You won't get access to delete users or modify triggers.

This granular approach matters for several reasons:

  • Security: If a token is compromised, the damage is limited to the scoped permissions
  • Compliance: You can demonstrate exactly what data your application accesses
  • User trust: End users see exactly what permissions they're granting during OAuth authorization
  • Debugging: When something breaks, you know exactly which permissions are involved

Zendesk supports two main scope formats depending on how you create your tokens. The OAuth Tokens API uses an array format ("scopes": ["read"]), while the grant-type token endpoint uses a space-separated string ("scope": "read write"). We'll cover both approaches in the implementation section. For a deeper comparison of OAuth versus API tokens, see Zendesk's authentication guide.

Available OAuth scopes in Zendesk

Zendesk organizes scopes into two categories: broad scopes that apply across resources, and resource-specific scopes that target individual API endpoints.

Broad scopes

These three scopes control access across all Zendesk resources:

ScopeAccess LevelBest For
readGET endpoints and sideloadingReporting tools, analytics dashboards, read-only integrations
writePOST, PUT, DELETE endpointsSync tools, automation platforms, two-way integrations
impersonateRequests on behalf of end usersCustomer portals, embedded support widgets, proxy applications

The impersonate scope deserves special mention. It lets administrators make API requests on behalf of end users, which is useful when building customer-facing applications that need to create tickets or access request history without exposing admin credentials. This scope requires admin privileges and should be used carefully.

Resource-specific scopes

For more granular control, Zendesk lets you scope permissions to specific resources using the syntax resource:scope. Here are the resources that support scoped access:

ResourceRead ScopeWrite ScopeNotes
ticketstickets:readtickets:writeCore ticketing functionality
usersusers:readusers:writeUser management and profiles
organizationsorganizations:readorganizations:writeOrganization records
auditlogsauditlogs:readN/ARead-only by design
hc (help center)hc:readhc:writeArticles, categories, sections
appsapps:readapps:writeApp marketplace management
triggerstriggers:readtriggers:writeBusiness rules automation
automationsautomations:readautomations:writeTime-based automations
targetstargets:readtargets:writeNotification targets
webhookswebhooks:readwebhooks:writeWebhook configuration
macrosmacros:readmacros:writeCanned responses
requestsrequests:readrequests:writeEnd-user ticket interface
satisfaction_ratingssatisfaction_ratings:readsatisfaction_ratings:writeCSAT data
dynamic_contentdynamic_content:readdynamic_content:writeDynamic content items
any_channelN/Aany_channel:writeWrite-only
web_widgetN/Aweb_widget:writeWrite-only
ziszis:readzis:writeZendesk Integration Services

The flexibility here is powerful. You can mix and match scopes to create precise permission sets. For example, "scopes": ["tickets:read", "users:write", "organizations:read"] gives you read access to tickets and organizations, plus the ability to update user records.

OAuth scope syntax and format

Getting the syntax right matters because Zendesk returns tokens even with invalid scope formats, but API calls with those tokens will fail with "Forbidden" errors.

Non-grant-type tokens (scopes array)

When using the OAuth Tokens API to create tokens directly (typically for internal use or admin-created tokens), use the array format:

{
  "token": {
    "client_id": 1234,
    "scopes": ["tickets:read", "users:read"]
  }
}

Key points:

  • Parameter name is scopes (plural)
  • Value is a JSON array of strings
  • Each scope is a separate array element
  • Endpoint: POST /api/v2/oauth/tokens

Grant-type tokens (scope string)

When implementing the OAuth authorization flow (authorization code, refresh token, or client credentials), use the space-separated string format:

{
  "grant_type": "authorization_code",
  "code": "7xqwtlf3rrdj8uyeb1yf",
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "scope": "tickets:read users:write"
}

Key points:

  • Parameter name is scope (singular)
  • Value is a space-separated string
  • Multiple scopes go in the same string
  • Endpoint: POST /oauth/tokens

Common scope combinations

Here are practical scope combinations for typical use cases:

Read-only reporting:

"scopes": ["read"]

Ticket management with user lookup:

"scopes": ["tickets:read", "tickets:write", "users:read"]

Help center content management:

"scopes": ["hc:read", "hc:write", "tickets:read"]

Full admin access (use sparingly):

"scopes": ["read", "write"]

How to implement OAuth scopes in your application

Let's walk through the complete implementation, from creating an OAuth client to making your first scoped API request.

OAuth implementation flow from client creation to API requests
OAuth implementation flow from client creation to API requests

Step 1: Create an OAuth client in Zendesk

Before you can request scoped tokens, you need to register your application as an OAuth client in Zendesk.

  1. Log into your Zendesk account as an administrator

  2. Navigate to Admin Center > Apps and integrations > APIs > OAuth clients

  3. Click Add OAuth client

  4. Fill in the required fields:

    • Name: Your application name (users will see this during authorization)
    • Description: Brief description of what your app does
    • Client kind: Choose Public for mobile/SPA apps, Confidential for server-side apps
    • Redirect URLs: Your callback URLs (must be HTTPS except for localhost)
  5. Click Save

  6. Copy the Secret value immediately (it's only shown once fully)

  7. Note your Unique Identifier (this is your client_id)

Important: If you select Public as the client kind, you must implement PKCE (Proof Key for Code Exchange) for security. Confidential clients can use PKCE, client secret, or both.

Step 2: Request authorization with scopes

Send your users to Zendesk's authorization endpoint with your requested scopes:

https://{subdomain}.zendesk.com/oauth/authorizations/new?
  response_type=code&
  redirect_uri=https://your-app.com/callback&
  client_id=your_unique_identifier&
  scope=read%20write&
  state=random_state_string

Zendesk's OAuth consent screen prompting a user to allow an application to access their account with specific data permissions.
Zendesk's OAuth consent screen prompting a user to allow an application to access their account with specific data permissions.

Required parameters:

  • response_type=code: Indicates you want an authorization code
  • redirect_uri: Must match one of the URLs registered in Step 1
  • client_id: Your OAuth client's unique identifier
  • scope: Space-separated list of requested scopes

Recommended parameters:

  • state: Random string to prevent CSRF attacks (validate this matches when the user returns)
  • code_challenge and code_challenge_method=S256: Required for PKCE with public clients

The user will see an authorization screen listing the scopes you're requesting. They'll approve or deny access.

Step 3: Exchange authorization code for access token

When the user approves, Zendesk redirects to your callback URL with an authorization code:

https://your-app.com/callback?code=7xqwtlf3rrdj8uyeb1yf&state=random_state_string

Exchange this code for an access token:

curl https://{subdomain}.zendesk.com/oauth/tokens \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "7xqwtlf3rrdj8uyeb1yf",
    "client_id": "your_unique_identifier",
    "client_secret": "your_client_secret",
    "redirect_uri": "https://your-app.com/callback",
    "scope": "read write"
  }'

Important: The authorization code expires in 120 seconds. Exchange it promptly.

The response includes your access token and refresh token:

{
  "access_token": "gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo",
  "refresh_token": "31048ba4d7c601302f3173f243da835f",
  "token_type": "bearer",
  "scope": "read write",
  "expires_in": 172800,
  "refresh_token_expires_in": 800000
}

Step 4: Use the access token in API requests

Include the token in your API requests as a Bearer token:

curl https://{subdomain}.zendesk.com/api/v2/tickets.json \
  -H "Authorization: Bearer gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo"

The token only works for endpoints matching your scopes. A token with tickets:read scope can fetch tickets but cannot create them (that would require tickets:write).

Common scope configurations for typical use cases

Different integrations need different permission sets. Here are configurations we see frequently:

Common OAuth scope configurations for reporting, sync, and automation tools
Common OAuth scope configurations for reporting, sync, and automation tools

Reporting and analytics tools

These tools only need to read data:

"scope": "read"

Or more restrictive:

"scope": "tickets:read users:read organizations:read"

Two-way sync integrations

Sync tools need to read and write across multiple resources:

"scope": "tickets:read tickets:write users:read users:write organizations:read organizations:write"

Help Center content management

For managing knowledge base articles:

"scope": "hc:read hc:write"

Customer-facing portals

When your application acts on behalf of end users:

"scope": "requests:read requests:write impersonate"

Automation and workflow tools

For tools that manage business rules:

"scope": "triggers:read triggers:write automations:read automations:write webhooks:read webhooks:write"

Troubleshooting scope-related errors

Even with proper implementation, you'll encounter errors. Here's how to handle the most common ones:

"Forbidden" errors (403)

This is the most common scope-related error. It means your token lacks permission for the requested endpoint.

Causes:

  • Missing required scope for the endpoint
  • Invalid scope format (array vs string mismatch)
  • User's role doesn't have permission (OAuth scopes are constrained by user permissions)

Solution: Check which scope the endpoint requires in the Zendesk API documentation, then verify your token includes it. Remember that some endpoints require admin privileges regardless of OAuth scopes. For more details on creating and managing tokens, see Zendesk's OAuth token tutorial.

401 Unauthorized

This indicates an expired or revoked token:

{
  "error": "invalid_token",
  "error_description": "The access token provided is expired, revoked, malformed or invalid for other reasons."
}

Solution: Use your refresh token to obtain a new access token, or redirect the user through the authorization flow again if the refresh token has also expired.

Invalid scope format

If you pass scopes in the wrong format (array when string expected, or vice versa), Zendesk may still issue a token, but API calls will fail.

Solution: Double-check which endpoint you're using:

  • /api/v2/oauth/tokens uses "scopes": [] array format
  • /oauth/tokens uses "scope": "" string format

Scope vs. role mismatch

OAuth scopes are filtered by the user's role. An agent's OAuth token cannot access admin-only endpoints, even if the token has write scope.

Solution: Ensure the user authorizing your application has the necessary role permissions for your integration's requirements.

Best practices for OAuth scope security

Following these practices will keep your Zendesk integrations secure:

Request minimal scopes

Only ask for the permissions you absolutely need. If your integration only reads tickets, don't request write scope. This limits exposure if a token is compromised.

Use confidential clients when possible

Server-side applications should use confidential clients with client secrets. Public clients (mobile apps, SPAs) must implement PKCE.

Implement token refresh logic

Access tokens expire. You'll want to build automatic refresh logic into your application:

response = requests.get(api_url, headers=headers)
if response.status_code == 401:
    new_token = refresh_access_token(refresh_token)
    headers['Authorization'] = f'Bearer {new_token}'
    response = requests.get(api_url, headers=headers)

Store tokens securely

Treat access tokens and refresh tokens like passwords. Store them encrypted, never log them, and don't expose them in client-side code.

Validate state parameters

Always include and validate the state parameter in your OAuth flow to prevent CSRF attacks.

Consider using a secure integration platform

Building OAuth integrations securely requires careful attention to token storage, refresh logic, and error handling. If you're building customer support integrations, consider using a platform like eesel AI that handles Zendesk OAuth securely with proper scope management built in. Our AI Agent integrates with Zendesk using minimal required scopes, following the principle of least privilege by default. You can also learn more about viewing and managing your OAuth tokens in Zendesk's documentation.

eesel AI dashboard with connected knowledge sources and integrations
eesel AI dashboard with connected knowledge sources and integrations

Conclusion

Zendesk API OAuth scopes give you precise control over what your integrations can access. By understanding the available scopes, implementing them correctly, and following security best practices, you can build integrations that are both powerful and secure.

The key takeaways:

  • Use broad scopes (read, write) for simple integrations, resource-specific scopes for granular control
  • Match your scope format to your token endpoint (array vs string)
  • Always request minimal permissions
  • Handle token expiration gracefully with refresh logic
  • Remember that user roles constrain OAuth scopes

Whether you're building a simple reporting tool or a complex two-way sync, proper scope configuration is the foundation of a secure Zendesk integration.

Frequently Asked Questions

No. You cannot modify scopes on an existing token. To change permissions, you need to generate a new token with the updated scopes by sending the user through the authorization flow again.
OAuth scopes control what API endpoints a token can access. User roles (admin, agent, end user) control what actions a user can perform in Zendesk. A token's effective permissions are the intersection of its scopes and the authorizing user's role. An agent cannot perform admin actions even with broad OAuth scopes.
Check the Zendesk API documentation. Most endpoint descriptions include the required scope. Generally, GET endpoints require 'read' or 'resource:read', while POST/PUT/DELETE endpoints require 'write' or 'resource:write'.
No. API tokens are a different authentication mechanism that grants broad account access without scope restrictions. OAuth tokens use scopes. Choose OAuth for granular permissions, API tokens for simple scripts where scope control isn't needed.
Zendesk will issue a token, but API calls will return 'Forbidden' errors. The token creation endpoint doesn't validate scope names, so typos or invalid scope strings won't be caught until you try to use the token.
No. Rate limits are based on your Zendesk plan and apply regardless of which scopes your token has. However, more permissive scopes might make it easier to accidentally hit rate limits if your application makes many write requests.

Share this post

Stevia undefined

Article by

Stevia Putri

Stevia Putri is a marketing generalist at eesel AI, where she helps turn powerful AI tools into stories that resonate. She’s driven by curiosity, clarity, and the human side of technology.