Skip to main content
Your backend performs the protocol steps. The customer clicks Connect to Photon, reviews access in Photon Dashboard, and returns to your product.

1. Create an installation request

Require a signed-in session in your product before starting. Generate a cryptographically random, expiring state and store it server-side with that session and customer account. Do not trust a customer ID supplied in an unverified callback. Sign a new JWT with your registered App private key: Use a maintained JWT library such as jose. Keep your server clock synchronized. Do not reuse assertions or sign the request using the webhook secret.
The response includes requestId, appId, state, and redirectUri. Check the echoed fields against the request, then redirect the browser to:
See Create installation request.

2. Let the customer approve access

Photon Dashboard handles Photon login and verifies that the user can manage App installations in the selected organization. This is separate from the login session in your own product. The customer reviews the requested permissions and chooses All projects or Only selected projects. All selected projects share the same approved project permissions. All projects includes projects created later; selected projects does not automatically include future projects. Customers can subsequently manage the installation under Integrations → Apps. See Permissions and lifecycle.

3. Validate the callback and redeem the code

On the registered HTTPS callback:
  1. Validate the browser session and compare state with the unexpired server-side value. Reject missing, mismatched, expired, or already-used state.
  2. Consume the state once. Do not let two callback requests redeem concurrently.
  3. Exchange code server-to-server with a new assertion, whose audience is the redemption endpoint.
A first successful delivery returns:
Persist the credentials securely before showing success. Associate the installation ID with your product’s customer account, and resolve/verify its Photon organization using the installation’s access token. Never send the client secret or access token to the browser.

A successful HTTP response may not contain credentials

If redemption times out, the operation may have succeeded even though you did not receive the secret. Do not loop until a new secret appears, replace another installation’s credentials, or mark the connection successful. Preserve a non-secret diagnostic reference and initiate recovery. A browser refresh of an old callback cannot safely repeat installation. See Redeem installation credential.

4. Obtain an installation access token

Send the installation credentials to the token endpoint configured for your Photon environment. This is the environment’s AuthKit OAuth token endpoint, not /v1/installation-requests/redeem and not the legacy Stable OAuth API. Obtain its exact URL from Photon when enabling App access; do not infer it from the Dashboard hostname or send credentials to a URL supplied by an end user.
Use a form encoder to construct the body. Use the response’s access_token as a bearer token:
This example requires organization:read. Cache tokens only until their expiry, keep them server-side, and handle authorization failures after an installation is paused, removed, or changes scope. Possessing an unexpired token does not override Photon authorization checks.

Store data per installation

Your persistent model should associate:
  • Your customer/account ID and the Photon installation ID.
  • The verified Photon organization ID.
  • Encrypted client credentials and connection status.
  • Event deduplication records and processing checkpoints.
App-level PEM and webhook signing secret are configured once per App/environment. Per-installation client credentials belong in storage, not a new .env file or a separate server for every customer.