Back arrowAll guides

Closing the Loop on Zendesk Feature-Request Tickets

Pixel art of a glowing chain link connecting a ticket icon to a code icon on a dark navy background
Talton Figgins•••8 min read

Zendesk doesn't know whether a feature shipped, because a ticket's status only describes the ticket, not the code. A ticket you tag feature-request and mark Solved can sit there forever with no connection to whatever engineering eventually built, unless someone builds that connection on purpose. The answer to "did this ship" almost never lives in Zendesk itself. It lives in a chain: the ticket links to a tracker issue, the issue links to a pull request, the pull request merges, and somewhere in that chain something has to fire a signal back into Zendesk, or the answer stays tribal knowledge held by whoever remembers filing the ticket.

That chain is buildable, and most of the pieces already exist as native features rather than custom glue. What doesn't exist natively is the last mile: confirming that "merged" actually means "the customer can use this," which turns out to be a different claim than it sounds.

What a Zendesk ticket can tell you on its own

A Zendesk ticket's status field is one of six fixed values: New, Open, Pending, Hold, Solved, or Closed, and that's the entire vocabulary, per Zendesk's own conditions reference. None of them mean "built," "in this release," or "shipped." A ticket marked Solved could mean the agent answered a question, closed a duplicate, or genuinely resolved a bug. The field can't distinguish those cases from each other, let alone from "engineering shipped the thing you asked for."

Tags get you further, but only as far as someone applies them consistently. Zendesk triggers and automations can key off a current_tags condition, checking whether a specific tag is present or absent on a ticket, and that same condition is available in views and SLA policies too. So a tag like fr-shipped, applied by hand or by a webhook, is a real, filterable signal. The catch is the same one every tagging system runs into. It works exactly as well as the discipline behind it, and nothing enforces that discipline for you.

Step 1
Track who asked
8 accounts on “SSO requests”
↓ the fix ships
Step 2
Link to shipped work
PR #482 merged · released
✕ where most teams break — shipped, moved on, nobody told
Step 3
Tell those people
8 accounts get “SSO is live”
↺ the follow-up that closes the loop
Step two is the part Zendesk can't see into on its own. "Merged" and "released" look identical from inside a ticket unless something outside Zendesk tells it otherwise.

The chain that actually answers the question

Three links close the loop, and two of them are native features rather than something you'd build from scratch.

Ticket to tracker issue. If engineering works in Linear, Linear's Zendesk integration links a ticket to an issue directly, and if the reopening automation is turned on in Linear's settings, it automatically posts an internal note and reopens the ticket when the linked issue moves to Done or Canceled. That's the closest thing to an automatic "did it ship" signal Zendesk gets without custom work, and it's worth turning on even if you build nothing else.

Tracker issue to code. If the issue lives in Linear and the fix lands in GitHub, Linear's GitHub integration moves the issue to Done as soon as any linked PR merges, whether that link came from a branch name, an issue ID in the PR title, or a magic word in the description. A closing keyword like "fixes" or "closes" isn't required for that terminal step; it mainly decides which status a PR lands on while it's still open. The merge-target branch is configurable per team too, so a team can set "merges to main" and "merges to staging" to land on different statuses. If the team skips Linear and files issues straight in GitHub, the mechanism works differently. A PR description with "closes #482" auto-closes the linked issue the moment that PR merges, but per GitHub's own docs, only when it merges into the repo's default branch. That default-branch restriction is a GitHub rule, not one Linear's own automation shares.

Code back to the ticket. For teams without Linear in the loop, this hop is the one you build. A GitHub webhook on pull_request events, filtered to merged PRs, calls a small relay that adds a tag or comment to the linked Zendesk ticket, using the same trigger-plus-webhook pattern covered in keeping Zendesk and Jira status in sync. It's the identical shape of problem, two systems that don't talk to each other natively, bridged by a webhook and a relay.

Line those three links up and a feature-request ticket can carry a signal all the way from "someone asked" to "the PR that answers it merged." A Zendesk community thread on feature-request handling shows the shape of the problem teams are solving without this chain. The original poster didn't want to leave a ticket open for months waiting on a long-term feature, but also didn't want to lose track of notifying the customer once it landed. The chain above is exactly the mechanism that lets you close the ticket early without losing the thread.

What the three-link chain doesn't cover

The chain above is a real fix for the tribal-knowledge problem, and it still has a specific, predictable gap:

  • Merged to the default branch isn't the same claim as released to production. Feature flags, staged rollouts, and release trains all sit between a merge and a customer actually seeing the change, and none of that state is visible to a GitHub webhook.
  • The automation reports on the code you told it to watch, not on customer-visible behavior. If the fix ships as part of a larger PR without a closing keyword, or a different PR than the one referenced, the signal never fires and the ticket sits there looking unresolved forever.
  • Multiple tickets on one issue still need a rollup. If the same request arrives on three tickets from three different customers, all three need tagging and replying to individually. The chain confirms shipped; it doesn't hold a list of who to tell.

None of that argues against building the chain. It argues for treating "merged" as a strong hint that a fix is close, and confirming against your actual release process before telling a customer it's live. That's a cheap habit compared to walking back a claim that something shipped when it hadn't.

Past one repo, the same check stops covering it

The tag-plus-webhook version above works well for one team, one repo, and a release process simple enough that "merged" and "released" rarely diverge for long. It gets harder to trust once there are multiple repos, multiple requesters per issue, or a release cadence that regularly puts days between merge and rollout. With days between merge and rollout, knowing whether to reply depends on someone remembering to check the deploy pipeline every time, which is the same fragile spot the chain was supposed to get you out of.

The piece that's genuinely hard to hold in your head by hand is the multi-requester rollup: when three different tickets turn out to be the same request, someone still has to notice that and reply to all three. Handling that rollup is what we built Modem for. Its Zendesk integration captures tickets with the requester's name, company, and tags attached, and groups them with any other channel reporting the same problem. Its GitHub integration reads PR titles and descriptions so a PR can be linked to the right topic, and with the opt-in close-the-loop automation on, a merge of a directly linked PR posts a note in your team's Slack naming who asked, so the requester list survives the trip from ticket to code without a spreadsheet holding it together. We sell Modem. Below the volume described here, the habit above is the better buy. Pairing it with a real "this went out in v2.14" habit is still on you. The broader field of tools for the Zendesk side of this problem is covered in tools that mine feedback from Zendesk tickets, and the notification habit itself in notifying the exact customer who asked when their feature ships.

What to set up before you need it

Pick one path. If engineering is on Linear, open Linear's integration settings and check whether the Zendesk reopening automation is turned on. If it isn't, turning it on is the single highest-leverage minute you can spend on this. If engineering lives in GitHub alone, add one GitHub Action that tags the linked Zendesk ticket when a PR referencing it merges to main. Either way, add a written rule next to it. Before telling a customer something shipped, check whether it's actually in production, not just in the default branch. That one line is what saves you from sending a second, correcting reply.