If you build on the Zendesk Developer Platform, you have likely run into 401 or 403 errors. These status codes account for many failed API requests we see from developers, especially early in an integration’s lifecycle.

Although both errors relate to access control, they fail for different reasons and require different approaches. If you treat them as interchangeable, you may often waste time and produce repeated failed requests.

In this post, you will learn how 401 and 403 errors work on Zendesk, how to diagnose them quickly, and how to fix them with confidence through practical examples and troubleshooting steps.

What you will learn

By the end of this post, you will understand:

  • The difference between 401 Unauthorized and 403 Forbidden on Zendesk
  • How to authenticate correctly with API tokens, OAuth access tokens, and JWTs
  • How OAuth scopes affect authorization
  • How to diagnose malformed headers, incorrect subdomains, and expired credentials

Difference between 401 and 403

Both status codes relate to access control, but they fail at different stages of request process.

401 Unauthorized

A 401 response means the Zendesk API cannot authenticate the request. Zendesk cannot identify the caller, so it doesn't evaluate permissions or business logic.

Common causes include:

  • Absent or malformed Authorization headers
  • Incorrect Base64 encoding for Basic authentication
  • Incorrect email and token format
  • Expired or revoked API tokens
  • OAuth tokens in a Basic authentication header
  • Invalid or expired JWTs for Messaging

If you receive a 401 error, focus on how the request authenticates, not on what the request tries to do.

403 Forbidden

A 403 response means Zendesk authenticated the request, but the authenticated identity lacks permission to perform the requested action.

Typical causes include:

  • OAuth tokens without required scopes
  • End-user credentials against agent-only endpoints
  • Access to resources that belong to another brand
  • Account IP allowlist rules
  • Suspended or downgraded agent accounts

If you receive a 403 error, authentication succeeds. The issue is authorization.

A quick diagnostic flow

When you debug access issues, the fastest way forward is to isolate the problem step by step.

  1. Start with a curl test. If the curl request fails, the issue likely involves credentials or account configuration, not your application code
  2. Confirm that you call the correct Zendesk subdomain. Credentials scope to a specific environment, and sandbox and production tokens do not interchange.
  3. Verify that you use the correct authentication method. Mix-ups between Basic Auth, OAuth, and JWT often cause failures.
  4. Check the role of the authenticated user. Many endpoints require agent or admin permissions, even if authentication succeeds
  5. If you use OAuth, confirm that the token includes the scopes that the endpoint requires
  6. Finally, consider where the request runs. Browser-origin requests often fail due to Cross-Origin Resource Sharing (CORS) policies when you use API token Basic authentication or other unsupported client-side flows. If you must call the API from a browser, use an OAuth flow that supports CORS, route requests through a backend service, or use a Zendesk app with the ZAF client. For more about CORS requests, see Making client-side CORS requests to the Ticketing API.

Authenticate correctly

Authentication runs before any permission or business logic checks. If authentication fails, Zendesk cannot associate the request with a user or integration and returns a 401 error.

Zendesk supports several authentication methods, each with strict format rules.

API token authentication

API tokens use Basic authentication, and the user name must include the /token suffix.

The correct format is:

curl -v \
  -u "agent@example.com/token:YOUR_API_TOKEN" \
  "https://yoursubdomain.zendesk.com/api/v2/tickets.json"

A common mistake that returns a 401 error is omission of the /token suffix:

emailAddress:APITOKEN

A Node.js example:

import fetch from "node-fetch";
import btoa from "btoa";

const subdomain = "your_subdomain";
const email = "agent@example.com";
const token = process.env.API_TOKEN;

const response = await fetch(
  `https://${subdomain}.zendesk.com/api/v2/users/me.json`,
  {
    headers: {
      'Authorization': 'Basic ' + btoa(`${email}/token:${token}`),
      'Content-Type': 'application/json'
    }
  }
);

console.log(response.status, await response.text());

OAuth authentication

Integrations that need long-lived credentials or fine-grained permission control often use OAuth. Send OAuth access tokens with the Bearer scheme. Use this header:

Authorization: Bearer ACCESS_TOKEN

Example request with curl:

curl \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  "https://yoursubdomain.zendesk.com/api/v2/users/me.json"

A Node.js example:

import fetch from "node-fetch";

const subdomain = process.env.SUBDOMAIN;
const token = process.env.OAUTH_TOKEN;

const url = `https://${subdomain}.zendesk.com/api/v2/users/me.json`;

const response = await fetch(url, {
  method: "GET",
  headers: {
    Authorization: `Bearer ${token}`
  }
});

console.log(response.status, await response.text());

A common cause of 401 Unauthorized with OAuth is a valid access token sent with the wrong scheme. In that case, Zendesk cannot authenticate the request and returns a 401 before it evaluates scopes or permissions.

OAuth tokens also use scopes that define permitted actions. A token can authenticate and still return 403 Forbidden if it lacks the scopes the endpoint requires.

