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

# Marketplace

> How merchants discover, install, and manage your app.

The OrderProtection App Marketplace is where merchants browse and install third-party apps. Once your public app is approved, it appears in the marketplace for all merchants to discover.

## How installation works

<Steps>
  <Step title="Merchant browses the marketplace">
    Merchants access the marketplace from their dashboard via **App Marketplace** in the left sidebar. They can search by name or filter by category.
  </Step>

  <Step title="Merchant reviews your app">
    Your app's detail page shows its name, description, logo, category, and the permissions it requests. Merchants can see which scopes are required and which are optional.
  </Step>

  <Step title="Merchant approves permissions">
    When the merchant clicks **Install**, a consent dialog shows all requested scopes. Required scopes are pre-selected and cannot be unchecked. The merchant can opt out of optional scopes.
  </Step>

  <Step title="Authorization code delivered">
    After the merchant confirms, OrderProtection creates an installation record and delivers an authorization code to the **first** redirect URI configured on your app — as a server-to-server `GET` (the merchant's browser never touches your domain):

    ```
    GET https://yourapp.example.com/callback?code=a1b2c3d4e5f6...&store_id=<store id>
    ```

    Your endpoint must respond `2xx` within 10 seconds, or the install fails and rolls back. No `state` parameter is sent and the request is unsigned — treat it as a hint and validate by exchanging the code (which requires your client secret). See [Installing Your App](/developer/installing-your-app#how-the-authorization-code-reaches-you) for the full contract.
  </Step>

  <Step title="Exchange code for tokens">
    Your server exchanges the authorization code for access and refresh tokens using the [token endpoint](/developer/authentication#2-exchange-code-for-tokens). You are now authorized to make API calls on behalf of that merchant's store.
  </Step>
</Steps>

## Handling reauthorization

When you update your app's requested scopes (e.g., adding a new permission), existing installations are flagged for reauthorization. Merchants will see a **Reauthorization required** badge on your app in their installed apps list.

When the merchant clicks **Reauthorize**, they review the updated scope list — with new scopes highlighted — and can approve or deny the changes. After reauthorization, a new authorization code is delivered to your redirect URI.

<Note>
  Your existing tokens continue to work with the original scopes until the merchant reauthorizes. Plan for a transition period where some installations may have the old scope set.
</Note>

## Handling uninstalls

When a merchant uninstalls your app:

1. All access and refresh tokens for that installation are immediately revoked
2. Any app webhooks registered for that store are deleted
3. The installation is marked as removed

Your app should handle `401 Unauthorized` responses gracefully — this typically means the merchant has uninstalled your app or revoked access.

## Private apps

Private apps are never listed in the public marketplace **Browse** tab. They're scoped to your **own account's stores** and go live via **Publish** rather than marketplace review (admin review only if they request admin-gated scopes — see [Creating an App](/developer/creating-an-app#private-apps)). This is ideal for:

* Internal tools for the stores you operate
* Custom integrations with specific partners
* Development and testing before going public

## Installing a private app

Private apps install from **App Marketplace → Private** on your own stores, or through the same API call below. There is no hosted `/oauth/authorize` page — consent happens in the dashboard or via the API.

<Note>
  The canonical install reference — including how to obtain the user token programmatically, both install paths, uninstalls, and every error — is [Installing Your App](/developer/installing-your-app). The short version follows.
</Note>

Installation is one authenticated call per store, made **as a dashboard user who has access to that store** (obtain the token via `POST /v1/auth/login` — see [Installing Your App](/developer/installing-your-app#step-1-obtain-a-user-token)):

```bash theme={null}
curl -X POST https://api.production.orderprotection.com/v1/oauth/authorize/approve \
  -H "Authorization: Bearer <your dashboard token>" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "op_app_...",
    "redirectUri": "https://yourapp.example.com/callback",
    "scopes": ["store:read", "partner-context:update", "..."],
    "storeId": "<store id>"
  }'
```

* `redirectUri` must **exactly match** a redirect URI registered on the app.
* `scopes` must include every scope the app marks as required (for most apps, that's all of them).
* The app must be published (and approved, if it requests admin-gated scopes) — an app still in review returns an error here.

The call **creates the installation** and returns a redirect URL containing a single-use authorization `code`. From here you have both flows available:

* **Authorization code**: exchange the `code` at [`POST /v1/oauth/token`](/developer/authentication#2-exchange-code-for-tokens).
* **Client credentials (server-to-server)**: you can ignore the code entirely — once the installation exists, [`POST /v1/oauth/token` with `grant_type: client_credentials`](/developer/authentication#client-credentials-flow) and the `store_id` works directly. This is the usual path for backend partner integrations.

To preview an app's details and scopes before approving, `POST /v1/oauth/authorize` with `{"clientId", "redirectUri"}` (same auth) returns the consent payload.


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