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

# Embedded Apps

> Embed your app's UI directly inside the merchant dashboard with session tokens.

Embedded apps let you display your own UI inside the OrderProtection merchant dashboard. When a merchant opens your app, it loads in a secure iframe with a session token that provides user and store context — enabling single sign-on without requiring merchants to log in separately.

## Setting up an embedded app

To enable embedding, configure these settings when [creating](/developer/creating-an-app) or editing your app:

1. Enable **Embedded Mode**
2. Set your **App URL** — the page that will be loaded inside the iframe (e.g., `https://yourapp.example.com/embed`)

Your App URL must serve a web page that can run inside an iframe.

## Session token flow

When a merchant opens your embedded app, the following happens:

<Steps>
  <Step title="Merchant clicks your app">
    From their **Installed Apps** list, the merchant clicks the **Open** button on your app.
  </Step>

  <Step title="OrderProtection generates a session token">
    The dashboard calls the OrderProtection API to generate a short-lived JWT session token containing the current user's context.
  </Step>

  <Step title="Your app loads in an iframe">
    Your App URL is loaded in an iframe with the session token appended as a query parameter:

    ```
    https://yourapp.example.com/embed?session_token=eyJhbGciOiJIUzI1NiIs...
    ```
  </Step>

  <Step title="Your app extracts the token">
    Your frontend JavaScript extracts the `session_token` parameter from the URL:

    ```javascript theme={null}
    const params = new URLSearchParams(window.location.search);
    const sessionToken = params.get("session_token");
    ```
  </Step>

  <Step title="Your server verifies the token">
    Send the session token to the OrderProtection verification endpoint from your server:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.production.orderprotection.com/v1/oauth/session/verify \
        -H "Content-Type: application/json" \
        -d '{
          "session_token": "eyJhbGciOiJIUzI1NiIs..."
        }'
      ```

      ```javascript Node.js theme={null}
      const response = await fetch(
        "https://api.production.orderprotection.com/v1/oauth/session/verify",
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ session_token: sessionToken }),
        }
      );
      const context = await response.json();
      ```
    </CodeGroup>
  </Step>

  <Step title="Receive user context">
    The verification endpoint returns the merchant's identity and store context:

    ```json theme={null}
    {
      "userId": "cmhdlc5we0001oin850tlbw7y",
      "email": "merchant@example.com",
      "firstName": "Jane",
      "lastName": "Smith",
      "storeId": "store_abc123",
      "installationId": "inst_xyz789",
      "applicationId": "app_def456",
      "clientId": "op_app_fc6767b5...",
      "scopes": ["read_orders", "read_claims", "read_store"]
    }
    ```
  </Step>

  <Step title="Establish your session">
    Use the verified context to create a session in your app. The merchant is now signed in — no separate login required.
  </Step>
</Steps>

## Verification response fields

| Field            | Description                                                  |
| ---------------- | ------------------------------------------------------------ |
| `userId`         | The OrderProtection user ID of the merchant viewing your app |
| `email`          | The merchant's email address                                 |
| `firstName`      | The merchant's first name                                    |
| `lastName`       | The merchant's last name                                     |
| `storeId`        | The ID of the store the merchant is currently viewing        |
| `installationId` | The ID of this app's installation on this store              |
| `applicationId`  | Your app's ID                                                |
| `clientId`       | Your app's client ID                                         |
| `scopes`         | Array of scopes the merchant granted to your app             |

## Security

### Token lifetime

Session tokens are valid for **60 seconds**. They are designed for a single use — extract the token, verify it immediately, and establish your own session. Do not store or reuse session tokens.

### Iframe sandboxing

The iframe that loads your app is sandboxed with the following permissions:

```
allow-scripts allow-forms allow-same-origin allow-popups
```

Your app **cannot** navigate the parent dashboard window (`allow-top-navigation` is not granted).

### Rate limiting

The session verification endpoint is rate-limited to **30 requests per minute** per IP address.

<Tip>
  Use the session token only for the initial handshake. After verification, create your own session (e.g., a cookie or JWT) so that subsequent page loads within the iframe don't require a new session token.
</Tip>

## Best practices

* **Verify server-side** — Always verify session tokens from your backend, never from client-side JavaScript alone. The verification endpoint validates the token signature and checks that the installation is still active.
* **Handle expiration** — If verification returns an error, the token may have expired. Display a message asking the merchant to reload the app.
* **Responsive design** — Your embedded page should be responsive, as the iframe adapts to the available dashboard space.
* **No popups for auth** — Since the merchant is already authenticated via the session token, avoid redirecting to login pages or showing auth prompts.
