Create the definition
In your developer organization, open Developer → Apps → New app. Use an account authorized to manage Apps in that organization.
The callback and webhook are different endpoints. The callback is a browser redirect with a short-lived installation code. The webhook receives HTTP POST deliveries when subscribed events occur, even when no user has your website open.
Use HTTPS URLs reachable by Photon. For local development, a tunnel can forward HTTPS traffic to your server. Keep the registered callback exactly aligned with the
redirectUri you send when starting installation, including its path and trailing slash.
Choose permissions and events together
Request only capabilities your product uses. Organization permissions apply at the organization level. Project permissions apply to the projects approved for an installation. For the local walkthrough, request:organization:read: resolve the installation’s organization through/v1/organizations/current.messages:read: receive message events.- Subscribe to
message.receivedand configure your event webhook URL.
project:write permission. If it lists organization projects, it needs organization:read_projects. Do not request billing or other unrelated access just to make installation work.
An event subscription is not a permission grant. Photon must also authorize delivery using the installation’s approved permissions and project scope. Changing a subscription does not bypass customer consent.
Save both App-level keys
After creation:- Record the App ID (
pho_app_…) and signing key ID. - Save the downloaded ES256 private key (
.pem) in your backend’s secret store. Keep its contents out of source control, browser code, recordings, and logs. - In Webhook signing secret, reveal and save the
whsec_…value for your backend’s webhook verifier.
kid. Use the Key ID displayed by Photon as the assertion JWT’s kid, together with the corresponding private key on your backend. This describes the Dashboard import flow; do not assume the imported JWK’s original kid is the registered value.