--- title: Flow description: Contains functions for verifying Shopify Flow extensions. api_version: v2 api_name: shopify-app-remix source_url: html: 'https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/flow' md: 'https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/flow.md' --- # Flow Contains functions for verifying Shopify Flow extensions. See the [Flow documentation](https://shopify.dev/docs/apps/flow/actions/endpoints) for more information. ## authenticate.​flow(**[request](#authenticateflow-propertydetail-request)**​) Verifies requests coming from Shopify Flow extensions. ### Parameters * **request** **Request** **required** ### Returns * **Promise\>** ### FlowContext * admin An admin context for the Flow request. Returned only if there is a session for the shop. ```ts AdminApiContext ``` * payload The payload from the Flow request. ```ts any ``` * session A session with an offline token for the shop. Returned only if there is a session for the shop. ```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 ``` ### GraphQLClient * query ```ts Operation extends keyof Operations ``` * options ```ts GraphQLQueryOptions ``` returns ```ts interface Promise { /** * 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(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; /** * 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(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; }, interface Promise {}, Promise: PromiseConstructor, interface Promise { readonly [Symbol.toStringTag]: string; }, interface Promise { /** * 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; } ``` ### GraphQLQueryOptions * apiVersion The version of the API to use for the request. ```ts ApiVersion ``` * headers Additional headers to include in the request. ```ts Record ``` * 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 ``` ### RestClientWithResources ```ts RemixRestClient & {resources: Resources} ``` ### RemixRestClient * session ```ts Session ``` * get Performs a GET request on the given path. ```ts (params: GetRequestParams) => Promise ``` * post Performs a POST request on the given path. ```ts (params: PostRequestParams) => Promise ``` * put Performs a PUT request on the given path. ```ts (params: PostRequestParams) => Promise ``` * delete Performs a DELETE request on the given path. ```ts (params: GetRequestParams) => Promise ``` Examples ### Examples * #### ##### Description Handle a flow action call ##### /app/routes/\*\*.ts ```ts import {type ActionFunctionArgs} from '@remix-run/node'; import {authenticate} from '../shopify.server'; export const action = async ({request}: ActionFunctionArgs) => { const {admin, payload} = await authenticate.flow(request); const customerId = payload.properties.customer_id; const response = await admin.graphql( `#graphql mutation setMetafield($customerId: ID!, $time: String!) { metafieldsSet(metafields: { ownerId: $customerId namespace: "my-app", key: "last_flow_update", value: $time, type: "string", }) { metafields { key value } } } `, { variables: { customerId, time: new Date().toISOString(), }, }, ); const body = await response.json(); console.log('Updated value', body.data!.metafieldsSet!.metafields![0].value); return new Response(); }; ``` * #### ##### Description Use the \`admin\` object in the context to interact with the Admin API. ##### /app/routes/flow\.tsx ```ts import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export async function action({ request }: ActionFunctionArgs) { const { admin } = await authenticate.flow(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 }); } ``` * #### ##### Description Get the request's POST payload. ##### /app/routes/flow\.tsx ```ts import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { payload } = await authenticate.flow(request); return new Response(); }; ``` * #### ##### Description Use the session associated with this request to use REST resources. ##### /app/routes/flow\.tsx ```ts import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { session, admin } = await authenticate.flow(request); const products = await admin?.rest.resources.Product.all({ session }); // Use products return new Response(); }; ``` *** ## Related [Interact with the Admin API. - Admin API context](https://shopify.dev/docs/api/shopify-app-remix/v2/apis/admin-api) [Receive requests from Flow. - Flow action endpoints](https://shopify.dev/docs/apps/flow/actions/endpoints) ***