How enforcement works
- Store-bound — an app token is tied to the single store it was installed on. Salesive resolves the store server-side from the installation, so you never send a store id, and a token can never reach another store’s data.
- Scope-checked — each endpoint requires a specific scope. A request without the required
scope is rejected with
403. - Resource-limited — apps can reach only the resources listed below (orders, carts,
catalog, customers, wishlists, reviews, categories, shipping, discounts, blogs, notifications,
tasks, notes, metafields, scripts, comments, domains, roles, payouts, Shipday, KYC, files,
settings, billing, checkout extensions, workflow triggers, plus outbound email). Requests to any
other resource (wallet, staff, payments, themes, …) are rejected with
403, regardless of scope. - Rate-limited — outbound messaging scopes (
SEND_NOTIFICATIONS,SEND_EMAILS) are rate limited per installation; over-limit requests get429. See Outbound messaging. - Revoked on uninstall — deactivating the installation (uninstall) invalidates the app’s tokens immediately.
Read scopes (
READ_*) cover GET endpoints; write scopes (WRITE_*) cover create/update
endpoints and include their read counterpart’s endpoints where relevant. A few
irreversible owner-only actions (e.g. deleting an order or a customer record) are reserved
for the store owner and are not available to apps even with a write scope.Default grant — store & user context
Every installed app can call one endpoint without requesting any scope. It returns basic store and user info so your app can display the merchant’s store name, logo, and contact details on first load without needing a full permission grant:storeRole is "owner" if the
installing user owns the store, or "staff" if they are a staff member — useful for
conditionally showing admin-level controls in your app UI. No financial, payment, or
credential fields are included. See Store and user context for the full
response shape and every store and user field.
If you are using the App Starter, this endpoint is pre-wired at GET /api/context?shop=<id>
on your app’s own server and your frontend can call apiGet(\/context?shop=$`)` directly.
The app token is store-bound — the store comes from the installation, not from any
header or query you send. You cannot call this endpoint on behalf of a store you aren’t
installed on.
Available scopes
You request scopes as a space-separated list in thescope parameter, e.g.
READ_ORDERS WRITE_ORDERS READ_INVENTORY.
READ_CARTS gates the cart events themselves and has no fetch endpoint of its own.
READ_CART_CONTENTS gates GET /carts and GET /carts/:customerId on its own, and adds the
cart aggregate to cart events only when the app also holds READ_CARTS. READ_WISHLIST gates
both the wishlist reads and the wishlist events, so neither of those two is a webhook-only
scope.WRITE_DOMAINS and WRITE_DNS are runtime permissions, not OAuth scopes, so they are not
part of the install consent screen. See Runtime permissions. Role,
payout and custom-domain writes remain reserved for the store owner and are not available
to apps even with a read scope.What Salesive will grant
Not every name in the catalog is available to a marketplace app. At authorization, Salesive checks the requested list against two rules and stores only what passes. Grantable catalog. A marketplace app can hold only the scopes that map to an app-reachable endpoint, which is the list in the table above. A scope outside that list is dropped. MCP clients keep the wider catalog because their tokens are not scope-gated the same way. Customer data approval.READ_CUSTOMERS, WRITE_CUSTOMERS and READ_CUSTOMER_ANALYTICS are
granted only when your app is official or an admin has set customerDataApproved on it. Salesive
reviews customer data access separately because these scopes expose shopper PII. Until that review
happens the three scopes are dropped even if your app lists them. Once you hold them, you must also
handle data protection notices.
Every response that describes the consent screen says what was dropped and why:
requestedScopes is what the merchant will see and what the authorize step will store.
deniedScopes is the explanation to show in your own UI or logs. GET /oauth/authorize and
POST /api/v1/apps/marketplace/:slug/install-consent both return this shape. The token response’s
scope field is the final grant.
The gate is applied again when the authorization code is written, so a caller cannot widen the list
between the consent screen and the token exchange.
A non-grantable scope is reported with the reason
This permission is not available to marketplace apps. A customer data scope without approval reports the separate review reason.
Unknown names that are not in the catalog at all are dropped silently.Runtime permissions
Five capabilities are granted after install, from inside the app, rather than as OAuth scopes. The merchant approves each one in a dashboard modal and picks how long it lasts. A grant dies with the installation, so a reinstall starts clean.
Neither domain permission reaches the full DNS zone replace:
PUT /domains/:id/dns is refused for app
tokens. WRITE_DOMAINS is domain lifecycle only and does not grant any DNS write. Request them
through the App Bridge; see DNS records
for the DNS endpoints, protection rules and limits.
Files — externally-hosted only.
WRITE_FILES lets apps register images and videos whose
bytes are hosted on an external service (your CDN, S3 bucket, etc.) — only the URL is stored
in the gallery. Only image/* and video/* MIME types are accepted; size is recorded as
0 since no storage is consumed on Salesive’s servers. Apps may update or delete only files
they registered (files whose size is 0). Merchant-uploaded files (stored on Salesive’s file
service) must be managed from the store dashboard.Settings scope.
READ_SETTINGS / WRITE_SETTINGS cover the store’s preferences and
checkout behaviour: notification toggles (push, payment, order, shipping, sales, visitor),
allowOrderWithoutShipping, disableShipmentInStorefront, and posTaxRate. Store identity
fields (name, logo, business info, social media) are available without any scope via
GET /app/context and are writeable by humans only. Analytics, wallet, payment method, and
theme settings are not accessible to apps.The authoritative, always-current list is in the OAuth discovery document
(
scopes_supported) and via the Developer console scope picker, which only offers scopes
that map to a reachable endpoint.The catalog differs by store type. A store’s catalog lives at
/products (ecommerce),
/foods (restaurant menu), /services (business), or /digital-products (digital store),
all covered by the single READ_INVENTORY / WRITE_INVENTORY scope. Read store.type
(ecommerce, restaurant, business or digital) from GET /app/context to know which
one to call. /digital-products and /digital-access answer 403 on every store type
other than digital. See Digital stores.Outbound messaging (send notifications & emails)
Two scopes let your app reach out to people instead of just reading and writing store data. Because they generate messages, they are rate limited per installation and constrained to the store’s own audience — your app can never message an arbitrary address.Send a notification — SEND_NOTIFICATIONS
POST /notifications sends an in-app + push notification to the merchant (the store owner).
The recipient is fixed server-side; you cannot target another user.
429.
Send an email — SEND_EMAILS
POST /emails sends an email to one of three audiences. Recipients are resolved server-side
from the store’s own records, so you supply only the audience — never raw email addresses.
Limit: 10 send requests per hour per installation, each fanning out to at most 1,000
recipients. Subscriber unsubscribes are always honoured. Over the limit returns
429.
Email content is delivered through Salesive’s branded notification template (
subject,
title, message, optional actionText + actionUrl) — arbitrary HTML is not accepted.
Sending to customers and subscribers is done on the merchant’s behalf; respect their consent
and applicable anti-spam law.Requesting scopes
Include the scopes in the authorization redirect (see Install flow):scope field; read it to
confirm what you were granted, and read deniedScopes on the consent response to see what was
dropped and why.
Adding scopes later
If a future version of your app needs more access, add the new scopes to your app and send the merchant through the consent flow again to grant the additional permissions. Existing installs keep working with their originally granted scopes until they re-consent. Customer data scopes needcustomerDataApproved (or official status) before they can be granted, so ask for that review
before you send merchants back through consent.
Handling permission errors
A403 on an API call means one of:
- Missing scope — your token wasn’t granted the scope that endpoint requires. Request it at install and have the merchant re-consent.
- Out-of-scope resource — the endpoint belongs to a resource apps can’t access in this release.
Next steps
Build & publish your app
Register your app, configure its listing, and submit it for review.

