Agent Tokens
Long-lived, scoped tokens for scripts, automation, and AI agents acting on your behalf. A separate token type from your account JWT.
When to Use One
Use an agent token whenever something other than the official BoxOwl app or browser extension needs to talk to your vault on your behalf:
- A personal script that reads your saved addresses and prints shipping labels.
- An AI assistant you'd like to delegate read-only access to your work history.
- A custom integration on a self-hosted tool that writes new vault entries.
Agent tokens are scoped — you can issue a read-only token to a third party without granting write access. They are also revocable: revoke one without touching your account password, MFA, or other tokens.
The Android app and browser extension don't use agent tokens; they hold a regular user JWT obtained through login.
Token Format
Agent tokens are prefixed with bxusr_ and look like this:
bxusr_a1b2c3d4_xT8mPq5KwR9NhL2vYzD3sB6FjUcW1AeXgHnM
Anatomy:
bxusr_— fixed prefix that identifies this as a personal user token.a1b2c3d4— 8-hex-character public key ID. Logged everywhere, safe to share with support; uniquely identifies the token.xT8mPq...— 32-character secret. Treat like a password. The server only stores SHA-256 of the full token; the plaintext leaves the server exactly once at creation and is never retrievable afterward.
Pass the token on any API request via the standard bearer header:
Authorization: Bearer bxusr_a1b2c3d4_xT8mPq5KwR9NhL2vYzD3sB6FjUcW1AeXgHnM
Scopes
A token carries a set of scopes that limits what it can do. The current scope vocabulary:
| Scope | Grants |
|---|---|
vault:read | Read vault categories (identity, addresses, contacts, work history, etc.). Excludes E2EE categories (passwords, payment methods, secure notes) — those never leave your device. |
vault:write | Create, update, and delete vault entries (server-readable categories only). |
profile:read | Read your public profile, resume, and links data — the same projection an anonymous viewer would get. |
profile:write | Toggle public-page enablement and edit profile-only fields (handle, bio, pronouns, etc.). |
Scopes are additive — a token can hold any combination. A token with no scopes is rejected at creation; pick at least one.
Scopes are validated at every request. Calls outside the token's scope return 403 Forbidden (BOX-403-002) — the request never reaches the controller.
Create a Token
Easiest: Settings > API Tokens > Create Token in the Android app. Pick a name, choose scopes, optionally add a description (a freeform note about what this token is for), and tap Create. The full token is shown once on the resulting screen — copy it immediately.
Programmatically, the same endpoint is available to anyone authenticated as you:
POST /api/v1/user/api-tokens
curl -X POST https://api.boxowl.me/api/v1/user/api-tokens \
-H "Authorization: Bearer <your-user-jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Personal shipping-label script",
"scopes": ["vault:read"],
"description": "Reads addresses to fill in PDF shipping labels"
}'
Response 201 Created:
{
"token": {
"id": "uat_01h455vb4pex5vsknk084sn02q",
"keyId": "a1b2c3d4",
"name": "Personal shipping-label script",
"scopes": ["vault:read"],
"createdAt": "2026-05-26T10:00:00Z",
"lastUsedAt": null
},
"rawKey": "bxusr_a1b2c3d4_xT8mPq5KwR9NhL2vYzD3sB6FjUcW1AeXgHnM"
}
rawKey is the only time the plaintext leaves the server. Save it somewhere safe — a password manager or your environment file. There is no way to retrieve it later; you can only revoke and re-issue.
List Your Tokens
GET /api/v1/user/api-tokens
curl https://api.boxowl.me/api/v1/user/api-tokens \
-H "Authorization: Bearer <your-user-jwt>"
Returns every token you've issued. Each row carries the keyId, name, scopes, creation time, and lastUsedAt. The plaintext is never returned — only the key ID and metadata. Use this list to audit what's still active and decide what to revoke.
Revoke a Token
DELETE /api/v1/user/api-tokens/{keyId}
curl -X DELETE https://api.boxowl.me/api/v1/user/api-tokens/a1b2c3d4 \
-H "Authorization: Bearer <your-user-jwt>"
Revocation is immediate. The next request that presents the revoked token gets 401 Unauthorized (BOX-401-002). Other tokens — and your account JWT — are unaffected.
The token row stays in the database (revoked, not deleted) so audit logs remain interpretable. The hash and metadata persist; the token will never validate again.
Rate Limits
Agent tokens share the standard per-user rate-limit bucket — they don't get a separate quota. If you run a tight loop with one, expect a 429 Too Many Requests response and a Retry-After header. The bucket replenishes continuously; back off and retry.
For sustained higher-volume integrations (organisations, partner apps), use an organisation API key (bxorg_*) instead — those carry their own rate-limit bucket and per-key scopes.
Registration Tokens (Separate System)
BoxOwl is in private beta and account creation is gated by a single-use registration token. Registration tokens are a different system from agent tokens — they're for getting into BoxOwl, not for calling the API afterwards.
- Each minted per accepted waitlist entry. One token per invite — invite a user a second time and the previous pending token is revoked first.
- Plaintext is emailed exactly once. The server stores SHA-256 of the token only.
- Default expiry is 14 days. After expiry the user must be re-invited.
- Consumed on successful registration — the
used_atcolumn flips, the token never validates again.
If you've been invited and lost the email, ask whoever invited you to resend (admin-side action — there is no self-serve "resend registration token" endpoint, on purpose). Once you've registered you no longer need the token; create an agent token if you want programmatic access from there.
Security Recommendations
- Scope as narrowly as possible. A token that only needs to read addresses doesn't need
vault:write. Pick the minimum. - One token per integration. If a script and an AI agent both need access, give them separate tokens. Revoking either one then doesn't disrupt the other.
- Rotate periodically. Especially for tokens held by services you don't fully control. Create a new one, deploy, then revoke the old.
- Never commit to version control. Treat tokens like passwords — environment variables, secret managers, never
.git. - Audit your list regularly.
GET /api/v1/user/api-tokensand look atlastUsedAt— anything you don't recognise should be revoked immediately.