Skip to main content

OAuth 2.0 Authentication

LaunchMyStore uses OAuth 2.0 for secure app authentication. This allows merchants to grant your app specific permissions without sharing their credentials.

Two install paths

Depending on how the merchant reaches your app, one of two OAuth flows runs.

A. Managed install — the merchant clicks Install in our marketplace

The merchant sees the consent screen inside LaunchMyStore’s admin, approves the scopes, and we redirect them straight to your /auth endpoint with a pre-authorized code. You do not call /oauth/authorize in this flow — the consent already happened. See Install handoff (/auth) for the full contract: HMAC verification, exchange semantics, code samples in Node/Python/Ruby.

B. Re-authorization — your app needs a fresh grant later

When your app needs a fresh grant after install (lost tokens, expired refresh token, or a scope upgrade), redirect the merchant’s browser to the admin consent page:
The merchant logs in (if needed), reviews your app’s name, developer and requested scopes on the consent screen, and clicks Authorize. The browser is then redirected to your redirect_uri with: If the merchant clicks Cancel you receive redirect_uri?error=access_denied&state=<your nonce>.
The consent page is app.launchmystore.io/oauth/authorize (the admin UI). The API endpoint api.launchmystore.io/apps/oauth/authorize is merchant-JWT-authenticated JSON that the consent page calls internally — redirecting a browser directly to the API returns 401. A merchant reinstall also re-runs the managed /auth handoff and delivers a fresh code, so either path recovers a lost token; prefer the consent redirect for scope upgrades (no uninstall involved).

Available Scopes

Request only the scopes your app needs. Merchants see all requested scopes during installation.

Store Data

Orders & Customers

Inventory & Discounts

Metafields

Content & Files

Scopes marked reserved are declared in the OAuth catalog and can be requested by an app today, but the corresponding REST endpoints are not yet exposed under /api/v1/. Request them now if you want forward-compat; the API surface will land before the v1 freeze.

Shipping & Gift Cards

Billing, Analytics, Settings & Marketing

Email Templates

Authorization Request

The authorize endpoint is a merchant-authenticated JSON API — it is called by the LaunchMyStore admin (with the merchant’s JWT), not by your app, and it does not redirect the browser:
Your app receives the resulting code + state through the managed install handoff redirect to your /auth endpoint.

Parameters

On success it returns JSON: { status, state: "success", data: { code, state, redirectUri, app } }. The server-generated data.state must be echoed back on the token exchange. See Authorize for the full contract.

Token Exchange

After the merchant approves, they’re redirected to your redirect_uri with a code parameter. Exchange this for tokens:

Response

The token payload is wrapped in the standard platform envelope ({ status, state, message, data }) — read the fields from data:
data.scope is a space-delimited string (e.g. "read_products write_orders") — split on a space, not a comma. This is the merchant’s granted scopes; persist it as your authorization source (see below). token_type is returned lowercase (bearer).

Token Refresh

Access tokens expire after 24 hours. Use the refresh token to get a new access token:
Refresh tokens expire after 30 days. If a refresh token expires, the merchant must re-authorize your app.
Refresh tokens rotate. Each refresh returns a new refresh_token and invalidates the one you just used. Always persist the newest refresh_token from the response and discard the old one — reusing a spent refresh token returns 401.
An expired access token does not require re-authorization or reinstalling the app — just call the refresh endpoint with a still-valid refresh token to get a new one.

Making Authenticated Requests

Include the access token in the Authorization header:

Security Best Practices

Never store tokens in client-side code or version control. Use encrypted database columns or a secrets manager.
Always validate that the state parameter in the callback matches what you sent. This prevents CSRF attacks.
Implement automatic token refresh before making API calls. Check expires_in and refresh proactively.
Only request the permissions your app actually needs. Merchants are more likely to install apps with fewer permissions.