How to Build a Support Ticket API Integration (with Code)
A practical guide to integrating a support ticket API: create tickets from your app, add replies and internal notes, sync tickets, receive webhooks with signature verification and handle rate limits.
TickOS Team · Oct 17, 2026 · 6 min read
Email and contact forms cover most support requests, but sooner or later your product needs to talk to your help desk directly: a "Contact support" button inside the app, an automatic ticket when a payment fails, or a "My tickets" page in the customer's account.
That's what a support ticket API is for. This guide walks through a complete integration, with working code: creating tickets from your backend, adding replies and internal notes, syncing tickets, receiving webhooks securely and handling errors and rate limits. The examples use the TickOS API, but the patterns apply to any help desk.
What you can build with a ticket API
- In-app support form. The customer is already logged in, so you know who they are, their plan and what page they were on. No need to ask for their email again.
- Automatic tickets. Create a ticket when a payment fails, an import breaks or a customer hits a critical error, before they even write to you.
- "My tickets" in your app. Show customers the status of their requests without leaving your product.
- Internal tools. Add diagnostic data to a ticket as a private note, or open tickets from your admin panel.
- Sync with other systems. React to new tickets and replies from your CRM, Slack, data warehouse or an AI agent.
How the integration fits together
The architecture is the same for almost every use case:
- Your frontend sends the request to your backend (never directly to the help desk).
- Your backend adds what it knows about the user and calls the ticket API with a secret key.
- The help desk creates the ticket, notifies your team and emails the customer when your team replies.
- Webhooks tell your backend when something changes, like a new reply.
Never expose your API key
API keys give access to your whole workspace. Keep them in an environment variable on the server and never send them to the browser or commit them to source control.
Step 1: Create an API key
In TickOS, go to Settings → Developers and create an API key. Keys start with sk_ and have one of three permission levels: read, write or admin. Creating tickets and messages needs write. Use a separate key per integration, so you can revoke one without breaking the others.
Store it as an environment variable:
Every request authenticates with a Bearer token:
Step 2: Create a ticket from your backend
A ticket needs a subject, a message and a customer. If the customer's email doesn't exist yet, TickOS creates the customer automatically. Use metadata to attach anything your team will need later, like the user ID, plan or the page they were on.
Then expose a small route that your in-app form calls. Here's a Next.js route handler; the same idea works in Express, Rails, Django or Laravel:
The API responds with 201 and the new ticket. Show the client_id to the customer ("Your request SUP-000142 was received"), and store the ticket id if you plan to update it later.
A few optional fields are worth knowing:
Step 3: Add replies and internal notes
Messages are added to an existing ticket with POST /v1/tickets/{id}/messages. The direction field decides what kind of message it is:
Internal notes are perfect for diagnostic data your team needs but the customer shouldn't see:
direction defaults to inbound
If you want to email the customer, send direction: "outbound" explicitly. Without it, the message is stored as if the customer had written it, and no email is sent.
Step 4: Show a customer their tickets
To build a "My tickets" page, list tickets filtered by the customer and show their status. The search parameter matches subject, ticket ID, customer email and name, so filter the results by exact email on your side:
Ticket statuses move through open, pending (waiting on the customer), review (the customer replied), resolved and closed. A customer reply automatically reopens resolved and closed tickets.
Step 5: Receive webhooks
Polling is fine for a "My tickets" page, but for anything real-time, use webhooks. Add a webhook URL to an inbox (in the inbox settings or with PATCH /v1/inboxes/{id}) and choose the events you need:
Each delivery is a POST with a JSON body like this:
Verify the signature
Every delivery from a webhook with a secret includes an X-Tickos-Signature header with a timestamp and an HMAC-SHA256 signature. Always verify it before trusting the payload, using the raw request body and a constant-time comparison. Rejecting old timestamps protects you from replayed requests:
A few rules for reliable webhooks:
- Respond with a 2xx quickly. Deliveries time out after 10 seconds, so move slow work to a background job.
- Expect events out of order. Use the
timestampand the resource'supdated_atto decide what's newest. - Make handlers idempotent. Processing the same event twice shouldn't create duplicates on your side.
- Reconcile after downtime. TickOS attempts each delivery once and doesn't retry, so if your endpoint was down, list what changed with
GET /v1/tickets?updated_after=....
Step 6: Handle errors and rate limits
Plan for these responses from day one:
Rate limits are per API key and per minute: 120 on Free, 600 on Starter, 1,500 on Pro and 6,000 on Enterprise. A small helper that respects Retry-After covers most cases:
Never retry a ticket creation blindly after a network timeout: the first request may have succeeded. Store the ticket ID as soon as you get it, and check before creating a second one.
The same flow in Python
If your backend is in Python, the create call looks like this:
Launch checklist
- The API key lives in an environment variable on the server, with
writepermission only. - Your form validates input and shows a friendly error if ticket creation fails.
- Tickets include useful
metadata(user ID, plan, page) for your team. - Webhook signatures are verified with the raw body, and old timestamps are rejected.
- Webhook handlers respond fast and are idempotent.
- You handle
429withRetry-Afterand never blindly retry ticket creation. - You've tested the full loop: create a ticket from the app, reply from the help desk, receive the
message.createdwebhook.
Going further
The full reference, including every field, filter and error, is in the TickOS API documentation. A good next read is the tickets reference and the webhooks guide. If you also send transactional email from your app, our comparison of Resend alternatives shows how to do it from the same platform. And if you're still choosing how customers reach you, start with how to turn emails into support tickets.
Frequently asked questions
A support ticket API lets your own software create, read and update tickets in a help desk over HTTP. Typical uses are a contact form inside your app, automatic tickets for failed payments or errors, showing a customer's tickets in their account, and syncing tickets with other tools.