A merchant installs your app with the OAuth 2.0 authorization-code grant. The result is an sq_agt_* token bound to that merchant and store, carrying exactly the scopes they consented to. Drive it against the Agent Gateway like any other key.

The flow

1

Send the merchant to the authorize URL

Redirect the logged-in merchant to the consent screen. scope is a space-delimited subset of your app’s approved version scopes; redirect_uri must match your app’s allowlist exactly.
The platform validates the client, the exact redirect_uri, and that every requested scope is within the approved version, then renders a consent screen showing each scope with your per-scope justification and a store picker.
2

Merchant consents

On approval the platform issues a one-time authorization code (5-minute expiry, single use) and redirects back to your redirect_uri:
Verify state matches what you sent before continuing.
3

Exchange the code for a token

From your backend, exchange the code for the token. The secret is verified in constant time; the body may be JSON or application/x-www-form-urlencoded.
The exchange creates the install, mints the sq_agt_* key, auto-registers your declared webhook topics, and fires app/installed. Store access_token — it is an offline token that does not expire on a timer (it lives until uninstall or rotation).
Run the token exchange server-to-server only. The client_secret and the resulting access_token must never touch a browser or the redirect URL.

Using the token

The install token is an ordinary service-account key — send it exactly like the Authentication page describes:
Pass X-Store-ID: <store_id> when the install spans multiple stores. Send an Idempotency-Key on every non-GET call. The token carries only the consented scopes — a call to a route needing a scope you were not granted returns 403 FORBIDDEN_SCOPE.
App tokens are strictly least-privilege: they get no super-scope behavior. A * or agent:admin scope carries no elevation for an app token on either the Agent Gateway or the commerce resource APIs — every request must match a scope the merchant explicitly consented to. This is enforced twice (at mint time and at authorization), so design for exact scopes.

Ask for the minimum, justify each scope

Request the fewest scopes your app needs. Every requested scope requires a non-empty justification on the version (see Versions & review) — the merchant reads it on the consent screen, and the review team rejects vague or over-broad requests. See Scopes for the full catalog.

Reinstall, uninstall, and scope changes

One live install exists per (app, merchant, store). Re-running the flow for an existing install re-consents it rather than creating a duplicate.

Next

Webhooks

React to installs and store events.

Versions & review

Get scopes approved.