---
title: Admin API
description: Contains objects used to interact with the Admin API.
api_version: v2
source_url:
  html: 'https://shopify.dev/docs/api/shopify-app-remix/v2/apis/admin-api'
  md: 'https://shopify.dev/docs/api/shopify-app-remix/v2/apis/admin-api.md'
api_name: shopify-app-remix
---

# Admin API

Contains objects used to interact with the Admin API.

This object is returned as part of different contexts, such as [`admin`](https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/admin), [`unauthenticated.admin`](https://shopify.dev/docs/api/shopify-app-remix/v2/unauthenticated/unauthenticated-admin), and [`webhook`](https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/webhook).

#### admin

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

* **graphql**

  **GraphQLClient\<AdminOperations>**

  **required**

  Methods for interacting with the Shopify Admin GraphQL API

* **rest**

  **RestClientWithResources\<Resources>**

  **required**

  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.

### GraphQLClient

* query

  ```ts
  Operation extends keyof Operations
  ```

* options

  ```ts
  GraphQLQueryOptions<Operation, Operations>
  ```

returns

```ts
interface Promise<T> {
    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;

    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}, interface Promise<T> {}, Promise: PromiseConstructor, interface Promise<T> {
    readonly [Symbol.toStringTag]: string;
}, interface Promise<T> {
    /**
     * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
     * resolved value cannot be modified from the callback.
     * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
     * @returns A Promise for the completion of the callback.
     */
    finally(onfinally?: (() => void) | undefined | null): Promise<T>;
}
```

### GraphQLQueryOptions

* apiVersion

  The version of the API to use for the request.

  ```ts
  ApiVersion
  ```

* headers

  Additional headers to include in the request.

  ```ts
  Record<string, any>
  ```

* tries

  The total number of times to try the request if it fails.

  ```ts
  number
  ```

* variables

  The variables to pass to the operation.

  ```ts
  ApiClientRequestOptions<Operation, Operations>
  ```

### 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>
  ```

Examples

### Examples

* #### Querying the GraphQL API

  ##### Description

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

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

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

  export const action = async ({ request }: ActionFunctionArgs) => {
    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({
      productId: productData.data?.productCreate?.product?.id,
    });
  }
  ```

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

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

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

* #### Handling GraphQL errors

  ##### Description

  Catch \`GraphqlQueryError\` errors to see error messages from the API.

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

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

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

    try {
      const response = await admin.graphql(
        `#graphql
        query incorrectQuery {
          products(first: 10) {
            nodes {
              not_a_field
            }
          }
        }`,
      );

      return json({ data: await response.json() });
    } catch (error) {
      if (error instanceof GraphqlQueryError) {
        // error.body.errors:
        // { graphQLErrors: [
        //   { message: "Field 'not_a_field' doesn't exist on type 'Product'" }
        // ] }
        return json({ errors: error.body?.errors }, { status: 500 });
      }
      return json({ message: "An error occurred" }, { status: 500 });
    }
  }
  ```

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

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

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

* #### Using REST resources

  ##### Description

  Getting the number of orders in a store using REST resources. Visit the \[Admin REST API references]\(/docs/api/admin-rest) for examples on using each resource.

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

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

  export const loader = async ({ request }: LoaderFunctionArgs) => {
    const {
      admin,
      session,
    } = await authenticate.admin(request);

    return json(
      admin.rest.resources.Order.count({ session }),
    );
  };
  ```

  ##### /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;
  ```

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

  ##### Description

  Use \`admin.rest.get\` to make custom requests to make a request to to the \`customer/count\` endpoint

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

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

  export const loader = async ({ request }: LoaderFunctionArgs) => {
    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 });
  };
  ```

  ##### /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;
  ```

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

  ##### Description

  Use \`admin.rest.post\` to make custom requests to make a request to to the \`customers.json\` endpoint to send a welcome email

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

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

  export const loader = async ({ request }: LoaderFunctionArgs) => {
    const {
      admin,
      session,
    } = await authenticate.admin(request);

    const response = admin.rest.post({
      path: "customers/7392136888625/send_invite.json",
      body: {
        customer_invite: {
          to: "new_test_email@shopify.com",
          from: "j.limited@example.com",
          bcc: ["j.limited@example.com"],
          subject: "Welcome to my new shop",
          custom_message: "My awesome new store",
        },
      },
    });

    const customerInvite = await response.json();
    return json({ customerInvite });
  };
  ```

  ##### /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;
  ```

***

## Related

[Authenticate requests from Shopify Admin. - Authenticated context](https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/admin)

[Interact with the Admin API on non-Shopify requests. - Unauthenticated context](https://shopify.dev/docs/api/shopify-app-remix/v2/unauthenticated/unauthenticated-admin)

***
