---
title: Admin
description: Contains functions for authenticating and interacting with the Admin API.
api_version: v1
source_url:
  html: 'https://shopify.dev/docs/api/shopify-app-remix/v1/authenticate/admin'
  md: 'https://shopify.dev/docs/api/shopify-app-remix/v1/authenticate/admin.md'
api_name: shopify-app-remix
---

# Admin

Contains functions for authenticating and interacting with the Admin API.

This function can handle requests for apps embedded in the Admin, Admin extensions, or non-embedded apps.

## authenticate.​admin(**[request](#authenticateadmin-propertydetail-request)**​)

Authenticates requests coming from the Shopify admin.

The shape of the returned object changes depending on the `isEmbeddedApp` config.

### Parameters

* **request**

  **Request**

  **required**

### Returns

* **Promise\<AdminContext\<Config, Resources>>**

### AdminContext

```ts
Config['isEmbeddedApp'] extends false
  ? NonEmbeddedAdminContext<Config, Resources>
  : EmbeddedAdminContext<Config, Resources>
```

### NonEmbeddedAdminContext

* admin

  Methods for interacting with the GraphQL / REST Admin APIs for the store that made the request.

  ```ts
  AdminApiContext<Resources>
  ```

* billing

  Billing methods for this store, based on the plans defined in the \`billing\` config option.

  ```ts
  BillingContext<Config>
  ```

* cors

  A function that ensures the CORS headers are set correctly for the response.

  ```ts
  EnsureCORSFunction
  ```

* session

  The session for the user who made the request. This comes from the session storage which \`shopifyApp\` uses to store sessions in your database of choice. Use this to get shop or user-specific data.

  ```ts
  Session
  ```

### AdminApiContext

Provides utilities that apps can use to make requests to the Admin API.

* graphql

  Methods for interacting with the Shopify Admin GraphQL API

  ```ts
  GraphQLClient
  ```

* rest

  Methods for interacting with the Shopify Admin REST API There are methods for interacting with individual REST resources. You can also make \`GET\`, \`POST\`, \`PUT\` and \`DELETE\` requests should the REST resources not meet your needs.

  ```ts
  RestClientWithResources<Resources>
  ```

### GraphQLClient

* query

  ```ts
  string
  ```

* options

  ```ts
  GraphQLQueryOptions
  ```

returns

```ts
Promise<Response>
```

### GraphQLQueryOptions

* apiVersion

  ```ts
  ApiVersion
  ```

* headers

  ```ts
  { [key: string]: any; }
  ```

* tries

  ```ts
  number
  ```

* variables

  ```ts
  QueryVariables
  ```

### QueryVariables

* \[key: string]

  ```ts
  any
  ```

### RestClientWithResources

```ts
RemixRestClient & {resources: Resources}
```

### RemixRestClient

* session

  ```ts
  Session
  ```

* get

  Performs a GET request on the given path.

  ```ts
  (params: GetRequestParams) => Promise<Response>
  ```

* post

  Performs a POST request on the given path.

  ```ts
  (params: PostRequestParams) => Promise<Response>
  ```

* put

  Performs a PUT request on the given path.

  ```ts
  (params: PostRequestParams) => Promise<Response>
  ```

* delete

  Performs a DELETE request on the given path.

  ```ts
  (params: GetRequestParams) => Promise<Response>
  ```

### BillingContext

Provides utilities that apps can use to request billing for the app using the Admin API.

* cancel

  Cancels an ongoing subscription, given its ID.

  ```ts
  (options: CancelBillingOptions) => Promise<AppSubscription>
  ```

* request

  Requests payment for the plan.

  ```ts
  (options: RequestBillingOptions<Config>) => Promise<never>
  ```

* require

  Checks if the shop has an active payment for any plan defined in the \`billing\` config option.

  ```ts
  (options: RequireBillingOptions<Config>) => Promise<BillingCheckResponseObject>
  ```

### CancelBillingOptions

* isTest

  ```ts
  boolean
  ```

* prorate

  Whether to prorate the cancellation.

  ```ts
  boolean
  ```

* subscriptionId

  The ID of the subscription to cancel.

  ```ts
  string
  ```

### RequestBillingOptions

* amount

  Amount to charge for this plan.

  ```ts
  number
  ```

* currencyCode

  Currency code for this plan.

  ```ts
  string
  ```

* interval

  Interval for this plan. Must be set to \`OneTime\`.

  ```ts
  BillingInterval.OneTime
  ```

* isTest

  Whether this is a test purchase.

  ```ts
  boolean
  ```

* lineItems

  The line items for this plan.

  ```ts
  ({ interval?: BillingInterval.Every30Days | BillingInterval.Annual; discount?: { durationLimitInIntervals?: number; value?: { amount?: number; percentage?: never; } | { amount?: never; percentage?: number; }; }; amount?: number; currencyCode?: string; } | { interval?: BillingInterval.Usage; amount?: number; terms?: string; currencyCode?: string; })[]
  ```

* plan

  The plan to request. Must be one of the values defined in the \`billing\` config option.

  ```ts
  keyof Config["billing"]
  ```

* replacementBehavior

  The replacement behavior to use for this plan.

  ```ts
  BillingReplacementBehavior
  ```

* returnUrl

  Override the return URL after the purchase is complete.

  ```ts
  string
  ```

* trialDays

  How many trial days to give before charging for this plan.

  ```ts
  number
  ```

### RequireBillingOptions

* isTest

  Whether to include charges that were created on test mode. Test shops and demo shops cannot be charged.

  ```ts
  boolean
  ```

* onFailure

  How to handle the request if the shop doesn't have an active payment for any plan.

  ```ts
  (error: any) => Promise<Response>
  ```

* plans

  The plans to check for. Must be one of the values defined in the \`billing\` config option.

  ```ts
  (keyof Config["billing"])[]
  ```

### EnsureCORSFunction



### EmbeddedAdminContext

* admin

  Methods for interacting with the GraphQL / REST Admin APIs for the store that made the request.

  ```ts
  AdminApiContext<Resources>
  ```

* billing

  Billing methods for this store, based on the plans defined in the \`billing\` config option.

  ```ts
  BillingContext<Config>
  ```

* cors

  A function that ensures the CORS headers are set correctly for the response.

  ```ts
  EnsureCORSFunction
  ```

* redirect

  A function that redirects the user to a new page, ensuring that the appropriate parameters are set for embedded apps. Returned only if \`isEmbeddedApp\` is \`true\`.

  ```ts
  RedirectFunction
  ```

* session

  The session for the user who made the request. This comes from the session storage which \`shopifyApp\` uses to store sessions in your database of choice. Use this to get shop or user-specific data.

  ```ts
  Session
  ```

* sessionToken

  The decoded and validated session token for the request. Returned only if \`isEmbeddedApp\` is \`true\`.

  ```ts
  JwtPayload
  ```

### RedirectFunction

* url

  ```ts
  string
  ```

* init

  ```ts
  RedirectInit
  ```

returns

```ts
TypedResponse<never>
```

### RedirectInit

```ts
number | (ResponseInit & {target?: RedirectTarget})
```

### RedirectTarget

```ts
'_self' | '_parent' | '_top'
```

Examples

### Examples

* ####

  ##### Description

  Use the \`cors\` helper to ensure your app can respond to requests from admin extensions.

  ##### /app/routes/admin/my-route.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";
  import { getMyAppData } from "~/db/model.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { session, cors } = await authenticate.admin(request);
    return cors(json(await getMyAppData({user: session.onlineAccessInfo!.id})));
  };
  ```

