Add a View tickets link to your app

Add a View tickets link in your own app that opens a signed-in customer’s ticket list on your portal — right next to your Contact support link. Show it only when the customer actually has a ticket (open or closed), so people who’ve never contacted you don’t see an empty list. It reuses the same single sign-on handoff as Contact support, plus one quick server-side check.

How it works

Two pieces, both driven by your backend:

  1. Decide whether to show the link. Your backend asks Essential Support — with your workspace API key — whether this customer has any tickets, and shows the link only if they do.
  2. Open their tickets. When clicked, it hands the customer off with the same signed token as your Contact support link, but lands them on the ticket list (next=/) instead of the new-ticket form (next=/new).

These use two different credentials, both from Settings → Integrations: an API key for the ticket-count check, and your signing secret for the SSO handoff. Keep both server-side.

Step 1 — Check whether the customer has tickets

Server-side, call the read-back endpoint for this customer. Match them by email (or by externalId if you set one when linking accounts), and read total from the response. With no status filter, it counts every ticket — open and closed. Use limit=1; you only need the count, and total is the full number regardless of limit.

GET https://{slug}.essential.support/api/tickets?email={email}&limit=1
Authorization: Bearer <your API key>

→ { "total": 3, "tickets": [ … ] }     // show the link when total > 0
→ { "total": 0, "tickets": [] }         // no tickets (or unknown customer) → hide it

Do this on your server and return only a yes/no to your frontend — never put the API key in client code. And fail soft: if the check errors or times out, just hide the link. A missing View tickets link is harmless; Contact support is unaffected.

const API_KEY = process.env.ESSENTIAL_SUPPORT_API_KEY; // server-side only
const PORTAL_HOST = 'acme.essential.support';          // or support.yourcompany.com

// Your frontend calls this; it returns only a boolean — the key never leaves the server.
app.get('/support/has-tickets', requireLogin, async (req, res) => {
  try {
    const r = await fetch(
      `https://${PORTAL_HOST}/api/tickets?email=${encodeURIComponent(req.user.email)}&limit=1`,
      { headers: { Authorization: `Bearer ${API_KEY}` } }
    );
    if (!r.ok) return res.json({ hasTickets: false });   // fail soft → hide the link
    const { total } = await r.json();
    res.json({ hasTickets: total > 0 });
  } catch {
    res.json({ hasTickets: false });
  }
});

Step 2 — Open their tickets via SSO

The link itself is the same signed handoff as Contact support — mint a short-lived HS256 token with your signing secret and redirect to /sso — just with next=/ so it lands on the customer’s ticket list. (See Add a Contact support link for the full token contract and rules.)

import jwt from 'jsonwebtoken';
import { randomUUID } from 'node:crypto';

const SIGNING_SECRET = process.env.ESSENTIAL_SUPPORT_SECRET; // server-side only

// Same as your Contact support route, but next=/ lands on the ticket LIST.
app.get('/support/tickets', requireLogin, (req, res) => {
  const now = Math.floor(Date.now() / 1000);
  const token = jwt.sign(
    { sub: req.user.id, email: req.user.email, name: req.user.name,
      iat: now, exp: now + 120, jti: randomUUID() },
    SIGNING_SECRET,
    { algorithm: 'HS256' }
  );
  res.redirect(`https://${PORTAL_HOST}/sso?token=${encodeURIComponent(token)}&next=/`);
});

If you already have a single /support route for Contact support, you can reuse it and pass the destination through — e.g. /support?next=/ for the list, /support?next=/new for a fresh ticket. Just keep validating next as a relative path on your side; Essential Support also rejects absolute or protocol-relative values.

Put it together in your UI

Show Contact support always; render View tickets only when your check returns true:

<a href="/support">Contact support</a>

<!-- Render this one only when /support/has-tickets returned true -->
<a href="/support/tickets">View tickets</a>

Tips