Beta access & desktop handshake
The Forven desktop app verifies beta access by calling the Forven entitlement API. This page describes how that handshake works, which is useful if you're integrating a custom build, debugging device links, or curious about what the app sends.
Overview
Linking uses an OAuth 2.0-style device-code flow. The desktop app
generates a short user code, the user approves it at /activate while
signed in, and a refresh token — an opaque bearer string that
authenticates a single installation — is handed back to the desktop.
The desktop stores the token in the OS keychain and calls
GET /api/entitlement periodically to refresh its access state.
Endpoints
POST /api/devices/code
Auth: none (public). Response:
{
"userCode": "FLPB-YMB9",
"deviceCode": "dc_…",
"expiresIn": 600,
"interval": 2
}
The desktop displays userCode to the user and polls
/api/devices/code/status with deviceCode.
GET /api/devices/code/status?deviceCode=<dc_…>
Auth: the deviceCode itself is the credential.
Response while pending: { "status": "pending" }.
Response after approval (one-time):
{
"status": "approved",
"deviceId": "uuid",
"refreshToken": "fv_…"
}
The token is returned exactly once, on the first poll after approval.
Subsequent polls return { "status": "consumed" }.
POST /api/devices/code/approve
Auth: web session cookie (Auth.js).
Body: { "userCode": "FLPB-YMB9", "deviceName": "Desktop" }.
Normally the /activate page server action calls the shared
approveDeviceCode helper directly; this endpoint exists for
desktop-adjacent tooling.
GET /api/entitlement
Auth: Authorization: Bearer <refreshToken>.
Response during beta:
{
"tier": "forged",
"status": "beta",
"currentPeriodEnd": null,
"deviceId": "uuid",
"offlineGraceHours": 72,
"checkedAt": "2026-04-21T15:30:00.000Z"
}
For compatibility with current desktop builds, beta access reports
tier: "forged" so the full product surface is unlocked. The status
field marks that the account is on beta access.
GET /api/devices
List your linked devices.
DELETE /api/devices?id=<uuid>
Revoke a device. The desktop will fail its next entitlement check and require the device to be linked again.
Offline grace period
The desktop caches the last successful /api/entitlement response to
disk. If it can't reach the server — bad Wi-Fi, travel, server outage —
it keeps honoring the cached tier for offlineGraceHours (72 hours by
default) past checkedAt.
This is a pragmatic tradeoff: users don't get locked out of their own research if we're down, and we don't need to ship a long-lived offline access file.
Security notes
- Refresh tokens are long random strings stored in the DB and compared directly. Rotate by revoking and re-linking.
- The token is the only credential needed to call
/api/entitlement; treat it like a password. - Web session cookies cannot be used to call
/api/entitlement; that endpoint accepts only bearer tokens. This keeps browser origins from being able to mint entitlement responses indirectly.