The Zendesk API in Postman
Spend an hour with Postman and the Zendesk API before you write a line of integration code. Every hour there saves about three in a debugger later.
Why Postman before the Zendesk API code
When an integration misbehaves, you're debugging two things at once: your code and your understanding of the API. Postman removes one of them.
It also gives you something to hand over. A collection with working requests, documented variables and a couple of tests is worth more to the next developer than a page of notes, and it survives the rewrite when your integration moves from a script to a service.
Two other reasons. You can see the exact shape of a response before you model it, which stops the classic mistake of assuming a field is a string when it is an array. And you can safely test destructive calls against a sandbox by flipping one variable.
Environments before requests
Set this up first. It is the difference between a collection you keep and one you rebuild every time.
Create two environments, one for sandbox and one for production, each holding the same variable names with different values.
base_url https://acme.zendesk.com/api/v2
email integration@acme.com
api_token <secret, marked as a secret variable>
ticket_id (left blank, filled by scripts)Mark the token as a secret type so Postman keeps it out of exported files and out of shared workspaces. Never put a token in a request URL, and never commit an exported environment with a live value in it. That mistake ends with a rotated token and an uncomfortable email.
Now every request in the collection starts with {{base_url}} and switching between sandbox and production is a dropdown.
Authentication
Zendesk API token auth is HTTP basic auth with a twist: the username is your email address with /token appended, and the password is the token itself.
Set it once at the collection level, on the Authorization tab, and let every request inherit it. Doing it per request is how you end up with three requests that work and one that mysteriously 401s.
Username field:
{{email}}/tokenPassword field:
{{api_token}}If you prefer to see what is actually going over the wire, the equivalent header is a base64 encoding of that same pair.
Authorization: Basic base64(email/token:api_token)For anything a customer installs, you want OAuth rather than a token. Postman handles OAuth 2.0 natively, and Zendesk exposes the standard authorize and token endpoints under your subdomain. Check the current API reference for the exact paths and scope names.
The requests worth having
Six requests cover most of what you'll build against. Start with the simplest possible read.
GET {{base_url}}/tickets.json?page[size]=25Then a single ticket, using a variable a previous request set, so you never paste an ID by hand.
GET {{base_url}}/tickets/{{ticket_id}}.jsonThen a create, with a JSON body. Note the wrapper object, which is easy to forget and produces an unhelpful error when you do.
POST {{base_url}}/tickets.json
{
"ticket": {
"subject": "Postman test",
"comment": { "body": "Created from Postman" },
"tags": ["postman-test"]
}
}Then an update, which uses the same wrapper and only touches the attributes you send. A search, covered in the search API guide. And a side-loaded list, which is the one that teaches you the most about how to keep request counts down.
GET {{base_url}}/tickets.json?include=users,groups,organizationsThe equivalent curl, for when you want to prove something outside Postman entirely:
curl -u "$ZD_EMAIL/token:$ZD_TOKEN" -H "Content-Type: application/json" "https://acme.zendesk.com/api/v2/tickets.json?page[size]=5"Scripts that make it useful
A collection without tests is a bookmark folder. Two small scripts change that.
In the Tests tab of the create request, capture the new ID so the next request can use it.
pm.test('created', () => pm.response.to.have.status(201));
const body = pm.response.json();
pm.environment.set('ticket_id', body.ticket.id);In the list request, capture the cursor so you can page through by hitting Send again.
const body = pm.response.json();
pm.environment.set('next_page', body.links && body.links.next ? body.links.next : '');
pm.test('has results', () => pm.expect(body.tickets.length).to.be.above(0));Zendesk uses cursor pagination on modern list endpoints, which means you follow the link the API gives you rather than incrementing a page number. Prove that in Postman and your production loop will be right first time.
One more test worth adding everywhere, because it catches the failure people design for last:
pm.test('not rate limited', () => pm.expect(pm.response.code).to.not.eql(429));Rate limits are per account and vary by plan, so check the current API reference for your numbers. A 429 returns a Retry-After header and honouring it's not optional.
Before you hand it over
Run the collection with the runner against sandbox and make sure it passes end to end. Then write two sentences in the collection description saying which environment to select and where to get a token.
Delete the test tickets you created. Or tag them all postman-test and clean up with a bulk update, which is easier and more honest than pretending you will remember.
And when you export, export the collection, not the environment. That's the single most common way a Zendesk API token ends up in a git repository.
Frequently asked questions
How should Postman be set up for Zendesk?
Environments first. Postman Zendesk auth belongs in an environment variable rather than in each request, and Zendesk API environment variables for subdomain and token make Zendesk API testing against sandbox and production a one-click switch.
How do I authenticate the Zendesk API in Postman?
Use basic auth at the collection level. The username is your email with /token appended, the password is the API token. Store both as environment variables.
Is there an official Zendesk Postman collection?
Zendesk has published collections at various points, but coverage varies. Building six requests yourself takes twenty minutes and you'll understand them, which is the point.
How do I paginate in Postman?
Modern Zendesk list endpoints use cursor pagination. Capture the next link from the response in a test script into an environment variable, then use that variable as the next request URL.
Can I test against a sandbox?
Yes, and you should. Create a second Postman environment pointing at the sandbox subdomain with its own token, then switch environments from the dropdown.
How do I avoid leaking my API token?
Mark it as a secret variable, keep it out of URLs, and never export an environment with a live value. Rotate the token if an export ever reaches a repository.
Testing shows you what you are creating
Every ticket your integration opens might already exist in the queue. Ticket Merger merges the pairs before agents duplicate the work.
Start free trial14-day free trial. No credit card required.