Skip to content
ForgeCastDocs

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).

  1. The app picks its redirect (the deep link, or a tiny HTTP server on 127.0.0.1 at a random free port), and generates a random code_verifier (43–128 characters from A-Z a-z 0-9 - . _ ~) and a random state.
  2. It computes code_challenge = base64url(SHA-256(code_verifier)) and opens the person's system browser at the authorize page.
  3. The person signs in on the website (if needed) and clicks Authorize.
  4. The website redirects the browser to forgecast://auth/callback?code=...&state=... (or http://127.0.0.1:PORT/callback?...). The app checks state, and that this is the sign-in it started.
  5. The app sends the code and code_verifier to the token endpoint and receives tokens.
  6. 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.

GET/desktop/authorizeWeb page

Name

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).

POST/api/app/token
curl -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

POST/api/app/token
curl -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.

POST/api/app/revoke

OAuth errors

Token endpoint errors follow RFC 6749: HTTP 400 with { "error": "...", "error_description": "..." }.

errorMeaning
invalid_requestA parameter is missing or malformed
invalid_grantThe code or refresh token is wrong, expired, already used, or the session was revoked; or PKCE / redirect_uri didn't match
unsupported_grant_typegrant_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.

On this page