Authenticate using HTTP Basic auth with the format {email}/token:{api_token} or OAuth 2.0 with a Bearer token; base URL is https://{subdomain}.zendesk.com/api/v2/.
POST to /api/v2/tickets with a JSON body under a 'ticket' key containing at minimum 'subject' and 'comment' (with 'body' or 'html_body'); add 'requester_id' or 'requester' object for the submitter.
Include 'tags' as an array of strings and 'custom_fields' as an array of objects with 'id' (field ID) and 'value' in the ticket body.
The response is a 201 with the created ticket object including 'id', 'status', and all fields; store the ticket ID for subsequent updates.
To update the ticket, PUT to /api/v2/tickets/{ticket_id} with the same 'ticket' wrapper; include only the fields you want to change.
Use the Tickets Create Many endpoint (POST /api/v2/tickets/create_many) for bulk creation, which returns a Job Status object to poll for completion.
Known gotchas
Custom field IDs are numeric and environment-specific — always look them up via GET /api/v2/ticket_fields rather than hardcoding values discovered in a sandbox.
Tags on a ticket are replaced entirely by a PUT update — to add tags without removing existing ones, use PUT with 'additional_tags' or first GET the ticket's current tags and merge them.
Tickets created via API with no 'via' source metadata default to 'api'; this may affect trigger conditions that filter on the 'via' channel in Zendesk automation rules.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp