Delegate access tokens are an artifact for making requests from private or authenticated contexts, like a server.

If you create a custom storefront with the [Headless channel](/docs/storefronts/headless/getting-started/build-options#the-headless-channel), then Shopify creates public and private access tokens for you.

This guide familiarizes you with delegate access tokens and describes how to create a delegate access token using the GraphQL Admin API.

> Caution:
> Unlike public access tokens, private access tokens should be treated as secret and not used on the client-side. We recommend only requesting the scopes that your app needs, to reduce the security risk if the token leaks.


## How delegate access tokens work

A delegate access token is an OAuth access token with a subset of the total permissions of an app.

Delegate access tokens are based on a parent API access token. The parent access token is used to authenticate your request for a delegate access token.

You need only one delegate access token for a shop, unless you need to rotate the tokens or change the access scopes that are available to the token.


The following diagram illustrates the delegate access token flow based on the actions of you, your app, and Shopify:

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/apps/auth/delegate-access-tokens-fd77ac9f3199d67251b738ee3a7852503b28a4b5604e4fc6106db08caca64ede.png" class="lazyload" alt="Workflow of the delegate access token process" sizes="1px" width="auto" height="auto"></figure>

1. The developer creates an app and authenticates it to the GraphQL Admin API.

1. The app requests an access token for the shop from the Admin API. This is the parent token.

1. Shopify authenticates the app and issues the access token.

1. The app uses the access token to request a delegate access token.

1. Shopify validates the request and returns a delegate access token.

1. The delegate access token is used to make requests to the Admin or Storefront API.

### When should I create a delegate access token?

An example scenario is for Admin API requests when app architectures are split across multiple subsystems, with each one running on its own server. Delegate access tokens avoid sharing a single access token between all subsystems, and ensure that each subsystem has access to only the minimal scopes that it needs to function properly.

### When do delegate access tokens expire?

You can explicitly declare an [`expiresIn`](/docs/apps/build/authentication-authorization/access-tokens/use-delegate-tokens#api-descriptions) value for the delegate access token.

If you don't specify an expiry, then the token expires at the same time as its parent. If the parent token is an [offline access token](/docs/apps/build/authentication-authorization/access-tokens/offline-access-tokens), then it won't expire and neither will the delegate access token. Otherwise, you'll need to rotate the parent and delegate tokens.

## Limitations and considerations

The following limitations and considerations apply to delegate access tokens:

- An app can delegate only the same or fewer scopes than were granted to it when [asking for permission](/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant#ask-for-permission). You can't request extra scopes using the GraphQL Admin APIs. If a new scope is required, then the app must first be re-authorized with the new access scope by a user of the store.

- When an app is re-authorized with fewer access scopes, all delegate access tokens lose the access scopes that are no longer authorized.

- A delegate access token can't be used to create new delegate access tokens.

- A delegate access token can be used to make requests to any API objects or resources that don't require access scopes. This includes, for example, uninstalling the app from a store. Make sure that only trusted parties have access to a delegated access token.

## Requirements

- You're familiar with [API authentication](/docs/api/usage/authentication).

- You've [retrieved an access token](/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant#step-4-get-an-access-token) for the Admin API.

- You can [make an authenticated request](/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant#make-authenticated-requests) to the Admin API for a parent token, which you'll use to authenticate your request for delegate access token.

- You've reviewed the delegate access token overview, including the [limitations and considerations](/docs/apps/build/authentication-authorization/access-tokens/use-delegate-tokens#limitations-and-considerations).

## Step 1: Create a delegate access token

> Caution:
> Unlike public access tokens, private access tokens should be treated as secret and not used on the client-side. We recommend only requesting the scopes that your app needs, to reduce the security risk if the token leaks.


Request a token from the GraphQL Admin API.

The following example requests an access token with [`write_orders` permissions](/docs/api/usage/access-scopes#authenticated-access-scopes). It also sets an [`expiresIn` value](#api-descriptions).

<p>
<div class="react-stacked-code-block ThemeMode-dim" data-preset="stacked">
<script data-option="title" data-value="Example request for a delegate access token"></script>


<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>

<script data-option="filename" data-value="POST https://{shop}.myshopify.com/admin/api/{api_version}/graphql.json"></script>

<script type="text/plain" data-language="graphql">
RAW_MD_CONTENTmutation {
  delegateAccessTokenCreate(input: { delegateAccessScope: [
      "write_orders" ], expiresIn: 3600 }){
    delegateAccessToken {
      accessToken
    }
    shop {
      id
    }
    userErrors {
      field
      message
    }
  }
}
END_RAW_MD_CONTENT</script>

</div>
</p>

<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>

<script data-option="filename" data-value="Response"></script>
<script data-option="nocopy" data-value="true"></script>

<script type="text/plain" data-language="json" data-title="GraphQL">
RAW_MD_CONTENT{
  "data": {
    "delegateAccessTokenCreate": {
      "delegateAccessToken": {
        "accessToken": "shppa_12345678910"
      },
      "shop": {
        "id": "gid:\/\/shopify\/Shop\/1"
      },
      "userErrors": []
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 10,
      "actualQueryCost": 10,
      "throttleStatus": {
        "maximumAvailable": 1000.0,
        "currentlyAvailable": 990,
        "restoreRate": 50.0
      }
    }
  }
}
END_RAW_MD_CONTENT</script>

</div>
</p>


</div>
</p>


## Step 2 (Optional): Make server-side requests to the Storefront API



To query the Storefront API with a delegate access token:

1. Include the `Shopify-Storefront-Private-Token` header with the delegate access token.

In some cases, a request to the Storefront API isn't linked to buyer traffic, such as during a static site build, however when making server-side requests to the Storefront API as a result of buyer traffic, be sure to also:

2. Include the `Shopify-Storefront-Buyer-IP` (case-sensitive) header with the IP address of the buyer. This allows Shopify to accurately enforce IP-level bot and platform protection, to help your storefront manage traffic from a single user consuming a high level of capacity, such as a bot.

> Caution:
> Failure to include the `Shopify-Storefront-Buyer-IP` (case-sensitive) header, can result in sub-optimal user experiences, including throttled API requests, limited Bot Protection, and unauthenticated flows at checkout as Shopify will not be able to differentiate requests from different buyers.


### API descriptions

| GraphQL field | Required? | Description |
|---|---|---|
| `delegateAccessScope` | Yes | The list of scopes that will be delegated to the new access token. |
| `expiresIn` | No | The amount of time, in seconds, after which the delegate access token is no longer valid. <br></br>The requirements for this parameter depend on whether the parent access token is set to expire: <ul><li>If it is, then `expiresIn` must be set to a time before the parent token expires.</li><li>If it isn't, then `expiresIn` accepts any length of time.</li></ul>With no `expiresIn` provided, the token expires at the same time as the token that's used to create the delegate. If an `offline` token generates the delegate, then the delegate token doesn't expire. Learn more about the differences between [online](/docs/apps/build/authentication-authorization/access-tokens/online-access-tokens) and [offline](/docs/apps/build/authentication-authorization/access-tokens/offline-access-tokens) access tokens. |

## Next steps

- Learn about [rate limiting in the Storefront API](/docs/api/usage/rate-limits#storefront-api-rate-limits).