* ####

  ##### Description

  Use the \`redirect\` helper to safely redirect between pages.

  ##### /app/routes/admin/my-route.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { session, redirect } = await authenticate.admin(request);
    return redirect("/");
  };
  ```

* ####

  ##### Description

  Pass in a \`target\` option of \`\_top\` or \`\_parent\` to go to an external URL.

  ##### /app/routes/admin/my-route.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { session, redirect } = await authenticate.admin(request);
    return redirect("/", { target: '_parent' });
  };
  ```

* #### Using offline sessions

  ##### Description

  Get your app's shop-specific data using an offline session.

  ##### shopify.server.ts

  ```ts
  import { shopifyApp } from "@shopify/shopify-app-remix/server";

  const shopify = shopifyApp({
    // ...etc
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";
  import { getMyAppData } from "~/db/model.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { session } = await authenticate.admin(request);
    return json(await getMyAppData({shop: session.shop));
  };
  ```

* #### Using online sessions

  ##### Description

  Get your app's user-specific data using an online session.

  ##### shopify.server.ts

  ```ts
  import { shopifyApp } from "@shopify/shopify-app-remix/server";

  const shopify = shopifyApp({
    // ...etc
    useOnlineTokens: true,
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";
  import { getMyAppData } from "~/db/model.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { session } = await authenticate.admin(request);
    return json(await getMyAppData({user: session.onlineAccessInfo!.id}));
  };
  ```

