Skip to content

Personal Access Tokens

Personal Access Tokens (PATs) let SDKs and automation scripts access the Inklet API as their owning user without interactive login. PATs have no independent scopes — they always carry the owning user's current resource permissions.

Base URL

The base URL for every endpoint on this page is https://dev.iminklet.com.

Overview

Use a PAT exactly like a regular access token, in the Authorization header:

Authorization: Bearer il_pat_...

Differences from regular access tokens:

  • PATs do not participate in X-Renewed-Token sliding renewal.
  • PATs cannot call PAT management endpoints (create, list, revoke); those endpoints require a regular user Access Token.
  • PAT permissions mirror the owning user's current permissions in real time — no Scope, Project, Workspace, or Service Account isolation is introduced.

Security Recommendations

Security

  • Never commit PATs to a Git repository, write them to logs or traces, or include them in URLs or query strings.
  • Store PATs in a Secret Manager or environment variable.
  • Set a reasonable expiry and rotate regularly; revoke immediately if a PAT is compromised.

PAT Model

{
  "id": "01912345-6789-7abc-def0-123456789abc",
  "name": "home automation",
  "prefix": "il_pat_abcdef",
  "lastFour": "wxyz",
  "createdAt": "2026-01-15T10:30:00Z",
  "lastUsedAt": "2026-07-01T08:00:00Z",
  "expiresAt": "2027-01-01T00:00:00Z",
  "revokedAt": null
}
Field Type Description
id UUID PAT database primary key
name string Name assigned to this token (max 100 characters)
prefix string Token prefix (il_pat_ plus the next 6 characters), for identification
lastFour string Last four characters of the token, for identification
createdAt timestamp Creation time
lastUsedAt timestamp or null Last used time (best-effort, updated at most once per 5 minutes)
expiresAt timestamp or null Expiry time; null means no expiry
revokedAt timestamp or null Revocation time; null means active

Secure Storage

The server stores only a SHA-256 digest of the token. The plaintext credential is returned only in the create response. If lost, the token must be revoked and a new one created.

Endpoints


POST /api/personal-access-tokens

Requires a regular user Access Token

Create a new personal access token.

Request Headers:

Authorization: Bearer {accessToken}

Request Body:

{
  "name": "home automation",
  "expiresAt": "2027-01-01T00:00:00Z"
}
Field Type Required Description
name string Yes Token name, 1–100 characters
expiresAt string (RFC 3339) No Expiry time; must be in the future. Omit for no expiry.

Response: 201 Created

{
  "id": "01912345-6789-7abc-def0-123456789abc",
  "name": "home automation",
  "prefix": "il_pat_abcdef",
  "lastFour": "wxyz",
  "createdAt": "2026-01-15T10:30:00Z",
  "lastUsedAt": null,
  "expiresAt": "2027-01-01T00:00:00Z",
  "revokedAt": null,
  "token": "il_pat_abcdefghijklmnopqrstuvwxyz0123456789ab"
}

Token Is Shown Only Once

The token field contains the full plaintext credential and is returned only in this create response. Save it securely immediately. List responses never include the plaintext token — if lost, revoke the PAT and create a new one.

Errors:

Code Cause
400 name is empty or exceeds 100 characters, or expiresAt is not in the future
401 Missing or invalid access token
403 Caller is itself a PAT (PATs cannot manage PATs)

GET /api/personal-access-tokens

Requires a regular user Access Token

List all personal access tokens belonging to the authenticated user.

Request Headers:

Authorization: Bearer {accessToken}

Response: 200 OK

[
  {
    "id": "01912345-6789-7abc-def0-123456789abc",
    "name": "home automation",
    "prefix": "il_pat_abcdef",
    "lastFour": "wxyz",
    "createdAt": "2026-01-15T10:30:00Z",
    "lastUsedAt": "2026-07-01T08:00:00Z",
    "expiresAt": "2027-01-01T00:00:00Z",
    "revokedAt": null
  },
  {
    "id": "01912345-6789-7abc-def0-000000000002",
    "name": "ci pipeline",
    "prefix": "il_pat_ghijkl",
    "lastFour": "1234",
    "createdAt": "2026-03-10T09:00:00Z",
    "lastUsedAt": null,
    "expiresAt": null,
    "revokedAt": "2026-06-01T12:00:00Z"
  }
]

List responses do not include a token field — only the name, prefix, last four characters, creation time, last used time, expiry, and revocation status are exposed.

Errors:

Code Cause
401 Missing or invalid access token
403 Caller is itself a PAT (PATs cannot manage PATs)

DELETE /api/personal-access-tokens/{id}

Requires a regular user Access Token

Revoke a personal access token by its ID. Revocation takes effect immediately — any subsequent request using that token returns 401. Revoking an already-revoked token is idempotent.

Path Parameters:

Parameter Description
id UUID of the PAT to revoke

Request Headers:

Authorization: Bearer {accessToken}

Response: 204 No Content

Successful revocation; response has no body.

Errors:

Code Cause
400 id is not a valid UUID
401 Missing or invalid access token
403 Caller is itself a PAT (PATs cannot manage PATs)

Error Behavior

All of the following conditions return 401 Unauthorized without disclosing the specific reason:

  • PAT is expired
  • PAT has been revoked
  • Token format is invalid or hash does not match
  • Owning user has been deleted or deactivated

PATs do not emit an X-Renewed-Token response header; that mechanism applies only to JWT access tokens.

Examples

Create a PAT (using a regular Access Token)

curl -X POST https://dev.iminklet.com/api/personal-access-tokens \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"home automation","expiresAt":"2027-01-01T00:00:00Z"}'

Use a PAT to list devices

curl https://dev.iminklet.com/api/devices \
  -H "Authorization: Bearer $INKLET_PAT"

Revoke a PAT

curl -X DELETE "https://dev.iminklet.com/api/personal-access-tokens/$PAT_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"