zendesk
Three things a twin of this API has to get right
Every response is wrapped in a named key —{"ticket": …}, never a bare object — so a twin answering bare objects fails a caller on its first read. Every identifier is an integer: 35436, not "35436", and every relation is an integer foreign key. And there are three error envelopes, all real and all branched on separately:
That inconsistency is Zendesk’s, and reproducing it is the point: a client written against the real API has branches for all three, and a twin that normalised them would let a caller ship code that crashes on the shape it did not see.
Two pagination mechanisms, both live
Zendesk is mid-migration from offset to cursor pagination and callers use both, on the same endpoints.page[size] opts a request into cursor pagination — meta.has_more, meta.after_cursor, links.next — and its absence means offset pagination, with next_page, previous_page and count. Offset is capped at 100 pages and 10,000 records, which the twin enforces with Zendesk’s own error rather than truncating silently, because that cap is the exact wall a caller hits in production. Every links.next and every url points at the container’s own host, so a paginating client cannot walk out of the sandbox.
What it models
Advancing the sandbox does three things, because three things in a helpdesk age: a solved ticket becomes closed once the account’s close window has passed — which no API call can trigger, and which is why
advance exists — a queued bulk job moves towards completed, and an unanswered ticket crosses its first-reply target.
Scenarios
busy-helpdesk, wismo-queue, closed-ticket, sla-breached, end-user-token, rate-limited, pending-bulk-job.
Not modelled
Help Center and Guide, Talk and Chat, Sunshine Conversations and messaging, Side Conversations, Explore and reporting, triggers and automations, SLA policy evaluation (the twin models one first-reply target so a breach is reachable, not a policy engine), the Apps framework, webhooks, custom objects, Sell, attachments and uploads, views, and the admin APIs beyond what the sandbox’s own directives need. The Support API has no dated releases, so the twin’s behaviour is pinned to the OpenAPI document’s version and to the date that document and the API reference were read. No live Zendesk account was available when it was built — the trial locks after fourteen days, which is a large part of why this twin exists — so its README lists every place a live account would settle something the twin had to decide, including what Zendesk does when a ticket is assigned to an agent outside its group. A route Zendesk has and the twin has not built answers a501 carrying a value Zendesk never sends, rather than RecordNotFound, which would read as missing data and send a caller away.