When a Tag Was Added in Zendesk
You can't do this in Explore. Zendesk Explore reports on which tickets currently have a tag, not the moment that tag was applied, and that gap is old enough and common enough that it has its own idea in Zendesk's community forum, open since March 2021 and marked "Parked" under the Analytics product area. The timestamp you want does exist. It's recorded in the ticket's event history the moment the tag changes. It's just not a field Explore's report builder can reach.
The actual answer lives one layer down, in the Ticket Audits API. Every time a ticket's tags change, Zendesk writes a Change event with field_name: "tags", a previous_value array, a value array, and a created_at timestamp on the audit that contains it. That's the record of when the tag was added. Getting it into a usable report means pulling it via API rather than the Explore UI, which is a different job than most support teams expect to take on.
Why Explore can't answer this
Explore's datasets are built for counting current attributes, not for diffing a ticket's history field by field. Tags are one of those attributes. You can filter and group by "has tag X," but there's no "tag X was added on this date" column to pull into a report.
For a while, there was a workaround. A calculated attribute on the Ticket Updates dataset, built off [Changes - Field Name], [Changes - Previous Value], and [Changes - New Value], could catch the moment a tag string entered or left the ticket. Several people documented the exact formula on the community thread linked above. Then Zendesk removed "Ticket tags" as a possible value of [Changes - Field Name], and every report built that way broke at once. One admin, tracking Explore for their team, wrote it up plainly: "I was trying to set up something similar today and noticed that 'Ticket Tags' no longer shows under the [Changes - Field Name] results... The only other way to track this now is by leveraging data we're collecting from the Support API Ticket Audits endpoint." That's still the state of things.
The workaround Zendesk support does still recommend is to attach the tag to a checkbox or dropdown custom field instead of a free tag, then build a calculated attribute on when that field changed. It works, but only for tags you're willing to convert into fields ahead of time, and it doesn't help with the tags already in your account.
Where the timestamp actually is
The Ticket Audits API is Zendesk's own description of it: "a read-only history of all updates to a ticket." Call GET /api/v2/tickets/{ticket_id}/audits and you get every audit for that ticket, each one carrying a created_at and an events array. Find the Change event where field_name is "tags", compare previous_value to value, and the audit's created_at is your answer: the exact time the tag was added, down to the second, with whichever agent or trigger made the change attached as author_id.
That per-ticket endpoint doesn't turn into an account-wide report just by looping it over every ticket: you'd need to already know every ticket ID up front, and it's one API call per ticket against Zendesk's rate limits. Zendesk does publish an account-wide audits list too (GET /api/v2/ticket_audits), on the same API reference page, but its own docs warn it off for this exact job: "This endpoint should not be used for capturing change data. When continually chasing the tail of a cursor, some records will be skipped." For that, there's the Incremental Ticket Event Export API: GET /api/v2/incremental/ticket_events?start_time={start_time}, a paginated stream of every field change across every ticket since a given time, including tag changes. That's the endpoint built for exactly this job: watch it continuously, filter for field_name: "tags", and you have a timestamped log of every tag ever added or removed, account-wide.
The report Driftpoint actually needed
Driftpoint runs telematics hardware for regional trucking fleets, and its support team tags a ticket hardware-recall the moment a customer reports the specific sensor fault behind an active recall. Priya Okafor, who runs support ops, had a contractual 30-day clock, timed from the moment a fleet reported the fault rather than from when the ticket eventually closed, inside which Driftpoint owed a replacement unit.
Priya, in the weekly ops review: Compliance is asking which recall tickets are past day 25. Explore's showing me every ticket tagged
hardware-recallright now, but not one of them says when the tag went on. Half of these were reopened twice, so "ticket created" isn't the clock we agreed to.Support engineer: The create date's the wrong field for sure. If the tag got added on a reopen, the audit trail's it, not the ticket metadata.
The fix looked exactly like the API section above: a small script polling incremental/ticket_events on a cron, filtering for field_name: "tags" where the new value contains hardware-recall and the previous value doesn't, and writing ticket ID, tag, and event timestamp to a table Priya's team could actually query against the 30-day clock. It took an afternoon to build and has run unattended since. Widen the filter to a different tag, or change what counts as "past day 25," and someone has to go back into that script.
Where the audit-log approach stops working
Building against the Ticket Audits or Incremental Ticket Event Export API is the correct fix, and it's also a maintained system now. Something has to run the poll, store the output somewhere queryable, handle pagination and rate limits, and get touched again every time the reporting question changes shape. That's a reasonable cost for one clock, like Driftpoint's recall SLA. Storing the unfiltered stream instead of Driftpoint's narrow single-tag filter turns a second or third tag into a query change, not new scripting, so that part scales fine on its own. Where it stays a real gap is identity: neither API tells you which account or which person is behind a given ticket, so answering "who actually asked for this" means building and maintaining that resolution yourself, on top of the poll.
At that point, most teams are asking for a system that already treats every tag change as a timestamped event and keeps it attached to the person and company behind the ticket, without building identity resolution from scratch. Modem is one option built for that. It connects to Zendesk over the documented integration, which registers a webhook and receives ticket activity, tags included, as it happens rather than as a periodic export, and matches it to the person and company record it already keeps. Because each update lands as structured, attributed data the moment it occurs, "when was this tag added, and to whose ticket" is a question you can ask directly instead of one you have to re-derive from an audit log.
Disclosure: we build Modem. A cron job against the Incremental Ticket Event Export API still handles Driftpoint's exact problem for free, and it always will. What that script doesn't do is resolve who's behind the ticket across tools, which is the piece Modem is built to close.
For the related, more common version of this problem, the volume-by-account question, see why Zendesk Explore can't tell you which companies asked for a feature. If tag sprawl itself is the issue rather than the timestamp, how to audit Zendesk macro and tag sprawl covers cleaning up the taxonomy before you build any report on top of it.
Prove it on one ticket before you script anything
Pull one ticket's audits with GET /api/v2/tickets/{ticket_id}/audits and find the Change event for field_name: "tags" by hand. That confirms the data's there and shows you the exact shape of previous_value and value for your account's tags. From there, a script against the Incremental Ticket Event Export API, filtered to the one tag you actually need a timestamp for, is a day of work, not a project.
