Trigger.dev public tokens: keep the Sume key server-side
Trigger.dev v4.6.2 hardened authorization for public tokens. Whatever token your browser holds, a Sume API key must never be one of them. Here is the split.

Keep the Sume API key on your server and give the browser only your own, narrowly scoped credentials. The Trigger.dev changelog lists v4.6.2 (Sep 16, 2026) with "Authorization hardening and cleaner chat agent trace spans", covering realtime payloads, public tokens and chat sessions. That is a reminder of the pattern, not a Sume feature: a public token is meant for the client, a Sume key is not.
What the changelog says
The v4.6.2 entry names three surfaces: realtime payloads, public tokens and chat sessions. The changelog line is all this post relies on; check the release notes for what exactly changed before you upgrade.
What Sume has instead of a public token
Sume has no per-end-user credential and no browser-safe key. The embed recipe puts it plainly: one Sume account, one server-side key, many of your customers. A Sume key spends your credits, so anyone holding it can run any Format you own up to your caps.
| Credential | Lives in | Safe in a browser? |
|---|---|---|
| Trigger.dev public token | Client, issued per use | Designed for it |
| Sume API key | Your server environment | No |
| Your own session cookie | Browser | Yes, it is yours |
Rules from the Sume docs
The Format embedding recipe lists the custody rules. They apply whether your background jobs run on Trigger.dev or anywhere else.
- Keep the key in server environment, never in client JavaScript, a mobile bundle or a
NEXT_PUBLIC_*variable. - Proxy the call, not the key. A pass-through endpoint that forwards the browser payload with your key attached is the same leak one hop later.
- Run your own authorization check. Sume authenticates you, not your customer.
- Rotate by creating a new key and retiring the old one, since scopes cannot be added to an existing key.
A server-side shape that works
Your endpoint accepts your customer's identifiers, builds the Sume request itself, and sets a spend cap and an idempotency key. The TypeScript SDK path from the recipe looks like this.
import { createSumeClient, subscribeFormatRun } from "@sume-com/sdk";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });
const run = await subscribeFormatRun({
client,
path: { handle: "acme", slug: "product-promo" },
idempotencyKey: `order-${order.id}`,
body: {
input: { product_url: order.productUrl },
generation_spend_cap_usd: 3,
},
});Where a task runner fits
If a Trigger.dev task calls Sume, the key is a secret in the task environment, like any other server code. Whatever the task reports back to the browser through a public token should be your own record ids and status, not Sume credentials or signed URLs. Prefer a webhook to polling for results in production, as the recipe advises.
Sources
Related posts
More in Developers
- Voice replication API audit checklist before you switch
Gemini 3.8 Flash TTS is GA with voice replication and 150+ voices. Before switching providers, audit these items against Sume's live catalog.
- Reuse TTS word timestamps as caption words, skip a second STT
You already know what the voice said and when. Feed the TTS word timings to the caption job as `words` so brand names are never misheard by speech-to-text.
- A "use step" function that submits a Sume job once
Put the Sume submit call inside one "use step" function and derive the Idempotency-Key from a stable run key, so a retried step returns the original job.
- Veo is US-region only: what EU teams call on Sume
A Sept 2026 listing says Veo runs only in us-central1, with no EU region documented. Sume has one video endpoint and its docs state no region.
Written by Sume