Zendesk
Let hires search and read Zendesk tickets, reply to customers or leave internal notes, set status, assign and tag, and be woken when tickets change.
Explore 8 actions and their permissionsExact inputs, sign-in scopes, access limits and approval rules.
With Zendesk connected, a hire can:
- search tickets by words (Zendesk's own search works, like
tags:vip), status, who's assigned, who asked, or what changed since a time, - read a ticket with its whole conversation, internal notes marked,
- reply to the customer, or leave an internal note only your team sees,
- set a ticket's status, assign it to an agent or a group, and add tags.
New connections need a registered Zendesk app, coming later
Zendesk's policy now asks tools like Roster to connect through an app registered with Zendesk, not with an API token or an OAuth client of your own, and Zendesk is retiring API tokens altogether: unused ones are deleted after 30 days, and all stop working on 30 April 2027. A registered Roster app for Zendesk isn't available yet. Connections already made keep working, and the steps below are for them.
1. Choose who hires reply as
Public replies show to your customers under the name of the Zendesk agent whose credentials
Roster has. Use an agent named after your team, like Bayt Studio Support, never a made-up
person's name.
Then either:
- An API token: in Zendesk's Admin Center → Apps and integrations → APIs → API tokens
(the form in Roster links there once you've typed your subdomain), add a token named
Rosterand copy it. You'll also need that agent's email. - Your own OAuth client: in Admin Center → Apps and integrations → APIs → OAuth clients, add a client, put the callback address Roster shows on the connection as its redirect URL, and copy its identifier and secret. You'll then sign in as the agent hires reply as.
2. Connect it in Roster
- Open Integrations → Tools → Add a tool, search for Zendesk and choose it.
- How Roster signs in: An agent's email and API token (paste both), or Your own Zendesk OAuth client (paste its identifier and secret, then Connect).
- Zendesk subdomain: the part before
.zendesk.comin your Zendesk address, likebayt. - Business name: your business's name, like
Bayt Studio. - Click Connect. With an API token, Roster checks it with Zendesk, and the connection shows Connected as the agent hires reply as. If Zendesk refuses it, Roster says so and saves nothing.
3. Give hires access
On the hire's Tools tab, click Give access on Zendesk:
- Read only: it can search and read tickets and see groups, and nothing else.
- Read and write: it can also reply, leave notes, set status, assign and tag.
- Groups: group names or IDs whose tickets it may see and work on. Leave it empty for every group. A ticket in any other group is refused, even if the hire knows its number, and it can't hand a ticket to a group outside the list.
Closed tickets can't be changed in Zendesk; a hire that tries is told so.
First replies wait for approval
The first public reply a hire writes to a requester it has never written to waits for a person's approval, even though they opened the ticket. If someone on your team already replied publicly on the ticket, it doesn't ask. The hire asks in the thread with the ticket and the reply, and when the approver says yes, Roster posts exactly that reply, once. After that, replies to that requester go out without asking. Internal notes never ask, and neither do replies to people at your team's own domains.
Customers your team already talks to can be added under Settings → Workspace → People you're already in touch with (more). Approving a first reply adds the requester's address there too.
Watching tickets
A hire's responsibility can watch Zendesk: it's woken when a ticket in its groups is created or changes, with the list. Zendesk's search can take a few minutes to show a change, so a watching hire may hear about one a little late.
Saying it's an AI assistant
A hire never pretends to be a person, and always says it's AI when asked. If you also want it to say so up front, turn on Say it's an AI assistant in first messages to outsiders under Settings → Workspace (more). Then the first public reply on a ticket starts with "This is the AI assistant for" and your business name. Internal notes are never changed.
Tools and permissions reference
This reference is built from the same definitions Roster uses to connect Zendesk and give hires access. It updates with each release.
Authentication and requested permissions
The account or app you connect sets the outer limit. Each hire's access can narrow it further. Connecting a tool gives it to no hire until you give access on that hire's Tools tab.
User name and password or key pair
The email of the Zendesk agent hires act as. Replies show under that agent's name.
For: How Roster signs in: An agent's email and API token.
OAuth 2.0
From the OAuth client you made in Zendesk's Admin Center (Apps and integrations → APIs → OAuth clients).
For: How Roster signs in: Your own Zendesk OAuth client.
Requested scopes:
readwrite
Connection fields
| Field | What to provide |
|---|---|
How Roster signs insignInOptional | Use the value for your account or connection. Choices: An agent's email and API token (token); Your own Zendesk OAuth client (oauth). Starts with: |
Agent's emailemailRequired | The email of the Zendesk agent hires act as. Replies show under that agent's name. Shown when |
API tokenapiTokenRequired · sealed secret | Use the value for your account or connection. Shown when |
OAuth app client IDclientIdOptional | From the OAuth client you made in Zendesk's Admin Center (Apps and integrations → APIs → OAuth clients). Shown when |
OAuth app client secretclientSecretOptional · sealed secret | Use the value for your account or connection. Shown when |
Zendesk subdomainsubdomainRequired | The part before .zendesk.com in your Zendesk address. |
Business namebusinessNameRequired | Used when hires say they're your business's AI assistant. Never a made-up person's name. |
Per-hire limits
Read-only hires receive only actions that read. Read-and-write access also allows actions that change things, where the connection itself permits them. An empty resource allowlist usually means everything the connected account can reach; each field below explains its meaning.
| Field | What to provide |
|---|---|
GroupsgroupsOptional | Group names or IDs whose tickets it may see and work on. Leave empty for every group. |
Actions
8 actions: 3 only read and 5 change something. A read action may still need approval when your workspace or hire is set to ask. A locked approval requirement always applies.
8 of 8 actions. Open an action for its arguments and full input schema.
search_ticketsRead only
Search tickets, most recently updated first: by words (Zendesk's search syntax works, like tags:vip), status, who's assigned, who asked, or changed since a time.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
wordsOptional | string | See input schema below. |
statusOptional | "new" | "open" | "pending" | "hold" | "solved" | "closed" | "unsolved" | unsolved: new, open, pending or on hold |
assigneeOptional | string | an agent's email, "me", or "none" for unassigned |
requesterOptional | string | the customer's email |
changedSinceOptional | string | See input schema below. |
limitOptional | integer | See input schema below.Default: 20 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"words": {
"type": "string",
"maxLength": 500
},
"status": {
"description": "unsolved: new, open, pending or on hold",
"type": "string",
"enum": [
"new",
"open",
"pending",
"hold",
"solved",
"closed",
"unsolved"
]
},
"assignee": {
"description": "an agent's email, \"me\", or \"none\" for unassigned",
"type": "string"
},
"requester": {
"description": "the customer's email",
"type": "string"
},
"changedSince": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"limit": {
"default": 20,
"type": "integer",
"minimum": 1,
"maximum": 50
}
}
}read_ticketRead only
Read a ticket: its details and the whole conversation oldest first, public replies and internal notes marked.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
}
},
"required": [
"id"
]
}replyRead and write
Reply to the customer on a ticket (a public comment: they get it by email or in their chat), optionally setting its status. It goes out in the business's name: write as the business, never sign with a person's name or say you're one.
Approval: when it writes to someone outside your team for the first time.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
textRequired | string | See input schema below. |
statusOptional | "open" | "pending" | "hold" | "solved" | pending when waiting on the customer |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 20000
},
"status": {
"description": "pending when waiting on the customer",
"type": "string",
"enum": [
"open",
"pending",
"hold",
"solved"
]
}
},
"required": [
"id",
"text"
]
}add_noteRead and write
Leave an internal note on a ticket, for the team only; the customer never sees it.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
textRequired | string | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 20000
}
},
"required": [
"id",
"text"
]
}set_statusRead and write
Set a ticket's status: open, pending (waiting on the customer), on hold, or solved.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
statusRequired | "open" | "pending" | "hold" | "solved" | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
},
"status": {
"type": "string",
"enum": [
"open",
"pending",
"hold",
"solved"
]
}
},
"required": [
"id",
"status"
]
}assignRead and write
Assign a ticket to an agent (by email or name) and/or a group (by name). Only groups this hire may use.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
agentOptional | string | an agent's email or name, or "none" to unassign |
groupOptional | string | a group's name |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
},
"agent": {
"description": "an agent's email or name, or \"none\" to unassign",
"type": "string"
},
"group": {
"description": "a group's name",
"type": "string"
}
},
"required": [
"id"
]
}tagRead and write
Add tags to a ticket. Tags already there stay.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
idRequired | integer | the ticket's number, like 1234 |
tagsRequired | string[] | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "the ticket's number, like 1234"
},
"tags": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"pattern": "^[\\w-]{1,80}$"
}
}
},
"required": [
"id",
"tags"
]
}list_groupsRead only
The Zendesk groups this hire may use.
Approval: Uses your workspace and hire approval settings.
This action takes no arguments.
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {}
}Watches and incoming events
- This integration supports a responsibility that watches for changes. The guide above explains what it checks and how to limit it.
- No incoming webhook handler is declared for this integration.
Limits and troubleshooting
- Permission errors: check both the connected account's rights and the hire's resource and read/write limits.
- Expired or revoked access: reconnect or replace the key on the connection.
- Rate limits and unavailable services can interrupt work. The hire's timecard records the outcome.
- The action schema describes accepted inputs. It does not grant additional access or bypass approvals.