Your app cannot read Shopify data without authenticating first. It must get permission from a user before gaining access to any of the resources in the REST API. This guide will walk you through the authorization process (described in greater detail by the OAuth 2.0 specification).


Before getting into the nitty-gritty of the authorization process, let’s go over some of the terms that we’ll be using for the rest of the guide.

  • Client
    Any application that would like access to a shop’s data. A user (usually the shop’s owner) must grant permission before the client can access any data.
  • API
    Shopify’s REST API. This is the place where the client can view and modify a shop’s data.
  • User
    A Shopify account holder, usually a shop owner. This is the person giving permission to a client to access their shop’s data through the REST API.

Step 1: Get the client's credentials

You will need to retrieve an API Key and Secret Key as the client uses them to identify itself during the authorization process.

To retrieve the credentials:

1. Open the Apps section of the Partner Dashboard.

2. Click the name of the app to view its details.

3. Click Get API Credentials and scroll down to App Credentials. The API key is displayed for you, and you can click Show next to API Secret Key to view the Secret key.

Step 2: Ask for permission

The first step of process is to get authorization from the user. This is done by displaying a prompt provided by Shopify:

Oauth app permissions

To show the prompt, redirect the user to this URL:


With these substitutions made:

  • {shop} - substitute this with the name of the user’s shop.
  • {api_key} - substitute this with the app’s API Key.
  • {scopes} - substitute this with a comma-separated list of scopes. For example, to write orders and read customers use scope=write_orders,read_customers.
  • {redirect_uri} - (Required) substitute this with the URL where you want to redirect the users after they authorize the client. The complete URL specified here must be identical to one of the Application Redirect URLs. Note: in older applications, this parameter was optional, and redirected to the Application Callback URL when no other value was specified.
  • {nonce} - a randomly selected value provided by your application, which is unique for each authorization request. During the OAuth callback phase, your application must check that this value matches the one you provided during authorization. This mechanism is important for the security of your application.
  • {option} - (Optional) substitute this with the value per-user if you would like to use the online access mode for API requests. Leave this parameter blank (or omit it) for offline access mode (default).

Step 3: Confirm installation

When the user clicks the Install button in the prompt, they will be redirected to the client server as specified above. One of the parameters passed in the confirmation redirect is the Authorization Code (the other parameters will be covered later in the guide).


Before you proceed, make sure your application performs the following security checks. If any of the checks fails, your application must reject the request with an error, and must not proceed further.

  • Ensure the provided nonce is the same one that your application provided to Shopify during the Step 2: Asking for permission.
  • Ensure the provided hmac is valid. The hmac is signed by Shopify as explained below, in the Verification section.
  • Ensure the provided hostname parameter is a valid hostname, ends with myshopify.com, and does not contain characters other than letters (a-z), numbers (0-9), dots, and hyphens.

If all security checks pass, the authorization code can be exchanged once for a permanent access token. The exchange is made with a request to the shop.

POST https://{shop}.myshopify.com/admin/oauth/access_token

With {shop} substituted for the name of the user’s shop and with the following parameters provided in the body of the request:

  • client_id
    The API Key for the app (see the credentials section of this guide).
  • client_secret
    The Secret Key for the app (see the credentials section of this guide).
  • code
    The authorization code provided in the redirect described above.

The server will respond with an access token when offline access mode is requested:

  "access_token": "f85632530bf277ec9ac6f649fc327f17",
  "scope": "write_orders,read_customers"

access_token is an API access token that can be used to access the shop’s data as long as the client is installed. Clients should store the token somewhere to make authenticated requests for a shop’s data.

scope is the list of access scope that were granted to the application and are associated with the access token. Due to the nature of OAuth, it's always possible for a merchant to change the requested scope in the URL during the authorize phase, so the application should ensure that all required scopes are granted before using the access token.

