What changed

Private apps were a per-store credential you generated in the admin: an API key, a password and access to the Admin API. They were convenient and, because the credentials were long-lived and often over-scoped, a security liability.

Shopify replaced them with custom apps, which are created and installed from the admin but use the modern access-scope model and an Admin API access token. Same use case, better controls.

Which option you actually need

You want to…UseWhy
Connect one store to your own script, ERP or internal toolCustom app (Admin API access token)Single store, no distribution, created in the admin
Build something for many merchantsPublic app with OAuthPer-store install and token exchange, listable on the App Store
Read storefront data for a headless front endStorefront API access tokenPublic-safe, read-oriented, no admin privileges
Let a partner agency work on one storeCollaborator accountAccess with permissions and an audit trail, not an API key

Creating a custom app

  1. 01

    Enable custom app development

    In the Shopify admin, go to Settings → Apps and sales channels → Develop apps. A store owner has to allow custom app development once, per store.

  2. 02

    Create the app

    Choose "Create an app" and name it for the integration it serves — the ERP, the script, the internal dashboard. Vague names age badly.

  3. 03

    Configure Admin API scopes

    Select only the scopes the integration needs. If it reads orders, it does not need write access to products.

  4. 04

    Install and reveal the token

    Install the app on the store, then reveal the Admin API access token once. Store it in a secrets manager immediately — it isn't shown again.

Using the access token

Authenticate Admin API requests with the X-Shopify-Access-Token header. The token replaces the old key-and-password pair entirely.

Admin GraphQL API request
curl -X POST \
  "https://your-store.myshopify.com/admin/api/2025-07/graphql.json" \
  -H "X-Shopify-Access-Token: $SHOPIFY_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ shop { name myshopifyDomain } }"}'

Pin an API version explicitly and put a calendar reminder on version upgrades. Silent breakage from an unsupported version is one of the more annoying integration failures, because it happens on a date nobody is watching.

Scopes, rotation and keeping it safe

  • Never put an admin token in the storefront. Theme code, browser JavaScript and public repositories are all disqualified. Admin tokens belong on a server.
  • One app per integration. Shared credentials across three systems make rotation impossible without an outage.
  • Least privilege. Review the scope list when the integration changes, and remove what it stopped needing.
  • Rotate on staff change. When the developer or agency who held the token leaves, uninstall and reissue.
  • Handle rate limits. Respect throttling and back off; the Admin API will tell you when you're going too fast.
  • Document ownership. Each custom app should have a named internal owner and a note on what breaks if it's removed.

The modern setup takes about five minutes longer than the old private app did, and removes an entire category of credential risk. Worth the five minutes.