A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Zendesk API is how an app or AI agent works with a Zendesk Support account: creating and updating tickets, replying to a customer or adding an internal note, looking up users and organizations, applying a macro, and searching across records. Access is granted through an API token or an OAuth access token, and an OAuth token carries scopes in a resource:access form, like tickets:read or users:write, that set which resources a call can read or write. A state change can fire a webhook event to a registered endpoint.
How an app or AI agent connects to Zendesk determines what it can reach. There is a route for making calls, governed by an API token or an OAuth access token, and a route for receiving events through webhooks. An OAuth token carries scopes that decide which resources a call can read or write.
The Support REST API answers under https://{subdomain}.zendesk.com/api/v2. It takes and returns JSON, requires an Accept: application/json header on every request and a Content-Type: application/json header on writes, and pages through lists with a cursor. A call authenticates with an API token or an OAuth access token.
Zendesk POSTs a JSON payload to a registered URL when a subscribed event fires, like a ticket being created or a comment added. A webhook subscribes to one or more event types, or is driven by a trigger or automation through the conditional ticket events it fires. Webhooks are managed through /api/v2/webhooks.
An API token is an account-generated password used with an agent's email address. It is sent through HTTP Basic auth, with the username set to {email_address}/token and the password set to the token itself. An API token carries the full permissions of the agent it belongs to, with no per-resource scoping, so it is best kept to trusted server-side use.
An OAuth access token is sent as a Bearer token and can be up to 184 characters long. It carries scopes that set what it can reach, either the global read, write, or impersonate scopes, or resource-specific scopes in a resource:access form like tickets:read or users:write. This is the route that allows least-privilege access. As of February 2026 Zendesk enforces default token expiration and the refresh-token flow for external OAuth clients.
Email-and-password basic auth was the original method. Zendesk removed password access for the API on 12 January 2026 for all accounts, so an integration must use an API token or OAuth instead.
The Zendesk Support API is split into areas an agent can act on, like tickets, ticket comments, users, organizations, groups, macros, and search. Each area has its own methods and its own scope, and writes in some areas change support records or delete people's accounts.
List, read, create, update, and delete tickets, create or update many at once, and count them. A ticket update is also how a public reply or internal note is added.
List the comments on a ticket, make a comment private, and redact words or attachments from a comment. Comments are created through the Tickets API, not here.
List, read, search, create, update, merge, and delete users (agents and end users), and read the currently authenticated user.
List, read, create, update, and delete the organizations that group end users together.
List, read, create, update, and delete the agent groups that tickets are assigned to.
List, read, create, update, and delete macros, the saved sets of actions an agent applies to a ticket.
Run the unified search across tickets, users, and organizations, count matches, and export large result sets.
List and read CSAT satisfaction ratings, and create a rating on a solved ticket.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
TicketsList, read, create, update, and delete tickets, create or update many at once, and count them. A ticket update is also how a public reply or internal note is added.8 | ||||||
| GET | /api/v2/tickets | List tickets in the account. | read | tickets:read | Current | |
Read-only. The global read scope also covers this. Acts onticket Permission (capability) tickets:readVersionAvailable since the API’s base version Webhook eventNone Rate limit50 requests/minute when paging beyond page 500 SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/tickets/{ticket_id} | Show a single ticket by ID. | read | tickets:read | Current | |
Read-only. Acts onticket Permission (capability) tickets:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/tickets | Create a ticket. | write | tickets:write | Current | |
A core write. Creating a ticket can notify the requester by email. Acts onticket Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/tickets/{ticket_id} | Update a ticket, including adding a public reply or an internal note as a comment. | write | tickets:write | Current | |
Comments are added through this endpoint. Limited to 30 updates per 10 minutes per user per ticket, and updates use optimistic locking that returns 409 on a conflict. Acts onticket Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.status_changedRate limit30 updates / 10 minutes per user per ticket; 100 requests/minute per account SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v2/tickets/{ticket_id} | Delete a ticket (soft delete; it can be restored before permanent deletion). | write | tickets:write | Current | |
Soft-deletes the ticket; a separate step permanently removes it. Acts onticket Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.soft_deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/tickets/create_many | Create up to 100 tickets in one request as a background job. | write | tickets:write | Current | |
Returns a job status to poll; processes asynchronously. Acts onticket Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/tickets/update_many | Update multiple tickets in one request as a background job. | write | tickets:write | Current | |
Returns a job status to poll; processes asynchronously. Acts onticket Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/tickets/count | Return an approximate count of tickets in the account. | read | tickets:read | Current | |
Read-only; the count is approximate and cached. Acts onticket Permission (capability) tickets:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Ticket commentsList the comments on a ticket, make a comment private, and redact words or attachments from a comment. Comments are created through the Tickets API, not here.3 | ||||||
| GET | /api/v2/tickets/{ticket_id}/comments | List the comments added to a ticket. | read | tickets:read | Current | |
Read-only; returns both public replies and private internal notes. Acts onticket_comment Permission (capability) tickets:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/tickets/{ticket_id}/comments/{ticket_comment_id}/make_private | Convert a public ticket comment into a private internal note. | write | tickets:write | Current | |
Hides the comment from the requester; it cannot be made public again. Acts onticket_comment Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.comment_made_privateRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/comment_redactions/{ticket_comment_id} | Permanently remove words, strings, or attachments from a ticket comment. | write | tickets:write | Current | |
The redaction is irreversible; the original content cannot be recovered. Acts onticket_comment Permission (capability) tickets:writeVersionAvailable since the API’s base version Webhook event ticket.comment_redactedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UsersList, read, search, create, update, merge, and delete users (agents and end users), and read the currently authenticated user.8 | ||||||
| GET | /api/v2/users | List users in the account (agents, admins, and end users). | read | users:read | Current | |
Read-only; returns email addresses and other profile fields. Acts onuser Permission (capability) users:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/users/{user_id} | Show a single user by ID. | read | users:read | Current | |
Read-only. Acts onuser Permission (capability) users:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/users/me | Show the currently authenticated user behind the token. | read | users:read | Current | |
Read-only; confirms which identity a token resolves to. Acts onuser Permission (capability) users:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/users/search | Search users by name, email, external ID, or other attributes. | read | users:read | Current | |
Read-only; reaches across every user the token can see. Acts onuser Permission (capability) users:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/users | Create a user (an agent or an end user). | write | users:write | Current | |
A core write; creating an agent can consume an agent seat. Acts onuser Permission (capability) users:writeVersionAvailable since the API’s base version Webhook event user.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/users/{user_id} | Update a user's profile, role, or status. | write | users:write | Current | |
Can change a user's role, which alters their access. Limited to 5 requests/minute per user record. Acts onuser Permission (capability) users:writeVersionAvailable since the API’s base version Webhook event user.role_changedRate limit5 requests/minute per user SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/users/{user_id}/merge | Merge one end user into another, combining their records. | write | users:write | Current | |
The merged-from user is removed; the action cannot be undone. Acts onuser Permission (capability) users:writeVersionAvailable since the API’s base version Webhook event user.mergedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v2/users/{user_id} | Delete a user. | write | users:write | Current | |
Removes the account; an agent's tickets are reassigned or unassigned. Acts onuser Permission (capability) users:writeVersionAvailable since the API’s base version Webhook event user.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
OrganizationsList, read, create, update, and delete the organizations that group end users together.5 | ||||||
| GET | /api/v2/organizations | List organizations, at most 100 per page. | read | organizations:read | Current | |
Read-only. Acts onorganization Permission (capability) organizations:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/organizations/{organization_id} | Show a single organization by ID. | read | organizations:read | Current | |
Read-only. Acts onorganization Permission (capability) organizations:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/organizations | Create an organization. | write | organizations:write | Current | |
A core write; the name field is required. Acts onorganization Permission (capability) organizations:writeVersionAvailable since the API’s base version Webhook event organization.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/organizations/{organization_id} | Update an organization's properties. | write | organizations:write | Current | |
Limited to 5 requests/minute per organization record. Acts onorganization Permission (capability) organizations:writeVersionAvailable since the API’s base version Webhook event organization.name_changedRate limit5 requests/minute per organization SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v2/organizations/{organization_id} | Delete an organization. | write | organizations:write | Current | |
Removes the organization; its users are detached from it. Acts onorganization Permission (capability) organizations:writeVersionAvailable since the API’s base version Webhook event organization.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
GroupsList, read, create, update, and delete the agent groups that tickets are assigned to.5 | ||||||
| GET | /api/v2/groups | List the agent groups in the account. | read | read | Current | |
Read-only; covered by the global read scope. Acts ongroup Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/groups/{group_id} | Show a single group by ID. | read | read | Current | |
Read-only. Acts ongroup Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/groups | Create an agent group. | write | write | Current | |
Allowed for admins; covered by the global write scope. Acts ongroup Permission (capability) writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/groups/{group_id} | Update an agent group. | write | write | Current | |
Restricted to admins; changes how tickets route. Acts ongroup Permission (capability) writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v2/groups/{group_id} | Delete an agent group. | write | write | Current | |
Tickets assigned to the group must be reassigned first. Acts ongroup Permission (capability) writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MacrosList, read, create, update, and delete macros, the saved sets of actions an agent applies to a ticket.5 | ||||||
| GET | /api/v2/macros | List the shared and personal macros available to the current user. | read | macros:read | Current | |
Read-only. Acts onmacro Permission (capability) macros:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/macros/{macro_id} | Show a single macro by ID. | read | macros:read | Current | |
Read-only. Acts onmacro Permission (capability) macros:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/macros | Create a macro, a saved set of actions to apply to a ticket. | write | macros:write | Current | |
A shared macro is available to other agents. Acts onmacro Permission (capability) macros:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/v2/macros/{macro_id} | Update a macro's actions or properties. | write | macros:write | Current | |
Changes a shared workflow shortcut for every agent who uses it. Acts onmacro Permission (capability) macros:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v2/macros/{macro_id} | Delete a macro. | write | macros:write | Current | |
Removes the macro for all agents. Acts onmacro Permission (capability) macros:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SearchRun the unified search across tickets, users, and organizations, count matches, and export large result sets.3 | ||||||
| GET | /api/v2/search | Run the unified search across tickets, users, and organizations. | read | read | Current | |
Returns at most 1,000 results, 100 per page. Reaches across every record the token can see. Acts onsearch_result Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/search/count | Return the number of results matching a search query. | read | read | Current | |
Read-only; returns a count rather than the records. Acts onsearch_result Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v2/search/export | Export a large result set for one object type using cursor pagination. | read | read | Current | |
For queries beyond 1,000 results; one object type per query. Limited to 100 requests/minute. Acts onsearch_result Permission (capability) readVersionAvailable since the API’s base version Webhook eventNone Rate limit100 requests/minute SourceOfficial documentation ↗ | ||||||
Satisfaction ratingsList and read CSAT satisfaction ratings, and create a rating on a solved ticket.2 | ||||||
| GET | /api/v2/satisfaction_ratings | List CSAT satisfaction ratings. | read | satisfaction_ratings:read | Current | |
Read-only. Acts onsatisfaction_rating Permission (capability) satisfaction_ratings:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v2/tickets/{ticket_id}/satisfaction_rating | Create a CSAT rating on a solved ticket. | write | satisfaction_ratings:write | Current | |
Only for a ticket that is solved, or was solved and then reopened. These are legacy CSAT endpoints; survey responses are the current path. Acts onsatisfaction_rating Permission (capability) satisfaction_ratings:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Zendesk can notify an app when something happens in an account, like a ticket being created or a comment added. A webhook subscribes to one or more event types and Zendesk posts a JSON payload to its URL, so an integration learns about activity without polling. A webhook can also be driven by a trigger or automation through the conditional ticket events it fires.
| Event | What it signals | Triggered by |
|---|---|---|
zen:event-type:ticket.created | Fires when a ticket is created. | /api/v2/tickets/api/v2/tickets/create_many |
zen:event-type:ticket.status_changed | Fires when a ticket's status changes, such as moving to pending, solved, or closed. | /api/v2/tickets/{ticket_id} |
zen:event-type:ticket.comment_added | Fires when a comment, a public reply or a private internal note, is added to a ticket. | /api/v2/tickets/{ticket_id} |
zen:event-type:ticket.comment_made_private | Fires when a public ticket comment is converted to a private internal note. | /api/v2/tickets/{ticket_id}/comments/{ticket_comment_id}/make_private |
zen:event-type:ticket.comment_redacted | Fires when words, strings, or attachments are permanently redacted from a ticket comment. | /api/v2/comment_redactions/{ticket_comment_id} |
zen:event-type:ticket.soft_deleted | Fires when a ticket is soft-deleted (deleted but recoverable before permanent removal). | /api/v2/tickets/{ticket_id} |
zen:event-type:ticket.priority_changed | Fires when a ticket's priority changes, such as to urgent or high. | /api/v2/tickets/{ticket_id} |
zen:event-type:ticket.agent_assignment_changed | Fires when a ticket's assigned agent changes. | /api/v2/tickets/{ticket_id} |
zen:event-type:user.created | Fires when a user (an agent or an end user) is created. | /api/v2/users |
zen:event-type:user.role_changed | Fires when a user's role changes, which alters their access. | /api/v2/users/{user_id} |
zen:event-type:user.merged | Fires when one end user is merged into another. | /api/v2/users/{user_id}/merge |
zen:event-type:user.deleted | Fires when a user is deleted. | /api/v2/users/{user_id} |
zen:event-type:organization.created | Fires when an organization is created. | /api/v2/organizations |
zen:event-type:organization.name_changed | Fires when an organization's name changes. | /api/v2/organizations/{organization_id} |
zen:event-type:organization.deleted | Fires when an organization is deleted. | /api/v2/organizations/{organization_id} |
Zendesk limits how fast an app can call by a request rate measured per minute, set by the account's plan, with tighter ceilings on some endpoints. Going over returns a 429 response with a Retry-After header.
Zendesk meters Support and Help Center API requests by a per-minute rate set by the account's plan: 200 requests per minute on Team, 400 on Professional, 700 on Enterprise, and 2,500 on Enterprise Plus. The High Volume API add-on raises a qualifying plan to 2,500 per minute. Some endpoints carry their own tighter ceilings on top, like 30 ticket updates per 10 minutes per user per ticket, 5 requests per minute per user or organization record, 100 requests per minute on search export, and 50 requests per minute when listing tickets beyond page 500. Going over returns HTTP 429 with a Retry-After header giving the seconds to wait, and the x-rate-limit header reports the account's limit and the requests remaining in the current minute.
List endpoints page with a cursor: the response carries a meta object with has_more and an after_cursor, passed back as page[after] to fetch the next page, with page[size] up to 100. Cursor-based pagination is now supported on all paginating endpoints, and the older offset-based pagination through the page parameter is being deprecated. The unified search returns at most 1,000 results across pages; the search export endpoint uses a cursor for larger sets.
A list endpoint returns at most 100 records per page. The unified search returns at most 1,000 results total per query; larger result sets use the search export endpoint. Create-many and update-many batch endpoints accept up to 100 records per request and run as background jobs.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed, such as invalid JSON or a missing required header. | Read the error and description fields in the body, correct the request, and resend. |
| 401 | Unauthorized | Authentication failed or was missing, returned with a 'Couldn't authenticate' message. The token or API-token credentials are invalid or expired. | Send valid API-token or OAuth credentials in the Authorization header, and confirm the token has not expired. |
| 403 | Forbidden | The credentials are valid but the user, account, or token scope lacks permission for the request. | Use an agent or admin with the needed role, or grant the OAuth token the matching scope. |
| 404 | Not Found | The requested resource does not exist or is not visible to this account. | Verify the ID and the path, and confirm the resource lives in this account. |
| 409 | Conflict | The request conflicts with the current state, such as two ticket updates colliding under optimistic locking. | Refetch the current ticket state, reapply the change, and retry. |
| 422 | Unprocessable Entity | The request was well-formed but its content is not processable, for example a validation failure where a required field is missing or invalid (RecordInvalid). | Read the details in the body, correct the named fields, and resend. |
| 429 | Too Many Requests | A rate limit was exceeded, either the account's per-minute limit or a tighter per-endpoint limit. | Wait the number of seconds in the Retry-After header before retrying, and smooth the request rate. |
| 500 | Internal Server Error | An error on Zendesk's side, which can also appear as 502, 503, or 504. A 503 may carry a Retry-After header during maintenance. | Retry with backoff, honoring any Retry-After header, and contact Zendesk support if it persists. |
The Zendesk Support REST API is served under a single stable version, v2, in the path /api/v2. It does not use dated versions; changes ship through the developer changelog, and breaking changes are announced ahead of time with deprecation dates.
The Zendesk Support REST API is served under one stable version, v2, in the path /api/v2. It does not use dated versions or a version header. New capabilities and breaking changes are announced through the developer changelog with deprecation dates, rather than minting a new version string. The entries below are notable dated changes from that changelog.
The legacy *.ultimate.ai API base URL for AI Agents was deprecated, with integrations directed to the {subdomain}.zendesk.com/ai-agents/api endpoint instead.
Zendesk announced enforcement of default token expiration and the refresh-token flow for external OAuth applications, beginning 2 February 2026 and rolling out to existing clients over time.
All ticket updates were placed behind a concurrency-control mechanism called optimistic locking, so two colliding updates to the same ticket return a 409 Conflict instead of silently overwriting.
Incremental user export operations were rate-limited, with standard accounts allowed 20 requests per minute and High Volume add-on accounts 60 per minute.
Track the changelog for deprecations and announced auth changes.
Zendesk API changelog ↗Bollard AI sits between a team's AI agents and Zendesk. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.