Create a Token

Generate a personal access token with createPersonalAccessToken and capture its one-time Secret.


Use the createPersonalAccessToken mutation to generate a new personal access token (PAT) for the Blue API. The token is created against your own user account and is the credential you supply in the X-Bloo-Token-ID and X-Bloo-Token-Secret request headers. In the API a token is a PersonalAccessToken object.

The create response is the only place the plaintext Secret is ever returned — see Capture the Secret now below before you run this.

Request

The smallest call passes only a name. Select uid (the Token ID for your headers) and secret (the plaintext value, returned only here).

mutation CreateToken {
  createPersonalAccessToken(input: { name: "CI deploy bot" }) {
    id
    uid
    name
    secret
    createdAt
  }
}

To make a token auto-expire, pass an expiredAt timestamp:

mutation CreateExpiringToken {
  createPersonalAccessToken(
    input: { name: "Quarterly export job", expiredAt: "2026-12-31T23:59:59Z" }
  ) {
    uid
    name
    secret
    expiredAt
  }
}

This mutation requires an authenticated user session (Firebase/JWT login), so it needs only the X-Bloo-Company-ID header alongside your session token — not the X-Bloo-Token-* headers. See Permissions.

Parameters

CreatePersonalAccessTokenInput

ParameterTypeRequiredDescription
nameString!YesA label for the token, shown in your token list. Max 50 characters. Trimmed, HTML-escaped, and stripped of links and tags on save.
expiredAtDateTimeNoOptional expiry timestamp (ISO 8601). After this moment the token stops authenticating — auth rejects it and the request is treated as unauthenticated. Omit for a token that never expires.
scopesStringNoReserved — not yet enforced. The value is validated but is not stored or checked anywhere; it grants no scope-limiting today. Every token currently has the full access of its owning user. Do not rely on it to restrict a token.

Response

The mutation returns the created PersonalAccessToken. The secret field is populated only on this response.

{
  "data": {
    "createPersonalAccessToken": {
      "id": "clm4n8qwx000008l0g4oxdqn7",
      "uid": "clm4n8qwx000108l0h2pzeabc",
      "name": "CI deploy bot",
      "secret": "pat_clm4n8qwx000208l0k7rytxyz",
      "createdAt": "2026-05-29T14:02:11.000Z"
    }
  }
}

Returns

PersonalAccessToken fields relevant to this mutation:

FieldTypeDescription
idID!Internal record ID of the token. Use this with deletePersonalAccessToken to revoke it. Not a header value.
uidString!The unprefixed Token ID. Send this as the X-Bloo-Token-ID header.
nameString!The sanitized label you supplied.
secretStringThe pat_-prefixed plaintext Secret. Send this as the X-Bloo-Token-Secret header. Non-null only on this create response — every other read returns null.
scopesStringAlways null in practice (the input value is not persisted). Reserved.
expiredAtDateTimeThe expiry you set, or null if the token never expires.
lastUsedAtDateTimeLast-used timestamp for auditing. null on a freshly created token.
createdAtDateTime!When the token was created.
updatedAtDateTime!When the token was last modified.
userUser!The owning user — always you.
Capture the Secret now

The secret (pat_...) is shown exactly once, here. Blue stores only a bcrypt hash of it, so it is unrecoverable afterward — not even Blue can show it to you again. Copy it into your secret store immediately. If you lose it, revoke the token and create a new one. The List Tokens query always returns secret: null.

Mapping fields to headers

The two values you read here map directly to the request headers used by every authenticated API call:

Create response fieldRequest headerExample value
uidX-Bloo-Token-IDclm4n8qwx000108l0h2pzeabc
secretX-Bloo-Token-Secretpat_clm4n8qwx000208l0k7rytxyz

The pat_ prefix belongs to the Secret, not the Token ID. See Making Requests for a full authenticated request.

Errors

CodeWhen
FORBIDDENThe request is authenticating with a token (X-Bloo-Token-ID header present) instead of a user session. Token creation requires a session — see Permissions.
BAD_USER_INPUTname is missing, not a string, or exceeds 50 characters; or expiredAt is not a valid date.
UNAUTHENTICATEDNo valid session credential was supplied at all.

Permissions

Creating a token requires an authenticated user session — the Firebase/JWT login the app uses, not token auth. The resolver rejects the request with FORBIDDEN if it detects PAT headers (X-Bloo-Token-ID), so you cannot mint a new token using an existing token. Generate tokens from a logged-in session. The same guard applies to revoking a token.

Tokens are always owned by the calling user. A token grants that user’s full access; there is no scope narrowing today (see the scopes note above).

  • Personal Access Tokens — overview of the Token ID / Secret split and the X-Bloo-* headers.
  • List Tokens — page through and audit your tokens (secret is always null there).
  • Revoke a Token — delete a token by id; it stops authenticating immediately.
  • Authentication — the in-app flow for generating a token.
  • Making Requests — send an authenticated request with the Token ID and Secret.