zendesk_write_ticket, the native Zendesk ticket-update tool exposed through the Agents Platform.
Authentication & enablement
Uses the same per-workspace Zendesk connection as zendesk-read-ticket.md — API token or OAuth. Off by default — add it to an agent explicitly.zendesk_write_ticket
Updates a Zendesk ticket by numeric id. This is a mutating tool. It can set custom fields, add and remove tags, add an internal note, and set the requester (name/email).
It is generic: it does NOT enforce any skip/guard policy (for example “skip if the ticket already has an assignee”). Implement that logic in the agent by calling zendesk_read_ticket first and deciding before you write.
Inputs
Required:ticket_id: numeric Zendesk ticket id.
custom_fields: a JSON object string keyed by numeric field id, e.g.{"360000012345":"Reviewed","360000067890":true}. Only the included fields are changed; other fields are untouched.tags: an array of tags to add (additive — existing tags are preserved).remove_tags: an array of tags to remove (additive — only these are removed; other tags stay). Combine withtagsto swap a tag, e.g. remove…_unsuccessfuland add…_successful.internal_note: an internal (private) note; not visible to the requester.requester_email(+ optionalrequester_name): set the ticket’s requester. Zendesk resolves an existing end user with this email, or creates one, and sets them as the requester.requester_nameis ignored unlessrequester_emailis set.
url, email, and api_token are injected from the connected integration.
Side effects
- Custom fields, the optional internal note, and the requester are applied in a single ticket update (
PUT /api/v2/tickets/{id}.json). Embeddingrequester:{name,email}in the ticket PUT makes Zendesk resolve/create the end user by email — it never calls the Users API, so it can’t create duplicate users or edit the wrong one. - Tags are added (
PUT …/tags.json, Zendesk’s additive “Add Tags”) and removed (DELETE …/tags.json, “Remove Tags”) via the dedicated tags endpoints, so the ticket’s other tags are always preserved. Zendesk inverts the usual REST verbs here —POST …/tags.jsonis “Set Tags” and would replace the entire tag set (as would a ticket-PUTtagsfield) — so this tool usesPUT/DELETEand neverPOST. - After writing, the tool re-reads the ticket and returns its resulting tags and assignment state.
Output
custom_fields (field id → value), internal_note, and requester_email/requester_name echo the values that were written, so the feed card can show what changed rather than just counts; each is omitted when that kind of change wasn’t made. field_names maps written field id → Zendesk field title (from a cached GET /api/v2/ticket_fields lookup) so the card can label custom fields by name; it’s omitted when the lookup fails, and the card then falls back to the id. resulting_* reflect a post-write re-read of the ticket. resulting_state_known gates them: when it is false the re-read failed (the write still succeeded) and the other resulting_* values are not meaningful. requester_update_sent means a requester update was sent (a requester_email was supplied), not that Zendesk confirmed it — check resulting_requester_id for the post-write requester. ticket_url is the ticket’s Zendesk web URL (omitted if the connection URL can’t be normalized).
Limits & errors
- Custom-field ids are per-workspace; get them from the workspace’s Zendesk configuration or from
zendesk_read_ticket. custom_fieldsmust be a JSON object string with numeric-id keys — a non-numeric key or malformed JSON is rejected before any write happens.HTTP 404→ check theticket_id;HTTP 401/403→ reconnect the integration;HTTP 422→ Zendesk rejected the values (e.g. an invalid field id or value).
Agent Instruction Guidance
To avoid overwriting a ticket a human has already picked up, callzendesk_read_ticket first and skip the write when is_assigned is true. Confirm the resolved field-id → value mapping against the workspace’s Zendesk configuration before writing, since field ids are tenant-specific. Any policy about when to set the requester (e.g. only for certain channels, skipped for some ticket types) is the agent’s decision — the tool sets the requester only when you pass requester_email. Use remove_tags + tags together for an outcome tag swap.