Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 161 additions & 27 deletions docs/apikeys.mdx
Original file line number Diff line number Diff line change
@@ -1,54 +1,188 @@
---
title: "API keys"
description: "How to authenticate with Trigger.dev so you can trigger tasks."
description: "Authenticate backend requests with environment-specific API keys and restrict additional keys to the access each integration needs."
---

### Authentication and your secret keys
**API keys authenticate backend requests to a specific Trigger.dev project and environment.** Each environment has a root key, and you can create additional named keys for separate services and integrations.

When you [trigger a task](/triggering) from your backend code, you need to set the `TRIGGER_SECRET_KEY` environment variable.
<Warning>
API keys grant access to your Trigger.dev environment. Store them in a secret manager or backend
environment variable, never commit them to source control, and never expose them in frontend code.
</Warning>

Each environment has its own secret key. You can find the value on the API keys page in the Trigger.dev dashboard:
## Root and additional keys

![How to find your secret key](/images/api-keys.png)
Each environment has two types of API key:

| Key type | Access | Secret visibility | Lifecycle |
| --- | --- | --- | --- |
| **Root key** | Full access to the environment | Available to copy from the dashboard | Regenerate it with a 24-hour grace period for the previous value |
| **Additional key** | Full or restricted access | Shown once when created, then stored as a hash and displayed only by its suffix | Set an optional expiration date or revoke it immediately |

Root keys use prefixes such as `tr_dev_`, `tr_stg_`, `tr_prod_`, and `tr_preview_`. Additional keys include `_sk_` after the environment, for example `tr_prod_sk_…`.

Use additional keys to give each backend service, deployment pipeline, or external integration its own credential. This lets you revoke one integration without rotating the environment's root key.

## Find your API keys

Open your project in the dashboard, select an environment, and open the **API keys** page.

API keys belong to one environment. A Development key cannot access Production, and a Production key cannot access Staging.

<Note>
For preview branches, you need to also set the `TRIGGER_PREVIEW_BRANCH` environment variable as
well. You can find the value on the API keys page when you're on the preview branch.
Every team member has their own Development environment and keys. Copy the Development key from
your own API keys page so local requests run against your machine.
</Note>

### Automatically Configuring the SDK
## Configure the SDK

To automatically configure the SDK with your secret key, you can set the `TRIGGER_SECRET_KEY` environment variable. The SDK will automatically use this value when calling API methods (like `trigger`).
Set `TRIGGER_SECRET_KEY` in your backend environment. The SDK reads it automatically for operations such as triggering tasks and retrieving runs.

```bash .env
TRIGGER_SECRET_KEY="tr_dev_…"
TRIGGER_PREVIEW_BRANCH="my-branch" # Only needed for preview branches
TRIGGER_SECRET_KEY="tr_prod_…"
```

Additional keys use the same environment variable:

```bash .env
TRIGGER_SECRET_KEY="tr_prod_sk_…"
```

To configure the SDK in code, pass the key to `configure`:

```ts Your backend code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'docs/apikeys.mdx' || true

echo "== surrounding lines =="
if [ -f docs/apikeys.mdx ]; then
  nl -ba docs/apikeys.mdx | sed -n '45,60p'
fi

echo "== all ts fenced markdown/code tags in docs apikeys =="
if [ -f docs/apikeys.mdx ]; then
  python3 - <<'PY'
from pathlib import Path
p=Path('docs/apikeys.mdx')
text=p.read_text()
for i,line in enumerate(text.splitlines(),1):
    x=line.strip()
    if x.startswith('```') and (x.startswith('```ts') or x.startswith('```typescript') or x.startswith('```js') or x.startswith('```typescript') or x.startswith('```bash')):
        print(f"{i}: {x}")
PY
fi

echo "== docs guidelines references =="
rg -n "language tag|typescript|ts" docs -g '*.md' -g '*.mdx' | head -100 || true

Repository: triggerdotdev/trigger.dev

Length of output: 262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and size =="
wc -l docs/apikeys.mdx

echo "== surrounding lines with wc/cut =="
cut -n -f45-60 docs/apikeys.mdx | sed -n '45,60p'
awk '{printf "%6d\t%s\n", NR, $0}' docs/apikeys.mdx | awk 'NR>=45 && NR<=60'

echo "== fence tags in docs/apikeys.mdx =="
awk '{if (/^```[A-Za-z0-9_-]*[[:space:]]?.*/) printf "%6d\t%s\n", NR, $0}' docs/apikeys.mdx

echo "== imports/other tags nearby context =="
rg -n "```(typescript|ts|javascript|js|bash)" docs/apikeys.mdx
awk '{if (/trigger\.dev\/sdk|```/) printf "%6d\t%s\n", NR, $0}' docs/apikeys.mdx

Repository: triggerdotdev/trigger.dev

Length of output: 1345


Use the required TypeScript fence tag.

Change line 53 from ts to typescript. MDX code examples must use language tags from GitHub’s known languages list.

Source: Coding guidelines

import { configure, tasks } from "@trigger.dev/sdk";

configure({
secretKey: process.env.TRIGGER_SECRET_KEY,
});

await tasks.trigger("send-email", {
to: "user@example.com",
});
```

You can do the same if you are self-hosting and need to change the default URL by using `TRIGGER_API_URL`.
If you self-host Trigger.dev, set `TRIGGER_API_URL` or pass `baseURL` to `configure`:

```bash .env
TRIGGER_SECRET_KEY="tr_prod_…"
TRIGGER_API_URL="https://trigger.example.com"
TRIGGER_PREVIEW_BRANCH="my-branch" # Only needed for preview branches
```

The default URL is `https://api.trigger.dev`.
The default API URL is `https://api.trigger.dev`.

