API Credentials
Autoheal has two kinds of non-browser credential. Both are Authorization: Bearer tokens — no token exchange, no OAuth dance — and both resolve your tenant, your identity and your permissions from the credential alone.
| Personal access token | Service account key | |
|---|---|---|
| Belongs to | you | the organization |
| Permissions | exactly your current roles | the service account's role |
| Created from | Settings → Platform → API Credentials → My tokens | Settings → Platform → API Credentials → Service accounts |
| Prefix | ahpat_ | ahsa_ |
Use a personal access token for ad-hoc work: your own scripts, your local CLI. Use a service account for automation: CI, scheduled jobs, config-as-code.
That distinction matters more than it looks. A personal access token deliberately carries your current access — lose a role and it stops working the same day. That is exactly what you want for a script you run yourself, and exactly what you do not want for the deploy pipeline: automation built on someone's personal token is only ever as durable as that person's access. A service account holds its own role, so it is not.
Your first call
Every credential answers GET /api/v1/whoami. Make that call first — if it works, your credential is good, your tenant is right, and you can see the roles you will be authorized against.
export AUTOHEAL_TOKEN='ahpat_...'
curl https://acme.autoheal.ai/api/v1/whoami \
-H "Authorization: Bearer $AUTOHEAL_TOKEN"
{
"actor_id": "sa_2f6a9c1e-4d3b-4a51-9f0e-8c2d1b7a5e42",
"actor_type": "service_account",
"actor_name": "deploy-bot",
"tenant_id": "8b1f...",
"roles": ["viewer"],
"key": { "id": "7Kd3mZq9Xb2A", "name": "ci", "last_four": "k29P", "expires_at": "2026-11-01T00:00:00Z" }
}
Your tenant is never a parameter — it is inferred from the credential, so there is nothing to get wrong and no way to reach another organization's data.
Which endpoints accept a credential
There is no separate API for automation. A credential authenticates the same endpoints the Autoheal web app calls — you can open your browser's network tab, copy a request path, and use it with a token.
Reachable with a credential:
/api/v1/labels · /api/v1/alerts · /api/v1/incidents · /api/v1/catalog · /api/v1/oncall · /api/v1/integrations · /api/v1/integrationTypes · /api/v1/agent-profile · /api/v1/agent-policies · /api/v1/status-pages · /api/v1/skills · /api/v1/auth-settings · /api/v1/rbac · /api/v1/whoami · /api/investigations · /api/chat · /api/custom-agents · /api/instructions/runbooks · /api/instructions/agentsmd
Two paths inside those prefixes are the exception and require a browser session: /api/v1/integrations/tools/call (an internal endpoint the investigation agent calls, not a supported API) and /api/v1/agent-profile/baseline (the platform-wide defaults, which are not yours to read or change).
Everything else requires a signed-in browser session. That includes organization administration, internal service endpoints, and — deliberately — credential management itself: you cannot mint or revoke a credential using a credential, which is what stops a leaked key from extending its own life or minting a more privileged sibling.
A path outside the list answers 401 with a JWT error rather than a credential error. That is the gateway saying "this path only accepts a browser session", not a problem with your token.
Personal access tokens
Settings → Platform → API Credentials → My tokens → New token. Your avatar menu has an API tokens shortcut to the same place. No permission is needed — the tab is yours whatever your role.
Pick a name you will recognise later and an expiry (30, 90, 180 or 365 days; 90 is the default). Choosing No expiry requires typing the token's own name — it should never be the accidental option.
The secret is shown exactly once. It is stored as a SHA-256 hash, so nobody — not support, not an administrator — can recover it. If you lose it, revoke it and create another.
Afterwards a token is identified by its name and last four characters. The list shows when each was created, when it expires, and when it was last used, so you can retire the ones nothing calls.
Revoking is immediate for you and takes effect everywhere within 60 seconds.
Your tokens are yours: no administrator can create one on your behalf or revoke one for you. An administrator can see that a token exists (name, owner, expiry, last use) through the organization-wide credential review, GET /api/v1/api-keys, but never its secret.
Service accounts
Settings → Platform → API Credentials → Service accounts. Requires the Admin role.
- Create the account. Name it after the automation, not the person:
deploy-bot,terraform,nightly-report. - Give it a role. A new account has none and can do nothing until you assign one. Pick the narrowest that works —
viewerfor anything read-only. - Mint a key. The secret appears once, exactly like a personal token.
Changing the role later takes effect on live keys within 60 seconds. There is no reissue: a key identifies the account, and the account's permissions are resolved on every request.
One account per automation
There are no per-key scopes, and that is deliberate. Least privilege is already expressible — create a separate service account with a narrower role — and that is the right granularity anyway, because it also gives each automation its own name in the audit trail and its own kill switch.
Limits, for the same reason: 25 service accounts per organization and 2 live keys per account. Two keys is a rotation overlap, not room to accumulate.
Rotation
Rotate rather than revoke-and-recreate when you are replacing a service-account key on a running system:
- A successor is issued immediately.
- The old key keeps working for a grace window (24 hours by default, 7 days at most).
- Callers pick up the new key whenever they restart — no coordinated cutover.
If you believe a key has leaked, rotate with no grace. The old key stops working at once.
Personal access tokens cannot be rotated: rotation hands the new secret to whoever asked for it, and only you may ever hold yours. Revoke the old token and create a replacement.
Revoke is for killing a key outright: callers break immediately, and it cannot be undone.
Disable the account when you want to stop everything it does but keep the option of turning it back on. Every key is rejected within 60 seconds and recovers on re-enable, with no reissue. Delete is the irreversible version — the account and all its keys go.
Expiry
Expiry is on by default: 90 days unless you choose otherwise, with a hard one-year ceiling.
Whoever created a credential is emailed 14 days, 3 days and 1 day before it expires, and again on the day it does. Service-account pages also show a banner from 14 days out.
Nothing expires silently, but nothing is renewed automatically either — rotate before the date or the calls start failing.
Attribution
Anything a credential does is attributed to it. An investigation started by a service account shows "deploy-bot (service account)" in its timeline, and you can filter investigation and chat lists by that actor. A personal access token's actions are attributed to you, because they are yours.
Every create, rotation, revocation and disable is recorded with who did it and when, on the service account's Audit tab. Failed authentication attempts against a real key are recorded too, so a credential being probed is visible.
Permissions
A credential can never do more than its actor's role allows. The full matrix is in Roles & Permissions; the credential-specific permissions are:
| Permission | Viewer | Responder | Admin |
|---|---|---|---|
| Manage your own personal access tokens | ✅ | ✅ | ✅ |
| View service accounts | — | — | ✅ |
| Create, rename, disable, delete service accounts and set their roles | — | — | ✅ |
| Create, rotate and revoke API keys; review all credentials | — | — | ✅ |
Managing your own tokens needs no permission at all: a token carries your access and nothing more, so creating one is not an escalation.
An administrator cannot give a service account a role they do not hold themselves.
Rate limits
| Limit | Value |
|---|---|
| Per credential | 60 requests / minute |
| Per organization | 600 requests / minute |
Exceeding either returns 429 with a Retry-After header. Back off for that many seconds and retry.
Errors
| Status | Meaning |
|---|---|
401 | The credential is missing, malformed, unknown, expired, revoked, belongs to a disabled service account, or belongs to a deactivated user. |
403 | The credential is valid but its role lacks the permission. The response names the permission you need. |
429 | Rate limited. See Retry-After. |
Every 401 returns the same body, on purpose: an attacker probing for valid credentials must not be able to tell "no such key" from "wrong secret" from "expired". If your own credential is failing and you cannot tell why, an administrator can see the reason in the credential audit trail — without ever seeing the secret.
Security
- Nothing is recoverable. Only
SHA-256(secret)is stored. A lost secret is replaced, not retrieved. - Revocation is bounded at 60 seconds. It is immediate on the server handling the request and propagates within a minute.
- Leaked keys are detectable. Both prefixes carry a checksum, so secret scanners can recognise a credential in a commit or a log.
- Never put a credential in a URL. Query parameters end up in browser history, proxy logs and referrer headers. Use the
Authorizationheader, over HTTPS only. - Store it in your CI's secret store, not in a repository, not in an environment file you commit.
- Review periodically.
GET /api/v1/api-keyslists every live credential in the organization — service-account keys and personal-token metadata alike — with its last use, which is the fastest way to find one nobody calls any more. Like all credential management it needs a signed-in admin session, not a credential.
Turning credentials off
Two switches, with different reach:
- API keys and service accounts (support-managed) is the master switch. With it off, nobody can manage credentials — but credentials that already exist keep working, so turning it off never strands automation mid-request. Revoke a credential to stop it.
- Personal access tokens (Settings → Org Preferences) is yours to flip. Turning it off blocks new personal tokens and rejects existing ones within 60 seconds. Service-account keys are unaffected.