> ## Documentation Index
> Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Build a Photon App

> Register one App, let organizations install it, and connect your service to Photon APIs and events.

A Photon App lets your service receive events and call APIs on behalf of an organization that installs it. Register the App once; each customer installation has its own approved permissions, project access, and API credentials.

> [!NOTE]
>
> This guide describes the Beta App installation flow. Confirm that Apps and project access are enabled in your target environment before testing. Use the API, Dashboard, and token endpoint from the same environment. Use installation credentials to read the installation’s approved permissions and project scope through `GET /v1/installations/current`, as explained in [Project discovery](https://docs.photon.codes/docs/beta/apps/permissions.md#project-discovery).

## Who does what?

| Actor | Responsibility |
| - | - |
| App developer | Registers the App, declares permissions and events, and operates its backend. |
| Customer organization administrator | Installs the App, approves its permissions, and selects projects in Photon Dashboard. |
| Photon | Authenticates the administrator, records consent, issues installation credentials, enforces access, and delivers signed events. |
| Your App backend | Starts installation, handles callbacks, stores credentials, verifies webhooks, and calls Photon APIs. |

In Photon Dashboard, **Developer → Apps** manages Apps you build. **Integrations → Apps** manages Apps installed in the current organization. You may use the same organization for both roles during development; they are still separate operations.

Your backend can serve many customers. It does not need a separate deployment or `.env` file for each installation. Store each customer's installation record in your backend's persistent storage and associate it with the correct account in your own product.

## Two integration directions

```mermaid theme={null}
flowchart LR
    Channels["Messaging channels"] --> Photon["Photon: normalized events"]
    Photon -->|"Signed event webhook"| Backend["Your App backend"]
    Backend --> Product["Your product / database"]
    Backend -->|"Installation access token"| API["Photon API"]
    API --> Channels
```

The webhook receiver is an HTTPS endpoint **you operate**. It can be part of your existing backend; a separate relay service is not required. In the Convex prototype, the demo web server also hosts this backend and forwards verified events to Convex. That is one implementation of the generic flow.

## Three credentials with different jobs

| Credential | Scope | Used for | Where your App keeps it |
| - | - | - | - |
| App private key (`.pem`) and key ID | One registered App | Signing short-lived assertions when creating an installation request or redeeming its callback code | Backend secret store; Photon keeps the registered public key |
| Webhook signing secret (`whsec_…`) | One registered App, shared across its installations | Verifying events sent by Photon | Backend secret store; Photon also needs the secret to sign deliveries |
| Installation `clientId` and `clientSecret` | One installation in one customer organization | Obtaining an access token for Photon API calls | Encrypted backend storage keyed by installation ID and your customer identity |

A PEM file is a key file, not an installation access token. The webhook secret verifies incoming deliveries; it does not authenticate outgoing API calls. End users installing your App do not download keys or edit environment variables.

## Build the integration

1. [Register your App](https://docs.photon.codes/docs/beta/apps/register.md) and declare its capabilities.
2. [Implement installation](https://docs.photon.codes/docs/beta/apps/install.md) and save per-installation credentials.
3. [Receive events and call APIs](https://docs.photon.codes/docs/beta/apps/webhooks.md).
4. [Handle permissions and lifecycle changes](https://docs.photon.codes/docs/beta/apps/permissions.md).
5. Run the [local server walkthrough](https://docs.photon.codes/docs/beta/apps/quickstart.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.