Desktop app sign-in
Sign a person in to ForgeCast from a native app with OAuth 2.0 and PKCE. For scripts and servers, use an API key instead.
Native apps can't safely hold a client secret or use browser cookies, so ForgeCast uses the standard authorization-code flow with PKCE for native apps (RFC 8252, RFC 7636). Only building a script or a server? An API key is simpler.
How it works
The browser hands the result back through one of two redirects: the forgecast://auth/callback deep link (what the ForgeCast desktop app uses: Windows opens the app, or hands the link to the copy that's already running) or a loopback address (for scripts and other tools, as in the example below).
- The app picks its redirect (the deep link, or a tiny HTTP server on
127.0.0.1at a random free port), and generates a randomcode_verifier(43–128 characters fromA-Z a-z 0-9 - . _ ~) and a randomstate. - It computes
code_challenge = base64url(SHA-256(code_verifier))and opens the person's system browser at the authorize page. - The person signs in on the website (if needed) and clicks Authorize.
- The website redirects the browser to
forgecast://auth/callback?code=...&state=...(orhttp://127.0.0.1:PORT/callback?...). The app checksstate, and that this is the sign-in it started. - The app sends the
codeandcode_verifierto the token endpoint and receives tokens. - The app calls the API with the access token, and renews it with the refresh token.
1. Open the authorize page
A web page, opened in the system browser.
/desktop/authorizeWeb pageName
Type
If the person clicks Cancel, the browser is sent to your redirect_uri with error=access_denied and your state.
2. Exchange the code
Send it as application/x-www-form-urlencoded (JSON works too).
/api/app/tokencurl -s -X POST "$FORGECAST_URL/api/app/token" \
-d "grant_type=authorization_code" \
-d "code=THE_CODE" \
-d "code_verifier=THE_VERIFIER" \
--data-urlencode "redirect_uri=http://127.0.0.1:53682/callback"The code is valid for 60 seconds and works once: even a failed attempt (wrong verifier, wrong redirect_uri) uses it up. Replaying a code revokes the session it created.
3. Call the API
GET /api/v1/inventory HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...Access tokens last 15 minutes. The app isn't subject to the developer-API rate limit, and can do everything the signed-in person can except manage API keys.
4. Refresh
/api/app/tokencurl -s -X POST "$FORGECAST_URL/api/app/token" \
-d "grant_type=refresh_token" \
-d "refresh_token=THE_REFRESH_TOKEN"The answer has the same shape as the first one, with a new refresh token. Refresh tokens rotate: each works exactly once, so always store the newest one. If an old refresh token is ever presented again, ForgeCast assumes it was stolen and revokes the whole session (the person signs in again). A session also ends 90 days after sign-in, however often it's refreshed.
5. Sign out
Send token=<refresh token> to end the session. It always answers 200.
/api/app/revokeOAuth errors
Token endpoint errors follow RFC 6749: HTTP 400 with { "error": "...", "error_description": "..." }.
error | Meaning |
|---|---|
invalid_request | A parameter is missing or malformed |
invalid_grant | The code or refresh token is wrong, expired, already used, or the session was revoked; or PKCE / redirect_uri didn't match |
unsupported_grant_type | grant_type must be authorization_code or refresh_token |
temporarily_unavailable (429) | You're calling the token endpoint too often |
Complete example (Node.js)
A complete, minimal implementation of the flow with a loopback redirect, in about 60 lines.

