Documentation Index
Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt
Use this file to discover all available pages before exploring further.
App Lifecycle
Every app on LaunchMyStore moves through the same lifecycle: a merchant discovers it in the marketplace, installs it (granting OAuth scopes), uses it (your code runs in their store), occasionally updates it (new version + new scopes), and eventually uninstalls it. This page is a single reference for every event your app will receive at each stage and what your handlers should do.Lifecycle States
| State | App can call APIs? | Webhooks delivered? | Extensions render? |
|---|---|---|---|
| Listing only | No | No | No |
| Installed | Yes | Yes | Yes |
| Scope-update pending | Yes (old scopes) | Yes | Yes |
| Uninstalled | No (revoked) | Final app/uninstalled only | No |
1. Discovery & Install
Merchants discover apps in the marketplace and click Install. This kicks off the OAuth flow.OAuth flow (high level)
Install rejection — per-shop function caps
If your app declares one or more functions inapp.json and the merchant’s store already has the maximum number of active apps shipping that function type, both install paths reject the install with HTTP 409 Conflict:
- Direct merchant install:
POST /apps/:appId/install - OAuth code exchange:
POST /apps/oauth/tokenwithgrant_type=authorization_code
message field directly — it names the offending function type and the current cap so the merchant knows what to uninstall. See Functions › Active-Install Caps Per Shop for the per-type limits.
Re-issuing tokens for an already-active installation never triggers the cap check — only new activations are counted. A previously-uninstalled app that the merchant is re-installing also passes the check as long as the cap still has headroom.
app/installed webhook
Fired immediately after the merchant completes OAuth. Use this to:
- Provision merchant-side resources (DB row, default settings)
- Send a welcome email
- Sync initial data via the granted scopes
2. Active Use
Once installed, your app can:- Call any
/api/v1/*endpoint with the access token (subject to granted scopes) - Receive any webhook the merchant has subscribed (or that you registered at install time)
- Have its extensions rendered into storefronts, checkouts, and admin pages
- Have its functions executed during
verifyCartandaddClientOrderflows
Token refresh
Access tokens expire after 24 hours. Refresh tokens last 30 days. Always implement refresh:3. Scope Updates (Version Publish)
When you publish a new app version that requires additional scopes, every installation gets aapp/scopes_update event the next time it pulls the version.
app/scopes_update webhook
addedScopes is non-empty, the merchant must re-authorize before the new scopes are usable. Show them an in-app banner with a re-auth link:
/api/v1/orders will return 403 missing_scope: read_orders.
4. Subscription / Billing Events
If your app charges for use, Stripe events flow through to your webhooks too:| Topic | When |
|---|---|
app/subscription_created | Merchant accepts a paid plan |
app/subscription_updated | Plan changed, quantity changed |
app/subscription_cancelled | Merchant downgraded to free or cancelled |
app/payment_succeeded | Recurring charge cleared |
app/payment_failed | Recurring charge declined — usually 3 retries before cancellation |
app/usage_charge_created | Per-use charge applied (for usage-based billing) |
5. Uninstall
Merchants can uninstall an app at any time from their admin. When they do:- OAuth tokens are revoked immediately — your app cannot make any further API calls
- Extensions are unmounted — blocks/checkout/admin extensions stop rendering
app/uninstalledwebhook fires (this is the only webhook your app receives after uninstall)- Webhook subscriptions are cleared
app/uninstalled webhook
- Clean up merchant data (or schedule it — see GDPR below)
- Cancel any active subscriptions / usage charges
- Send an “we’d love your feedback” email
- Update internal analytics
6. GDPR Lifecycle Webhooks
Three additional webhooks satisfy GDPR / CCPA obligations. Subscribing to these is mandatory for any app published to the public marketplace.customers/data_request
Fires when a merchant or customer requests a data export.
customers/redact
Fires when a customer exercises their right to be forgotten, 48 hours after the merchant approves the request.
shop/redact
Fires 48 hours after an app is uninstalled (i.e. 48h after app/uninstalled).
Webhook Delivery Guarantees
- Signature: HMAC-SHA256 of the raw request body, signed with your
clientSecret, sent in theX-LMS-Hmac-Sha256header. Always verify before processing. - Retries: 3 attempts with exponential backoff (1m, 5m, 15m). After the 3rd failure, the event is dropped.
- Ordering: Best-effort, not guaranteed. Use
createdAtto sequence; use idempotency keys (e.g.installationId + topic + createdAt) to dedupe. - At-least-once: A successful response (2xx) acks the event. Missing the ack causes a retry — your handler must be idempotent.
Testing Webhooks Locally
Waiting for a real merchant install, order, or GDPR request just to verify a handler works is painful — and some events (likecustomers/redact) are nearly impossible to reproduce on demand. The lms webhook trigger CLI command generates a sample payload for any topic, signs it with your app’s clientSecret, and POSTs it to a local URL so you can exercise your handler end-to-end.
Install the CLI
The command ships with the LaunchMyStore CLI. If you haven’t set it up yet, see CLI Setup. Once configured, yourclientSecret is read from LMS_CLIENT_SECRET or .lmsrc.json, so most invocations need only the topic.
Common scenarios
Headers it sends
Each request mirrors what production webhook delivery sends, so the same verification code path runs in dev:| Header | Value |
|---|---|
Content-Type | application/json |
X-LMS-Topic | The topic you passed (e.g. orders/create) |
X-LMS-Webhook-Id | Random UUID — useful for dedupe testing |
X-LMS-Delivery-Attempt | 1 (bump manually if you want to test retry behavior) |
X-LMS-Hmac-SHA256 | Base64 HMAC-SHA256 of the raw body, signed with your clientSecret |
X-LMS-Hmac-SHA256 against the raw request body before doing anything else. See Webhook Verification for the exact comparison code.
Lifecycle Checklist
Before you publish your app to the marketplace, your handler must:Handle OAuth callback (`/oauth/callback`)
Exchange code for tokens, create your installation row, redirect merchant to your dashboard.
Handle `app/installed` webhook
Idempotent provisioning — running it twice should not duplicate data.
Related
- Authentication — OAuth flow code walkthrough
- App Versioning — what triggers
app/scopes_update - GDPR Reference — full payloads + retention windows
- Webhooks Overview — delivery guarantees + topic list