Alternatively, the server will respond with an access token with additional data when online access mode is requested:

  "access_token": "f85632530bf277ec9ac6f649fc327f17",
  "scope": "write_orders,read_customers",
  "expires_in": 86399,
  "associated_user_scope": "write_orders",
  "associated_user": {
    "id": 902541635,
    "first_name": "John",
    "last_name": "Smith",
    "email": "john@example.com",
    "account_owner": true

expires_in is the number of seconds until the access token expires.

associated_user_scope is the list of access scopes that were granted to the application and are available for this access token, given the user's permissions.

associated_user contains information about the user who went through the OAuth2 authorization flow.


The email field in this response should not be considered a reliable source for authenticating users, as Shopify does not guarantee the ownership of an email address when creating user accounts on a given store. We do guarantee that the id field is suitable to uniquely identify a single user.

Step 4: Making authenticated requests

Now that the client has obtained an API access token, it can make authenticated requests to the REST API. These requests are accompanied with a header X-Shopify-Access-Token: {access_token} where {access_token} is replaced with the permanent token.


Part of the authorization process requires specifying which parts of a shop’s data the client would like access to (see the “Getting permission” part of this guide). A client can ask for any of the following scopes:

API access modes

Shopify offers two types of access tokens: online access and offline access. It's important for application developers to understand the difference and the limitation of each.


It's possible for an application to use both access modes concurrently, using different access tokens when appropriate.

Online access

We refer to online access when the access token is linked to an individual user on a store, because the access token's lifespan matches the lifespan of the user's web session. This type of access token is meant to be used when a user is interacting with your application through the web, or when an application must respect an individual user's permission level.

  • This access mode must be explicitly requested in the authorization phase.
  • An API request made using an online mode access token is guaranteed to respect the user's individual permissions. Shopify returns a 403 Forbidden status code when the access token is valid but the user does not have access. Application developers should make sure to handle such a response gracefully.
  • An access token created with this access mode is temporary, and is guaranteed to expire after some amount of time.
  • After an access token has expired, Shopify will return a 401 Unauthorized response code.
  • Users can revoke their own access to your app at any time, without affecting the validity of other users' access tokens.
  • When the user logs out of their Shopify admin area, all online mode access tokens created during the course of the same web session are instantly revoked.
  • It's recommended to keep this type of access token in a user's temporary session storage, backed by a cookie in the user's browser, and make API requests using this access token in response to the user's requests.
  • If your application implements caching to avoid fetching data from Shopify too often, make sure to scope the cache to each individual user. Since online access mode is guaranteed to respect each user's permission level, caching API responses irrespective of which user's access token was used would most likely result in an inconsistent cache.
  • When this mode is requested and the application is not already installed in a store, the user installing the application must have access to all required scopes, or the installation will fail.
  • Once your app is installed, requesting this access mode will always return an access token restricted to the scopes available to the user. The application can inspect scope and associated_user_scope to determine if a user is lacking certain permissions.

Offline access

In contrast, the offline access mode is meant for long term access to the store, when no user interaction is involved. This kind of access token is ideal for background work in response to webhooks, or maintenance work in backgrounded jobs.

  • This is the default access mode when none is specified.
  • The access tokens created with this access mode are permanent; they are revoked only when the application is uninstalled from a store.
  • This access mode is suitable when no user interaction is involved.
  • Authorizing an application multiple times in this access mode will return the same access token each time. After obtaining offline access to a store, it is only necessary to re-authorize an application after it has been uninstalled, or when the application must request additional access scopes.
  • When this mode is requested and the application is not already installed in a store, the user installing the application must have access to all required scopes, or the installation will fail.
  • After the application is installed on a store, all users with Applications permission will be able to successfully complete this OAuth flow again, regardless of their permission level.

Delegating access to subsystems

Application developers may want to split their applications in multiple subsystems, each running on their own servers. With this type of architecture, a good practice is to avoid sharing a single access token between all the subsystems, and make sure each subsystem has access to only the minimal scopes it needs to function properly. It's better for security, but also makes access token rotation easier.

To create a new delegate access token, make an authenticated request to this endpoint:

POST https://{shop}.myshopify.com/admin/access_tokens/delegate

Provide the following parameters in the body of the request:

  • delegate_access_scope
    Required - The list of scopes that will be delegated to the new access token.
  • expires_in
    Optional - The amount of time, in seconds, after which the new access token is no longer be valid.

There are a few restrictions to take into account when creating a delegate access token:

  • An application can only delegate the same or fewer scopes than were granted to it when asking for permission. It's not possible to request extra scopes using this endpoint. If a new scope is required, the app must first be re-authorized with the new access scope by a user of the store.
  • When an application is re-authorized with fewer access scopes, all delegate access tokens will also lose the access scopes that are no longer authorized.
  • A delegate access token cannot be used to create new delegate access tokens.
  • Only an access token that never expires can be used to make authenticated requests to this endpoint.
  • A delegate access token can be used to make requests to any API endpoints that do not require access scopes. This includes, for example, uninstalling the application from a store. Make sure only trusted parties have access to a delegated access token.


Every request or redirect from Shopify to the client server includes an hmac parameter that can be used to ensure that it came from Shopify.

To verify that a request is valid, first parse the query string into a map of keys to values.

An example query string:


Is converted to this map:

  "code": "0907a61c0c8d55e99db179b68161bc00",
  "hmac": "4712bf92ffc2917d15a2f5a273e39f0116667419aa4b6ac0b3baaf26fa3c4d20",
  "shop": "some-shop.myshopify.com",
  "timestamp": "1337178173"


This query string is merely an example, and the request parameters provided by Shopify could be subject to change at sometime in the future. Please ensure that your verification strategy is not dependent on the exact parameters in the example above.

HMAC Validation

The hmac entry is removed from the map, leaving the remaining parameters:

  "code": "0907a61c0c8d55e99db179b68161bc00",
  "shop": "some-shop.myshopify.com",
  "timestamp": "1337178173"

The characters & and % are replaced with %26 and %25 respectively in keys and values. Additionally the = character is replaced with %3D in keys.

Each key is concatenated with its value, separated by an = character, to create a list of strings. The list of key-value pairs is sorted lexicographically, and concatenated together with & to create a single string:


Lastly, this string is processed through an HMAC-SHA256 using the Secret key as the key. The message is authentic if the generated hexdigest is equal to the value of the hmac parameter.

digest = OpenSSL::Digest.new('sha256')
secret = "hush"
message = "code=0907a61c0c8d55e99db179b68161bc00&shop=some-shop.myshopify.com&timestamp=1337178173"

digest = OpenSSL::HMAC.hexdigest(digest, secret, message)
ActiveSupport::SecurityUtils.secure_compare(digest, "4712bf92ffc2917d15a2f5a273e39f0116667419aa4b6ac0b3baaf26fa3c4d20")


The HMAC verification procedure for OAuth is different from the procedure for verifying webhooks. To learn more about HMAC verification for webhooks, see the documentation for Using Webhooks.