<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kal Wiggins</title>
    <description>The latest articles on Forem by Kal Wiggins (@kalwiggins).</description>
    <link>https://forem.com/kalwiggins</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F591369%2F12ab6ffd-f12e-4c0a-bce9-93c6447f763b.jpeg</url>
      <title>Forem: Kal Wiggins</title>
      <link>https://forem.com/kalwiggins</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kalwiggins"/>
    <language>en</language>
    <item>
      <title>Why Per-Seat Pricing for Support Tools is Bleeding Your SaaS Dry</title>
      <dc:creator>Kal Wiggins</dc:creator>
      <pubDate>Mon, 19 Jan 2026 17:00:00 +0000</pubDate>
      <link>https://forem.com/kalwiggins/why-per-seat-pricing-for-support-tools-is-bleeding-your-saas-dry-1k4p</link>
      <guid>https://forem.com/kalwiggins/why-per-seat-pricing-for-support-tools-is-bleeding-your-saas-dry-1k4p</guid>
      <description>&lt;p&gt;You know what's weird? Every developer tool prices differently—Stripe charges per transaction, Twilio charges per message, AWS charges per compute hour. But support software? Everyone charges per seat.&lt;/p&gt;

&lt;p&gt;Zendesk, Freshdesk, Intercom, Help Scout—they all want $50-150/month for each person who can &lt;em&gt;look at&lt;/em&gt; a support ticket. And we've just... accepted this?&lt;/p&gt;

&lt;p&gt;Let me show you why this model is probably costing you way more than you think.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Tax on Modern Dev Teams
&lt;/h2&gt;

&lt;p&gt;Here's the thing about modern SaaS companies: support isn't a department anymore. It's everyone.&lt;/p&gt;

&lt;p&gt;Who needs to see support tickets?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers debugging reported bugs&lt;/li&gt;
&lt;li&gt;PMs tracking feature requests&lt;/li&gt;
&lt;li&gt;Founders responding to VIP customers&lt;/li&gt;
&lt;li&gt;DevOps checking if outages were reported&lt;/li&gt;
&lt;li&gt;Sales answering pre-purchase questions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under per-seat pricing, each of these people needs a $79/month seat. Even if the PM touches 5 tickets a month. Even if the engineer just needs to see the stack trace someone pasted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// What your costs look like&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;supportAgents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// These actually need it&lt;/span&gt;
  &lt;span class="na"&gt;engineers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// Need occasional access&lt;/span&gt;
  &lt;span class="na"&gt;productManagers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Review feature requests&lt;/span&gt;
  &lt;span class="na"&gt;founders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// VIP escalations&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seatsNeeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;team&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;monthlyBill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;seatsNeeded&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seatsNeeded&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; seats × $79 = $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;monthlyBill&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/month`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 11 seats × $79 = $869/month&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's $869/month so your engineers can occasionally check if a bug was already reported. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Workarounds Everyone Uses (And Why They're Worse)
&lt;/h2&gt;

&lt;p&gt;When seats are expensive, teams get creative:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# The shared login approach (don't do this)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ZENDESK_LOGIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;support@company.com
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ZENDESK_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hunter2
&lt;span class="c"&gt;# "Just use the team account"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Shared logins&lt;/strong&gt; - No audit trail, security nightmare, probably violates your SOC2 compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot relay&lt;/strong&gt; - Engineer: "Can you forward me that ticket?" Support: &lt;em&gt;takes screenshot, pastes in Slack&lt;/em&gt; - Now you have context in three different places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The human API&lt;/strong&gt; - Support becomes a proxy layer between your team and customer feedback. Every escalation adds latency.&lt;/p&gt;

&lt;p&gt;All of this operational overhead doesn't show up on your SaaS bill. But it's real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Talk Numbers
&lt;/h2&gt;

&lt;p&gt;I'll run through three scenarios and you can see which one looks like your company:&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario A: Small SaaS (500 tickets/month)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Per-seat model:
  3 agents + 5 occasional users = 8 seats
  8 × $79 = $632/month
  Cost per ticket: $1.26

Per-ticket model:
  $29/month for 1,000 tickets
  All 8 users included
  Cost per ticket: $0.06

Delta: -$603/month (-95%)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario B: Growing E-commerce (3,000 tickets/month)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Per-seat model:
  5 agents + 8 occasional users = 13 seats
  13 × $79 = $1,027/month
  Cost per ticket: $0.34

Per-ticket model:
  $99/month for 10,000 tickets
  All 13 users included  
  Cost per ticket: $0.03

Delta: -$928/month (-90%)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario C: Agency with 20 clients (8,000 tickets/month)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Per-seat model:
  4 staff + 15 client contacts = 19 seats
  19 × $79 = $1,501/month
  Cost per ticket: $0.19

Per-ticket model:
  $99/month for 10,000 tickets
  All 19 users included
  Cost per ticket: $0.01

Delta: -$1,402/month (-93%)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern is clear: the more people who need access, the worse per-seat pricing gets.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Elephant in the Room
&lt;/h2&gt;

