We're constantly trying to improve your support experience, and your feedback is extremely valuable to us.

Please take a moment to tell us about your experience today.
Sign up for future Help Center user research studies.

API credential rotation

For various reasons, API credentials should be changed regularly: employees leave, API credentials can be accidentally committed to version control, and wide-reaching security flaws can be discovered. While these situations pose security risks, in most cases you can address them without causing any downtime for your app by rotating your API credentials.

Step 1: Create a new secret key

To communicate securely with Shopify’s API, you need to generate a new shared secret. You can do this from your app's page in the Partner Dashboard.

Step 2: Configure webhooks

Webhooks are signed with your app's secret key to prevent forgeries. If your app uses webhooks, then configure it to accept both webhooks signed with the new secret key and webhooks signed with the old secret key until after you revoke the old secret.

Step 3: Configure OAuth

Access tokens requested from Shopify’s API using the new secret key will be secure. Configure your app to use only the new secret key for OAuth Authentication.

Step 4: Generate new refresh token

Many of the access tokens stored by your app will be associated with the old secret key. New access tokens must be requested from the Shopify API to work with the new secret key. You'll need a refresh token to generate these new access tokens. Create a refresh token from your app’s page in the Partner Dashboard. Refresh tokens automatically expire after one hour.

Step 5: Request new access tokens

Refresh each access token stored by your application by requesting new tokens that use your new secret key and the refresh token:

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

Include the following required parameters in your requests:

  • client_id: The API key for your app
  • client_secret: The new secret key for your app
  • refresh_token: The refresh token you created from your app's page in the Partner Dashboard
  • access_token: The access token you would like to refresh

Step 6: Revoke the old secret key

Now your app is using the new secret key to communicate with the Shopify API. The old secret key can now be revoked. Revoke it from your app's page in the Partner Dashboard. Remember that revoking any secret will also remove the access tokens associated with it.

If your app uses webhooks, then configure it to accept webhooks that are signed with the new secret key only.



The following example shows a basic implementation of access token rotation in the Ruby programming language:

require "rest_client"
require "json"

api_key = "public-api-key"
shared_secret = "newly-generated-shared-secret"
refresh_token = "token-generated-from-partners-dashboard"
access_token = "access-token-to-refresh"

post_data = {
  client_id: api_key,
  client_secret: shared_secret,
  refresh_token: refresh_token,
  access_token: access_token,

response = RestClient.post('https://{shop}.myshopify.com/admin/oauth/access_token.json', post_data)
access_token = JSON.parse(response.body)['access_token'] # abracadabra


The following example shows a basic implementation of access token rotation in the PHP programming language:

  $api_key = "public-api-key";
  $shared_secret = "newly-generated-shared-secret";
  $refresh_token = "refresh-token-from-partners-area";
  $access_token = "access-token-to-refresh";

  $post_data = array(
    "client_id" => $api_key,
    "client_secret" => $shared_secret,
    "refresh_token" => $refresh_token,
    "access_token" => $access_token,
  $data_string = json_encode($post_data);

  $headers = array(
    "Content-Type: application/json",
    "Accept: application/json",
    "Content-Length:" . strlen($data_string)

  $handler = curl_init('https://{shop}.myshopify.com/admin/oauth/access_token.json');
  curl_setopt($handler, CURLOPT_CUSTOMREQUEST, "POST");
  curl_setopt($handler, CURLOPT_POSTFIELDS, $data_string);
  curl_setopt($handler, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handler, CURLOPT_HTTPHEADER, $headers);

  $response = curl_exec($handler);

<?php echo($response) ?>
<!-- {"access_token": "abracadabra"} -->

Sign up for a Partner account to get started.

Sign up