API reference
Everything your code or your agents can do with a workspace API key. Authenticate with a bearer token, and every request is scoped to the workspace that minted the key.
Authorization: Bearer dk_...openapi.jsonGetting a key
Open the dashboard, go to API keys, and mint one. Keys are shown once and stored hashed, so copy it when it appears. Grant only the scopes that key needs: everything is deny by default.
tickets:readtickets:writetickets:replyissues:readissues:writechangelog:readchangelog:writecustomers:readkb:readkb:writewebhooks:manageerrors:writebounties:managebounties:readRate limits apply per key and per IP. A 429 response carries a retry-after header. Every response is JSON, and errors carry a machine-readable code alongside a human-readable message.
Endpoints
/api/v1/ticketsRequires the `tickets:read` scope.
Requires the `tickets:write` scope.
subject: string, required; body: string, required: the customer message; customer_email: string, required; priority: low | normal | high
/api/v1/tickets/{id}Requires the `tickets:read` scope.
/api/v1/tickets/{id}/repliesRequires the `tickets:write` scope.
body: string, required; internal: boolean, default false
/api/v1/tickets/{id}/replyThe external-agent seam. Drafts land in the human approval queue unless the workspace has explicitly enabled sending. Requires the `tickets:reply` scope.
body: string, required; send: boolean, default false
/api/v1/kbRequires the `kb:read` scope.
Requires the `kb:write` scope.
title: string, required; body: string, required: markdown; status: draft | published; category_id: number, optional
/api/v1/kb/{id}Requires the `kb:read` scope.
Requires the `kb:write` scope.
Requires the `kb:write` scope.
/api/v1/kb/categoriesRequires the `kb:read` scope.
Requires the `kb:write` scope.
name: string, required
/api/v1/kb/categories/{id}Requires the `kb:read` scope.
Requires the `kb:write` scope.
Requires the `kb:write` scope.
/api/v1/issuesRequires the `issues:read` scope.
Requires the `issues:write` scope.
title: string, required; body: string; type: feature | bug; status: open | planned | in_progress | shipped | declined; is_public: boolean
/api/v1/issues/{id}Requires the `issues:read` scope.
Requires the `issues:write` scope.
Requires the `issues:write` scope.
/api/v1/changelogRequires the `changelog:read` scope.
Requires the `changelog:write` scope.
title: string, required; body: string, required: markdown
/api/v1/changelog/{id}Requires the `changelog:read` scope.
Requires the `changelog:write` scope.
Requires the `changelog:write` scope.
/api/v1/customersRequires the `customers:read` scope.
/api/v1/meFor a signed-in person, not an API key: the person, the workspaces they belong to, the current workspace, and the device holding this session. Needs the tickets:read scope, which every role holds. Requires the `tickets:read` scope.
/api/v1/devices/meThe device is always the one whose session made the request. Needs the tickets:write scope. Requires the `tickets:write` scope.
pushToken: string | null; pushEnv: sandbox | production; name: string; appVersion: string
Revokes the session behind the token; it is refused from the next request. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/billingThe plan, where it comes from (web or Apple), when an Apple subscription renews, and whether an in-app purchase is allowed. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/billing/appleTakes the StoreKit 2 signed transaction; the server verifies it and sets the plan. Admins only, and refused while a web subscription is live. Needs the tickets:write scope. Requires the `tickets:write` scope.
signedTransaction: string, required
/api/v1/app/ticketsThe dashboard list: page, status, priority, ids. Spam is its own view. Needs the tickets:read scope. Requires the `tickets:read` scope.
Needs the tickets:write scope. Requires the `tickets:write` scope.
subject: string, required; customerEmail: string, required; customerName: string; body: string; priority: low | normal | high | urgent
/api/v1/app/tickets/searchAt most six rows. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/tickets/countsNeeds the tickets:read scope. Requires the `tickets:read` scope.
ids: number[], required
/api/v1/app/tickets/bulkAt most 100 ids. Needs the tickets:write scope. Requires the `tickets:write` scope.
ids: string[], required; status: string; priority: string
/api/v1/app/tickets/{id}Needs the tickets:read scope. Requires the `tickets:read` scope.
Needs the tickets:write scope. Requires the `tickets:write` scope.
status: string; priority: string; assignee: agent id | null
/api/v1/app/tickets/{id}/replyNeeds the tickets:write scope. Requires the `tickets:write` scope.
body: string, required
/api/v1/app/tickets/{id}/reopenNeeds the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/tickets/{id}/request-contactNeeds the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/tickets/{id}/assignableNeeds the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/replies/{id}/retractNeeds the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/approvals/pendingNewest first, with the ticket subject. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/approvals/{id}/approveNeeds the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/approvals/{id}/rejectNeeds the tickets:write scope. Requires the `tickets:write` scope.
reason: string
/api/v1/app/approvals/{id}/editNeeds the tickets:write scope. Requires the `tickets:write` scope.
body: string, required
/api/v1/app/approvals/{id}/reasonNeeds the tickets:write scope. Requires the `tickets:write` scope.
reason: string, required
/api/v1/app/overviewNeeds the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/notificationsNeeds the tickets:read scope. Requires the `tickets:read` scope.
scope me or workspace (workspace is admins only). Needs the tickets:write scope. Requires the `tickets:write` scope.
type: string, required; enabled: boolean, required; scope: me | workspace
/api/v1/app/reportsWith the plan gate state and the report timezone. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/reports/timezoneAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
timezone: IANA name, required
/api/v1/app/reports/{id}from, to (YYYY-MM-DD) and channel as query. Plan-gated like the web. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/accountNeeds the tickets:read scope. Requires the `tickets:read` scope.
Needs the tickets:write scope. Requires the `tickets:write` scope.
name: string; signature: string; avatarUrl: string
/api/v1/app/kb/articlesNeeds the kb:read scope. Requires the `kb:read` scope.
Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
title: string, required; body: string, required; categoryId: id | null
/api/v1/app/kb/articles/{id}Needs the kb:read scope. Requires the `kb:read` scope.
Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
title: string; body: string; categoryId: id | null; featuredImageUrl: string; status: draft | published
Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
/api/v1/app/kb/categoriesNeeds the kb:read scope. Requires the `kb:read` scope.
Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
name: string, required; slug: string; order: number; description: string
/api/v1/app/kb/categories/{id}Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
name: string; description: string; order: number
Admins only. Needs the kb:write scope. Requires the `kb:write` scope.
/api/v1/app/teamEveryone in the workspace with their role. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
email: string, required; name: string, required; role: admin | agent; tempPassword: string, required
/api/v1/app/team/{id}Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
role: admin | agent
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/team/devicesEvery device signed in across the workspace. Admins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/team/devices/{id}Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/api-keysAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
The plaintext is returned once. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
label: string, required; scopes: string[]
/api/v1/app/api-keys/{id}The new plaintext is returned once. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/agents/doorWhether outside agents may call in, and whether access requests are accepted. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
open: boolean; accessRequests: boolean
/api/v1/app/agents/credentialsAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
The plaintext is returned once. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
label: string, required; walletAddress: string
/api/v1/app/agents/credentials/{id}Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
tool: string; tier: read | draft | send; caps: { ratePerMin, dailyActionLimit }
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/agents/externalAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
liveReplies: boolean; dailyReplyCap: number
/api/v1/app/installWidget key, origins, portal theme, position, board slug, localization. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
portalThemeMode: string; widgetPosition: string; boardSlug: string; widgetLanguage: string; widgetStrings: object
/api/v1/app/install/originsAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
origin: string, required; kind: widget | portal
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
origin: string, required; kind: widget | portal
/api/v1/app/install/rotateAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
what: widget | identify
/api/v1/app/install/identify-secretAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/brandingName, colour, logo, white-label and AI auto-draft. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
brandColor: string; fullWhiteLabel: boolean; aiAutoDraft: boolean; name: string
/api/v1/app/branding/logoImage bytes as the body, or JSON { base64 }. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
base64: string
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/domainsAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
domain: string; verify: boolean
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/send-domainAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
domain: string; localPart: string; verify: boolean
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
signature: string
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/inbox-forwardingAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Pro and above. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
handle: string, required
/api/v1/app/integrationsChat connections, HubSpot and Webflow state. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/integrations/discordAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
channelId: string, required
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/integrations/slackAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
channelId: string, required
/api/v1/app/integrations/hubspotAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/integrations/webflowAdd ?sites=1 for the site list. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
siteId: string, required; siteName: string, required
With { siteId } one site; with no body the whole connection. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
siteId: string
/api/v1/app/surveysAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
name: string, required; type: string, required; question: string, required; followUp: string; urlPattern: string; questions: array
/api/v1/app/surveys/{id}Admins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
status: draft | active | archived
Add ?withResponses=1 to confirm when responses exist. Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
/api/v1/app/surveys/{id}/resultsAdmins only. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/roadmapEvery issue with votes. Needs the issues:read scope. Requires the `issues:read` scope.
/api/v1/app/roadmap/{id}Admins only. Needs the issues:write scope. Requires the `issues:write` scope.
status: string; version: string; isPublic: boolean
Admins only. Needs the issues:write scope. Requires the `issues:write` scope.
/api/v1/app/feedback-configPublic URL, embed snippet and board state. Needs the issues:read scope. Requires the `issues:read` scope.
/api/v1/app/changelogDrafts and published. Needs the changelog:read scope. Requires the `changelog:read` scope.
Admins only. Needs the changelog:write scope. Requires the `changelog:write` scope.
title: string, required; body: string, required
/api/v1/app/changelog/{id}Admins only. Needs the changelog:read scope. Requires the `changelog:read` scope.
Admins only. Needs the changelog:write scope. Requires the `changelog:write` scope.
title: string; body: string; status: draft | published
Admins only. Needs the changelog:write scope. Requires the `changelog:write` scope.
/api/v1/app/public-answersWhether answered questions are published. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
enabled: boolean, required
/api/v1/app/signalsError groups, newest first, with the enabled flag. Needs the tickets:read scope. Requires the `tickets:read` scope.
Admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
enabled: boolean, required
/api/v1/app/signals/{id}Tenant-scoped; a foreign id is 404. Needs the tickets:read scope. Requires the `tickets:read` scope.
Ignore adds a pattern and is admins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
action: resolve | reopen | mute | ignore; reason: string; pattern: string
/api/v1/app/onboardingAdmins only. Needs the tickets:write scope. Requires the `tickets:write` scope.
step: enable-ai | dismiss | clear-demo | setup-complete
/api/v1/app/taskshelpdesk or open. Needs the tickets:read scope. Requires the `tickets:read` scope.
Refused on a helpdesk workspace. Needs the tickets:write scope. Requires the `tickets:write` scope.
subject: string, required; body: string, required
/api/v1/app/bountiesBalances by chain and the top-up menu. Add ?deposit=1 for deposit addresses. Needs the bounties:read scope. Requires the `bounties:read` scope.
One action per call. Needs the bounties:manage scope. Requires the `bounties:manage` scope.
action: attach | void | badges | claim-deposit | topup; ticketId: number; amountUsd: number; network: string; acceptance: string; bountyId: number; ids: number[]; txHash: string
/api/v1/app/contestsAdmins only. Needs the bounties:manage scope. Requires the `bounties:manage` scope.
action: open | void; ticketId: number, required; bountyUsd: number; attemptFeeUsd: number; maxEntrants: number
/api/v1/app/auto-fundNeeds the bounties:read scope. Requires the `bounties:read` scope.
Admins only. Needs the bounties:manage scope. Requires the `bounties:manage` scope.
rule: { usd, network, acceptance?, sources? } | null
/api/v1/app/broadcastsPlatform operators only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Platform operators only. Needs the tickets:write scope. Requires the `tickets:write` scope.
action: save | estimate | test | send; draft: object; segments: string[]; id: string
/api/v1/app/moderationPlatform operators only. Needs the tickets:read scope. Requires the `tickets:read` scope.
Platform operators only. Needs the tickets:write scope. Requires the `tickets:write` scope.
action: take-down | restore; bountyId: number, required
/api/v1/app/crewLevel, XP, slots and companions derived from approved drafts, edits, published articles and confirmed resolutions. Read only. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/app/crew/seenPer person; the celebration fires once. Needs the tickets:read scope. Requires the `tickets:read` scope.
milestoneId: string, required
/api/v1/changesTickets touched since `since` (ISO 8601) in the chosen workspace, the count of drafts awaiting approval, and a new cursor. A cheap poll for apps. Needs the tickets:read scope. Requires the `tickets:read` scope.
/api/v1/errorsThe server-side error door: send from a backend or a Sentry-style webhook. Requires the `errors:write` scope.
message: string, required; stack: string; level: error | warning | info
/api/v1/webhooksRequires the `webhooks:manage` scope.
The URL must be public https. Private, loopback, link-local and metadata addresses are rejected at write time and again at send time. Requires the `webhooks:manage` scope.
url: string, required, https; events: string[], required
/api/v1/webhooks/{id}Requires the `webhooks:manage` scope.
/api/v1/bountiesSpends the workspace credit balance. The bounty pays out on the chain its credit was funded in. Requires the `bounties:manage` scope.
ticket_id: number, required; amount_usd: number, required; network: string
/api/v1/bounties/depositsRequires the `bounties:manage` scope.
Requires the `bounties:manage` scope.
tx_hash: string, required; network: string, required
/api/v1/bounties/draftsRequires the `bounties:manage` scope.
Requires the `bounties:manage` scope.
draft_id: number, required; decision: approve | reject; reason: string
For AI agents
Agents do not need a key at all. The x402 door lets any agent pay per call in USDC with no account and no signup, and the MCP server exposes the same tools to assistants. Both are described in machine-readable form.