&lt;p&gt;Here's where it gets really interesting. AI is changing support economics &lt;em&gt;fast&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's say you implement an AI that handles 40% of your tickets automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Per-seat economics with AI&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ticketsBefore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ticketsAfterAI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ticketsBefore&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// AI handles 40%&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seatsNeeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Still need humans for oversight&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perSeatCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// $632/month - UNCHANGED&lt;/span&gt;

&lt;span class="c1"&gt;// Per-ticket economics with AI  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perTicketCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Base tier still covers 1000&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actualCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ticketsAfterAI&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ticketsAfterAI&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Cost drops as AI handles more!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With per-seat pricing, your AI investment saves you nothing on software costs. You still need the same seats for human oversight and edge cases.&lt;/p&gt;

&lt;p&gt;With per-ticket pricing, your costs actually decrease as AI handles more volume. The efficiency gains translate directly to savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Per-Seat Actually Makes Sense
&lt;/h2&gt;

&lt;p&gt;I'm not saying per-seat is always wrong. It can work if:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You have 1-2 users total&lt;/strong&gt; - At that scale, $79/seat might be cheaper than a $99 base fee&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extremely high volume, tiny team&lt;/strong&gt; - 100,000 tickets handled by 5 people&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need specific enterprise features&lt;/strong&gt; - SSO, advanced workflows only available in legacy vendors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But honestly? Scenario 1 and 2 are pretty rare. Most companies have more people who &lt;em&gt;should&lt;/em&gt; have support access than currently do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Operational Cost Iceberg
&lt;/h2&gt;

&lt;p&gt;Here's what most cost comparisons miss—the hidden overhead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 What you see:
                 ┌──────────────┐
                 │ Software bill │ ← $632/month
                 └──────────────┘
  ─────────────────────────────────────────
                 What you don't:
          ┌─────────────────────────┐
          │  Escalation delays      │ ← Waiting for access
          │  Context handoffs       │ ← Explaining issues
          │  Slack threads about    │ ← tickets
          │  tickets not in         │ ← the ticket system
          │  Knowledge silos        │ ← Engineers miss patterns
          │  Customer frustration   │ ← "Let me check with..."
          └─────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Studies show cross-functional tickets take 2-3x longer when access is restricted. If your average ticket costs $15 in labor and you add 30 minutes of coordination overhead, that's $7.50 per ticket in hidden costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Per-seat pricing charges for capacity, not usage. You pay the same whether someone handles 500 tickets or 5.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modern dev teams have 3-4x more people who need support access than traditional "agents"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The workarounds (shared logins, screenshot relay, human proxies) add operational overhead that doesn't show on invoices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI makes it worse—your per-seat costs stay flat while AI handles the easy tickets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Per-ticket pricing aligns with how dev tools &lt;em&gt;should&lt;/em&gt; work: pay for what you use, not who might use it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the math for your team. Count everyone who &lt;em&gt;should&lt;/em&gt; have access, not just who currently does.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://dispatchtickets.com/guides/customer-support-pricing-per-ticket-vs-per-seat/" rel="noopener noreferrer"&gt;Dispatch Tickets&lt;/a&gt;. We're building an API-first ticketing system with per-ticket pricing—unlimited users included. &lt;a href="https://dispatchtickets.com/early-access/" rel="noopener noreferrer"&gt;Check it out&lt;/a&gt; if the per-seat tax is hitting your team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>startup</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Why I Stopped Using Traditional Helpdesks (And Built Support Into My App Instead)</title>
      <dc:creator>Kal Wiggins</dc:creator>
      <pubDate>Tue, 13 Jan 2026 07:04:52 +0000</pubDate>
      <link>https://forem.com/kalwiggins/why-i-stopped-using-traditional-helpdesks-and-built-support-into-my-app-instead-4p7c</link>
      <guid>https://forem.com/kalwiggins/why-i-stopped-using-traditional-helpdesks-and-built-support-into-my-app-instead-4p7c</guid>
      <description>&lt;p&gt;Every helpdesk I've used follows the same pattern: it's a &lt;em&gt;separate app&lt;/em&gt;. Your users email &lt;a href="mailto:support@company.com"&gt;support@company.com&lt;/a&gt;, tickets land in Some Other Dashboard™, and your team context-switches between your product and your support tool all day.&lt;/p&gt;

&lt;p&gt;It works. But it's not great.&lt;/p&gt;

&lt;p&gt;What if support tickets were just... an API primitive? Like Stripe for payments or Twilio for SMS, but for support tickets?&lt;/p&gt;

&lt;h2&gt;
  
  
  The "We Have An API" Lie
&lt;/h2&gt;

&lt;p&gt;Most helpdesks claim to have APIs. They do—technically. But there's a difference between "we bolted an API onto our app" and "the API &lt;em&gt;is&lt;/em&gt; the product."&lt;/p&gt;

