Create a personal access token

A personal access token is the credential your scripts use when you aren't around to log in. Mint one from the App's API explorer, scope it down, and copy the secret somewhere safe before you leave the page — you only see it once.

When you need a PAT

Anything else — manual work in a browser — uses your normal App session and doesn't need a PAT.

What to record before you leave the page

The mint flow shows you the secret once. After you navigate away, the App can list the token by name and scope, but the secret itself is unrecoverable. Three things to capture before that happens:

Name it after the job, not the person

The audit trail records who minted the PAT regardless of the name; the name's job is to tell future-you (or a teammate) what it does. Bad names: michael-token, test, ci. Good names: analytics-export-prod, etl-markers-acme-tenant, config-repo-sync.

When the name describes the job, rotation and least-privilege review become obvious. When the name describes the person, every token review turns into archaeology.

Set an expiry

A short-but-survivable expiry beats "never." Quarterly is the default the App ships; 30 days is the right setting for anything you're not sure about, since the rotation forces a check-in before something silently keeps working past its purpose. Long-running production integrations can run longer (six months, a year) with the rotation calendared.

Mint it scoped

The mint form lets you set scope at create time. Don't skip it — see Scope a token for the four axes, the worked examples, and the anti-patterns.

Mint it from a script

The App's mint flow is calling POST /oauth/pats. For bootstrap scripts or fresh-environment setup, call it directly with a user JWT in the Authorization header:

curl -X POST https://api.airbrx.ai/oauth/pats \
  -H "Authorization: Bearer $AIRBRX_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "etl-markers-acme",
    "expiresAt": "2026-12-02T10:00:00Z",
    "scopes": {
      "GET":    ["/tenants/acme.app.airbrx.com/**"],
      "POST":   ["/tenants/acme.app.airbrx.com/markers"],
      "PUT":    [],
      "DELETE": []
    }
  }'

The response wraps the PAT metadata with two fields that matter on creation:

{
  "id":        "<64-char hex storage id>",
  "name":      "etl-markers-acme",
  "pat":       "airbrx_pat_<64-char hex secret>",
  "expiresAt": "2026-12-02T10:00:00Z",
  "scopes":    { ... },
  "tenants":   ["acme.app.airbrx.com"],
  "accounts":  [ ... ],
  "stripped":  {}
}

pat is the one-time secret — same one-shot rule as the App. stripped is the set of permissions you asked for but couldn't grant; it should be empty. If it isn't, the API silently filtered scopes outside what your own JWT could grant — fix the request and re-mint rather than shipping a token that doesn't do what it says.

Verify the new PAT

Before wiring a fresh PAT into anything load-bearing, post it to the introspection endpoint and read back what it actually grants. Same scope cube the API will enforce on every call, surfaced before you commit it to a config file:

curl -X POST https://api.airbrx.ai/oauth/introspect \
  -H "Content-Type: application/json" \
  -d '{ "token": "airbrx_pat_<your-secret>" }'

Look for active: true, the exp you set, and scope / tenants / accounts matching what mint claimed. If any of those disagrees, fix it before anything else runs against the token. The introspection endpoint takes a raw PAT (the only place outside /oauth/token that does), so this is the cheapest way to validate without minting a throwaway JWT.

Rotation in practice

Rotation is two-step, not one. Mint the new PAT with the same scope but a new ID, deploy it alongside the old one, confirm the new one works, then revoke the old. This avoids the brief outage you'd otherwise get during the swap.

For systems where you can't run both keys side by side, the rotation window is small — the old token works until you revoke it, and the new token works the moment you mint it. Schedule the cutover during a maintenance window or before anyone's looking at the report.

If a PAT leaks

  1. Revoke it from the API explorer. Effective immediately; in-flight requests using it complete, new requests are rejected.
  2. Mint a replacement with the same scope and a new ID.
  3. Update the secret store and redeploy anything that used the old one.
  4. Audit recent activity attributed to the old PAT — the analytics audit endpoint lists every action it took.

Where to go next

Open the API explorer

Personal access tokens are minted from the same page that exercises every endpoint.

Open in the App