### Manually Configuring the SDK
## Create an additional key

If you prefer to manually configure the SDK, you can call the `configure` method:
Create a separate key for each service or integration that accesses Trigger.dev.

```ts
import { configure } from "@trigger.dev/sdk";
import { myTask } from "./trigger/myTasks";
<Note>
Creating and revoking keys requires permission to manage API keys for the selected environment.
The dashboard disables these actions when your role does not have permission.
</Note>

configure({
secretKey: "tr_dev_1234", // WARNING: Never actually hardcode your secret key like this
previewBranch: "my-branch", // Only needed for preview branches
baseURL: "https://mytrigger.example.com", // Optional
});
<Steps titleSize="h3">
<Step title="Open the API keys page">
Select the project and environment the integration needs to access, then open **API keys**.
</Step>
<Step title="Create the key">
Click **New API key**, enter a descriptive name, and optionally set an expiration date. Names can
contain up to 64 characters.
</Step>
<Step title="Choose its access">
Select an access preset. For task-aware presets, choose all tasks or up to 10 task identifiers.
</Step>
<Step title="Copy and store the secret">
Copy the key into your secret manager or backend environment. Trigger.dev shows the complete
value only once.
</Step>
</Steps>

The dashboard displays the key's status, access, creator, creation time, and last-used time without storing or revealing its plaintext value.

## Access presets

Access presets define what an additional key can do. The dashboard shows which presets are available for your plan.

| Preset | Access |
| --- | --- |
| **Trigger only** | Trigger runs and batches for all or selected tasks. Trigger responses include scoped public access tokens for the runs and batches they create |
| **Task operator** | Trigger all or selected tasks and inspect or operate on their runs |
| **Environment observer** | Read runs, tasks, batches, logs, traces, and queues |
| **Environment operator** | Observe and operate on runs and queues, and trigger tasks |
| **Deploy only** | Deploy new versions, read deployment status, and read environment variables |
| **Environment variables only** | Read and write environment variables in this environment |
| **No restrictions** | Full access to the environment, matching the root key |

async function triggerTask() {
await myTask.trigger({ userId: "1234" }); // This will use the secret key and base URL you configured
}
**Trigger only** and **Task operator** can be restricted to selected tasks. Task restrictions use task identifiers, such as `send-email`, and continue to apply across deployments. A request involving multiple tasks succeeds only when the key can access every task in the request.

Access is fixed when you create a key. Changes to a preset do not alter existing keys. To change a key's access, revoke it and create a replacement.

<Warning>
Streamed batch ingestion is not atomic. When using a task-restricted key, earlier items may be
accepted before a later item fails validation or authorization.
</Warning>

## Expire and revoke additional keys

Set an expiration date when creating a key if the integration only needs temporary access. An expired key stops authenticating automatically.

Revoking a key takes effect immediately and cannot be reversed. Requests using the key fail, and the key can no longer create public access tokens. Create a replacement before revoking a key when you need to rotate it without interrupting the integration.

Removing a team member does not revoke additional keys they created. Review and revoke their keys separately when their access changes.

## Regenerate the root key

Regenerating the root key creates a new value immediately. The previous root key remains valid for 24 hours so you can update services without downtime, then stops authenticating.

Public access tokens signed with the previous root key remain valid until the earlier of their own expiration and the end of the 24-hour grace period. Additional-key revocation does not have a grace period.

## Create public access tokens

Additional keys can create scoped [Public Access Tokens](/realtime/auth) without receiving the environment's root key. Use `@trigger.dev/sdk` version 4.5.8 or later with additional keys.

When an additional key calls `auth.createPublicToken()`:

- The token must request at least one scope.
- Its scopes cannot exceed the additional key's access.
- It expires after 15 minutes by default.
- Its expiration cannot exceed 30 days.
- A numeric `expirationTime` is a Unix timestamp in seconds.

Revoking or expiring an additional key does not revoke tokens it already created. Those tokens remain valid until their own expiration, unless the environment's root key is regenerated first.

## Target Preview and Development branches

Preview and named Development branches use their parent environment's key set. Select the branch by setting `TRIGGER_PREVIEW_BRANCH` alongside the environment key:

```bash .env
TRIGGER_SECRET_KEY="tr_preview_…"
TRIGGER_PREVIEW_BRANCH="feature/new-checkout"
```

The SDK sends the branch automatically. When calling the API directly, send the same value in the `x-trigger-branch` header.

## Self-hosting

Self-hosted installations support multiple additional keys with **No restrictions**. The restricted access presets are available in Trigger.dev Cloud.

Keep your instance and SDK current before creating additional keys. Calling a public-token API with an additional key on a server that does not support server-minted tokens returns an upgrade error; use the root key until the server is upgraded.

## Security recommendations

- Create one additional key per service or integration instead of sharing the root key.
- Choose the narrowest access preset and task selection that supports the integration.
- Store keys in a secret manager and inject them as backend environment variables.
- Set expiration dates for temporary integrations and deployment credentials.
- Revoke keys when an integration or team member no longer needs access.
- Never put an API key in frontend code. Use scoped [Public Access Tokens](/realtime/auth) for client-side access.

## Next steps

<CardGroup cols={2}>
<Card title="Trigger tasks" icon="bolt" href="/triggering">
Trigger tasks from your backend with an environment API key.
</Card>
<Card title="Realtime authentication" icon="key" href="/realtime/auth">
Create scoped public tokens for frontend and realtime access.
</Card>
</CardGroup>