&lt;p&gt;Here's how you can tell the difference:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bolted-on API:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API is read-heavy (pull tickets into your system)&lt;/li&gt;
&lt;li&gt;Webhooks are an afterthought&lt;/li&gt;
&lt;li&gt;You still need their UI for most workflows&lt;/li&gt;
&lt;li&gt;Authentication assumes you're the only consumer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;API-first:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API is the primary interface&lt;/li&gt;
&lt;li&gt;Webhooks are first-class citizens&lt;/li&gt;
&lt;li&gt;Their UI is just a client consuming the same API you do&lt;/li&gt;
&lt;li&gt;Multi-tenant by design&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What This Looks Like in Practice
&lt;/h2&gt;

&lt;p&gt;With an API-first ticketing system, creating a ticket is just a POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.dispatchtickets.com/v1/workspaces/ws_xxx/tickets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer your_api_key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "subject": "Button not working on checkout page",
    "description": "User clicked Pay and nothing happened",
    "customer_email": "user@example.com",
    "priority": "high",
    "custom_fields": {
      "user_id": "usr_12345",
      "page_url": "/checkout",
      "browser": "Chrome 120",
      "error_log": "TypeError: undefined is not a function"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See that &lt;code&gt;custom_fields&lt;/code&gt; object? It takes &lt;em&gt;any&lt;/em&gt; JSON. No predefined schema. No "please contact sales to add custom fields." Just pass whatever context is relevant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cool Stuff This Enables
&lt;/h2&gt;

&lt;p&gt;Once tickets are an API primitive, you can do things that traditional helpdesks make painful:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Automatic Ticket Creation from Errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In your error boundary or catch block&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/support/tickets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`JS Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No stack trace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;custom_fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getCurrentUserId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your support team sees the ticket &lt;em&gt;before&lt;/em&gt; the user complains.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. In-App Support That Actually Has Context
&lt;/h3&gt;

&lt;p&gt;Instead of "please describe your issue," you can pre-fill everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SupportButton&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openSupport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;openTicketModal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;prefill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;customer_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;custom_fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;recent_actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activityLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openSupport&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Get Help&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more "what's your account email?" No more "can you send a screenshot?" The context is already there.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Build Support Into Your Admin Dashboard
&lt;/h3&gt;

&lt;p&gt;Why make your team learn another app?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In your existing admin panel&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CustomerDetail&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tickets&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tickets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchTickets&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CustomerInfo&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OrderHistory&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SupportTickets&lt;/span&gt; &lt;span class="na"&gt;tickets&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tickets&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Same dashboard */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your ops team sees customer info, orders, and support tickets in one place. No tab switching.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Webhooks for Everything
&lt;/h3&gt;

&lt;p&gt;When a ticket is created, updated, or resolved—you get a webhook. Build whatever you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Your webhook handler&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/webhooks/tickets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ticket.created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urgent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Page on-call engineer&lt;/span&gt;
    &lt;span class="nx"&gt;pagerDuty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;support-ticket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ticket.resolved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Update your CRM&lt;/span&gt;
    &lt;span class="nx"&gt;crm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer_email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;last_support_interaction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;tickets_resolved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Pricing Thing
&lt;/h2&gt;

&lt;p&gt;Traditional helpdesks charge per seat. Five agents? Five seats. But here's the thing—in a modern SaaS, &lt;em&gt;everyone&lt;/em&gt; touches support sometimes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers triage bugs&lt;/li&gt;
&lt;li&gt;PMs review feature requests&lt;/li&gt;
&lt;li&gt;Founders reply to key accounts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Per-seat pricing punishes this. You either pay $79/month for someone who handles 3 tickets, or you create workarounds (shared logins, forwarding emails, Slack threads about tickets).&lt;/p&gt;

&lt;p&gt;API-first systems tend toward usage-based pricing. Pay for tickets, not seats. Everyone can have access.&lt;/p&gt;

&lt;h2&gt;
  
  
  When &lt;em&gt;Not&lt;/em&gt; to Use API-First
&lt;/h2&gt;

&lt;p&gt;To be fair, API-first ticketing isn't for everyone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Non-technical teams&lt;/strong&gt;: If no one can write code, you need a full UI out of the box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple needs&lt;/strong&gt;: If email-only support with 1-2 agents covers you, a traditional helpdesk is fine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing investment&lt;/strong&gt;: If you've already built complex workflows in Zendesk, migration has a cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But if you're building a SaaS product and you have developers on the team? There's no reason your support system should be less flexible than everything else in your stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Traditional helpdesks are apps with APIs bolted on&lt;/li&gt;
&lt;li&gt;API-first ticketing means tickets are the primitive—build whatever you want&lt;/li&gt;
&lt;li&gt;You can embed support in your product, not around it&lt;/li&gt;
&lt;li&gt;Custom fields take any JSON (no schema limits)&lt;/li&gt;
&lt;li&gt;Webhooks let you integrate with everything&lt;/li&gt;
&lt;li&gt;Usage-based pricing means your whole team can have access&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://dispatchtickets.com" rel="noopener noreferrer"&gt;Dispatch Tickets&lt;/a&gt;—an API-first ticketing system designed for developers. If you're interested, we're doing &lt;a href="https://dispatchtickets.com/early-access/" rel="noopener noreferrer"&gt;early access&lt;/a&gt; right now.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>saas</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