For example, a token with tickets:read can fetch ticket data but cannot create or update tickets. A write attempt without the right scope always returns a 403 error.

403: You do not have access to this resource

If this occurs, authentication works, but you must regenerate the token with the correct scopes. For scope details, see OAuth Tokens for Grant Types.

JWT authentication for Messaging

Zendesk Messaging in web or mobile apps uses JWT to identify end users. Your backend must sign a JSON Web Token with the secret from Admin Center. Zendesk validates the token before it associates the Messaging session with a user.

Messaging JWTs need specific header and claim values so Zendesk can resolve the user’s identity.

At a minimum, a Messaging JWT must include:

  • kid – The Key ID from Admin Center in the JWT header, not the payload
  • external_id – A unique identifier for the user
  • scope – The value "user" for end-user authentication in Messaging

Optional claims such as name, email, and email_verified can populate user details in the agent interface and support email-based identity matching.

Example Node.js JWT generator:

import jwt from "jsonwebtoken";
const payload = {
  scope: "user",
  external_id: "user_12345",
  name: "Jane Doe",
  exp: Math.floor(Date.now() / 1000) + (5 * 60)
};

const token = jwt.sign(payload, process.env.ZENDESK_JWT_SECRET, {
  keyid: process.env.ZENDESK_KEYID,
});

console.log(token);

If required claims such as external_id or scope are absent, or if you sign with the wrong secret, Zendesk returns 401 Unauthorized.

Common 401 causes with JWT:

  • A JWT secret from the wrong environment (sandbox vs production)
  • An expired token or invalid time-based claims
  • Required claims such as external_id or scope aren't present
  • A token signed with an incorrect or rotated secret
  • A malformed or improperly encoded JWT

To debug Messaging authentication, first confirm the correct secret and required claims. If authentication succeeds but identity behavior seems off, verify stable and consistent values for external_id and any optional identity fields across sessions. For more, see Authenticating users in your application.

Common causes of 401 errors

A 401 response means Zendesk cannot authenticate the request and cannot determine the caller’s identity.

Incorrect Authorization headers, disabled tokens, or environment mismatches cause most 401 responses.

Format Basic authentication headers like this:

headers: {
  'Authorization': 'Basic ' + btoa(`${email}/token:${token}`),
  'Content-Type': 'application/json'
}

Unexpected characters, whitespace, or encoding issues often cause silent failures.

The Zendesk REST API does not support browser-origin authentication. Client-side JavaScript requests fail due to CORS, missing session cookies, and unsupported authentication flows. Use a backend service or a Zendesk app with the ZAF client instead.

Common causes of 403 errors

A 403 response indicates that Zendesk authenticated the request, but permission rules deny access.

The lack of OAuth scopes cause most 403 responses. For example, a token with tickets:read can fetch tickets but cannot create or update them. A write attempt always returns a 403 error.

You cannot modify OAuth scopes after token creation. If scopes are wrong, generate a new token.

Another frequent pitfall: a call to agent-only endpoints with end-user credentials. End-user OAuth tokens can call /users/me, but they return 403 for restricted endpoints such as tickets, views, or ticket fields.

Other causes include revoked tokens, IP allowlisting rules, and multibrand access limits. In these cases, Zendesk rejects the request because credentials are inactive or the user does not meet access criteria.

A step-by-step troubleshooting approach

1. Validate credentials in isolation:

curl -v \
  -u "email/token:token" \
  "https://yoursubdomain.zendesk.com/api/v2/users/me.json"
  • If this fails: The issue likely involves credentials or the account.
  • If this succeeds: The credentials are valid. The issue lies in your application logic or environment. Move to step 2.

2. Check for CORS limits:

If curl works but your client-side app fails, you likely hit CORS restrictions. Open the browser developer console and review the error. If you see a 401/403 with an Access-Control-Allow-Origin message, the browser blocks the request before Zendesk can process it.

3. Inspect raw request headers:

  • Log the Authorization header: Print the exact string your app sends. Confirm no hidden whitespace and correct prefixes such as Basic or Bearer.
  • Verify environment: Confirm that your app targets the correct subdomain. Many teams target a sandbox URL with production credentials, or the other way around.

4. Verify scopes and claims:

  • For OAuth: Call /api/v2/oauth/tokens/current to list current scopes. Confirm the token has the scope the resource requires.
  • For Messaging/JWT: Revalidate your JWT payload. Confirm that the kid (Key ID) matches your Zendesk configuration and that you used the correct signing secret.

Final thoughts

Most 401 and 403 errors on the Zendesk Developer Platform come from a small set of predictable misconfigurations. Separate authentication from authorization and you will speed up diagnosis and increase reliability.

Validate credentials early, confirm scopes and roles, and follow a structured diagnostic approach to resolve issues quickly and prevent repeats in production.

For more details, see the Zendesk docs on API token access, OAuth authentication, the Zendesk App Framework, and Messaging JWT authentication.

Powered by Zendesk