* #### Using the decoded session token

  ##### Description

  Get user-specific data using the \`sessionToken\` object.

  ##### shopify.server.ts

  ```ts
  import { shopifyApp } from "@shopify/shopify-app-remix/server";

  const shopify = shopifyApp({
    // ...etc
    useOnlineTokens: true,
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";
  import { getMyAppData } from "~/db/model.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { sessionToken } = await authenticate.public.checkout(
      request
    );
    return json(await getMyAppData({user: sessionToken.sub}));
  };
  ```

* ####

  ##### Description

  Use \`admin.graphql\` to make query / mutation requests.

  ##### Example

  ```ts
  import { ActionArgs } from "@remix-run/node";
  import { authenticate } from "../shopify.server";

  export async function action({ request }: ActionArgs) {
    const { admin } = await authenticate.admin(request);

    const response = await admin.graphql(
      `#graphql
      mutation populateProduct($input: ProductInput!) {
        productCreate(input: $input) {
          product {
            id
          }
        }
      }`,
      { variables: { input: { title: "Product Name" } } }
    );

    const productData = await response.json();
    return json({ data: productData.data });
  }
  ```

* #### Using REST resources

  ##### Description

  Getting the number of orders in a store using REST resources.

  ##### /app/shopify.server.ts

  ```ts
  import { shopifyApp } from "@shopify/shopify-app-remix/server";
  import { restResources } from "@shopify/shopify-api/rest/admin/2023-07";

  const shopify = shopifyApp({
    restResources,
    // ...etc
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { admin, session } = await authenticate.admin(request);
    return json(admin.rest.resources.Order.count({ session }));
  };
  ```

* #### Performing a GET request to the REST API

  ##### Description

  Use \`admin.rest.\&lt;method\&gt;\` to make custom requests to the API.

  ##### /app/shopify.server.ts

  ```ts
  import { shopifyApp } from "@shopify/shopify-app-remix/server";
  import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";

  const shopify = shopifyApp({
    restResources,
    // ...etc
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, json } from "@remix-run/node";
  import { authenticate } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { admin, session } = await authenticate.admin(request);
    const response = await admin.rest.get({ path: "/customers/count.json" });
    const customers = await response.json();
    return json({ customers });
  };
  ```

* #### Cancelling a subscription

  ##### Description

  Use the \`billing.cancel\` function to cancel an active subscription with the id returned from \`billing.require\`.

  ##### /app/routes/cancel-subscription.ts

  ```ts
  import { LoaderArgs } from "@remix-run/node";
  import { authenticate, MONTHLY_PLAN } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { billing } = await authenticate.admin(request);
    const billingCheck = await billing.require({
      plans: [MONTHLY_PLAN],
      onFailure: async () => billing.request({ plan: MONTHLY_PLAN }),
    });

    const subscription = billingCheck.appSubscriptions[0];
    const cancelledSubscription = await billing.cancel({
      subscriptionId: subscription.id,
      isTest: true,
      prorate: true,
     });

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Using a custom return URL

  ##### Description

  Change where the merchant is returned to after approving the purchase using the \`returnUrl\` option.

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs } from "@remix-run/node";
  import { authenticate, MONTHLY_PLAN } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { billing } = await authenticate.admin(request);
    await billing.require({
      plans: [MONTHLY_PLAN],
      onFailure: async () => billing.request({
        plan: MONTHLY_PLAN,
        isTest: true,
        returnUrl: '/billing-complete',
      }),
    });

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Requesting billing right away

  ##### Description

  Call \`billing.request\` in the \`onFailure\` callback to immediately request payment.

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs } from "@remix-run/node";
  import { authenticate, MONTHLY_PLAN } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { billing } = await authenticate.admin(request);
    await billing.require({
      plans: [MONTHLY_PLAN],
      isTest: true,
      onFailure: async () => billing.request({ plan: MONTHLY_PLAN }),
    });

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Using a plan selection page

  ##### Description

  Redirect to a different page in the \`onFailure\` callback, where the merchant can select a billing plan.

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, redirect } from "@remix-run/node";
  import { authenticate, MONTHLY_PLAN, ANNUAL_PLAN } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { billing } = await authenticate.admin(request);
    const billingCheck = await billing.require({
      plans: [MONTHLY_PLAN, ANNUAL_PLAN],
      isTest: true,
      onFailure: () => redirect('/select-plan'),
    });

    const subscription = billingCheck.appSubscriptions[0];
    console.log(`Shop is on ${subscription.name} (id ${subscription.id})`);

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

***

## Related

[Interact with the Admin API. - API context](https://shopify.dev/docs/api/shopify-app-remix/v1/apis/admin-api)

[Bill merchants for your app using the Admin API. - Billing context](https://shopify.dev/docs/api/shopify-app-remix/v1/apis/billing)

***
