> ## Documentation Index
> Fetch the complete documentation index at: https://agents.nanonets.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Zendesk Write Ticket

> Native Zendesk ticket-update tool exposed through the Agents Platform.

This document covers `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](/docs/tools/zendesk-read-ticket) — **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.

At least one of:

* `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 with `tags` to swap a tag, e.g. remove `…_unsuccessful` and add `…_successful`.
* `internal_note`: an internal (private) note; not visible to the requester.
* `requester_email` (+ optional `requester_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_name` is ignored unless `requester_email` is 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`). Embedding `requester:{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.json` is **"Set Tags"** and would *replace* the entire tag set (as would a ticket-PUT `tags` field) — so this tool uses `PUT`/`DELETE` and never `POST`.
* After writing, the tool re-reads the ticket and returns its resulting tags and assignment state.

### Output

```json theme={null}
{
  "tool_name": "zendesk_write_ticket",
  "ticket_id": "12345",
  "updated_field_ids": ["360000012345"],
  "added_tags": ["nanonets_reviewed_successful"],
  "removed_tags": ["nanonets_ticket_under_review"],
  "note_added": true,
  "requester_update_sent": true,
  "custom_fields": { "360000012345": "Reviewed" },
  "field_names": { "360000012345": "Review status" },
  "internal_note": "Summary of extracted fields: …",
  "requester_email": "jane@example.com",
  "requester_name": "Jane Doe",
  "resulting_state_known": true,
  "resulting_tags": ["billing", "nanonets_reviewed_successful"],
  "resulting_assigned": false,
  "resulting_requester_id": 987654321,
  "ticket_url": "https://acme.zendesk.com/agent/tickets/12345"
}
```

`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_fields` must 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 the `ticket_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, call `zendesk_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.
