---
id: createApi
title: createApi
sidebar_label: createApi
hide_title: true
description: 'RTK Query > API: createApi reference'
---

&nbsp;

# `createApi`

`createApi` is the core of RTK Query's functionality. It allows you to define a set of "endpoints" that describe how to retrieve data from backend APIs and other async sources, including the configuration of how to fetch and transform that data. It generates [an "API slice" structure](./created-api/overview.mdx) that contains Redux logic (and optionally React hooks) that encapsulate the data fetching and caching process for you.

:::tip

Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`. This allows you to effectively take advantage of [automated re-fetching](../usage/automated-refetching.mdx) by defining [tag](../usage/automated-refetching.mdx#tags) relationships across endpoints.

This is because:

- Automatic tag invalidation only works within a single API slice. If you have multiple API slices, the automatic invalidation won't work across them.
- Every `createApi` call generates its own middleware, and each middleware added to the store will run checks against every dispatched action. That has a perf cost that adds up. So, if you called `createApi` 10 times and added 10 separate API middleware to the store, that will be noticeably slower perf-wise.

For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See [code splitting](../usage/code-splitting.mdx) for how you can use the `injectEndpoints` property to inject API endpoints from other files into a single API slice definition.

:::

```ts title="Example: src/services/pokemon.ts"
// file: src/services/types.ts noEmit
export type Pokemon = {}

// file: src/services/pokemon.ts
// Need to use the React-specific entry point to allow generating React hooks
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import type { Pokemon } from './types'

// highlight-start
// Define a service using a base URL and expected endpoints
export const pokemonApi = createApi({
  reducerPath: 'pokemonApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
  endpoints: (build) => ({
    getPokemonByName: build.query<Pokemon, string>({
      query: (name) => `pokemon/${name}`,
    }),
  }),
})
//highlight-end

// highlight-start
// Export hooks for usage in function components, which are
// auto-generated based on the defined endpoints
export const { useGetPokemonByNameQuery } = pokemonApi
// highlight-end
```

## `createApi` Parameters

`createApi` accepts a single configuration object parameter with the following options:

```ts no-transpile
  baseQuery(args: InternalQueryArgs, api: BaseQueryApi, extraOptions?: DefinitionExtraOptions): any;
  endpoints(build: EndpointBuilder<InternalQueryArgs, TagTypes>): Definitions;
  extractRehydrationInfo?: (
    action: UnknownAction,
    {
      reducerPath,
    }: {
      reducerPath: ReducerPath
    }
  ) =>
    | undefined
    | CombinedState<Definitions, TagTypes, ReducerPath>
  tagTypes?: readonly TagTypes[];
  reducerPath?: ReducerPath;
  serializeQueryArgs?: SerializeQueryArgs<InternalQueryArgs>;
  keepUnusedDataFor?: number; // value is in seconds
  refetchOnMountOrArgChange?: boolean | number; // value is in seconds
  refetchOnFocus?: boolean;
  refetchOnReconnect?: boolean;
```

### `baseQuery`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.baseQuery)

#### baseQuery function arguments

- `args` - The return value of the `query` function for a given endpoint
- `api` - The `BaseQueryApi` object contains:
  - `signal` - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) object that may be used to abort DOM requests and/or read whether the request is aborted.
  - `abort` - The [`abort()`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort) method of the AbortController attached to `signal`.
  - `dispatch` - The `store.dispatch` method for the corresponding Redux store
  - `getState` - A function that may be called to access the current store state
  - `extra` - Provided as thunk.extraArgument to the configureStore getDefaultMiddleware option.
  - `endpoint` - The name of the endpoint.
  - `type` - Type of request (`query` or `mutation`).
  - `forced` - Indicates if a query has been forced.
  - `queryCacheKey`- The computed query cache key.
- `extraOptions` - The value of the optional `extraOptions` property provided for a given endpoint

#### baseQuery function signature

```ts title="Base Query signature" no-transpile
export type BaseQueryFn<
  Args = any,
  Result = unknown,
  Error = unknown,
  DefinitionExtraOptions = {},
  Meta = {},
> = (
  args: Args,
  api: BaseQueryApi,
  extraOptions: DefinitionExtraOptions,
) => MaybePromise<QueryReturnValue<Result, Error, Meta>>

export interface BaseQueryApi {
  signal: AbortSignal
  abort: (reason?: string) => void
  dispatch: ThunkDispatch<any, any, any>
  getState: () => unknown
  extra: unknown
  endpoint: string
  type: 'query' | 'mutation'
  forced?: boolean
}

export type QueryReturnValue<T = unknown, E = unknown, M = unknown> =
  | {
      error: E
      data?: undefined
      meta?: M
    }
  | {
      error?: undefined
      data: T
      meta?: M
    }
```

[examples](docblock://query/createApi.ts?token=CreateApiOptions.baseQuery)

### `endpoints`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.endpoints)

See [Endpoint Definition Parameters](#endpoint-definition-parameters) for details on individual properties.

#### Query endpoint definition

Query endpoints (defined with `build.query()`) are used to cache data fetched from the server.

You must specify either a `query` field (which will use the API's `baseQuery` to make a request), or a `queryFn` function with your own async logic. All other fields are optional.

```ts title="Query endpoint definition" no-transpile
export type FullTagDescription<TagType> = {
  type: TagType
  id?: number | string
}
export type TagDescription<TagType> = TagType | FullTagDescription<TagType>

type TagDescriptionArray<TagTypes extends string> = ReadonlyArray<
  TagDescription<TagTypes> | undefined | null
>

export type ResultDescription<
  TagTypes extends string,
  ResultType,
  QueryArg,
  ErrorType,
  MetaType,
> =
  | TagDescriptionArray<TagTypes>
  | (
  result: ResultType | undefined,
  error: ErrorType | undefined,
  arg: QueryArg,
  meta: MetaType,
) => TagDescriptionArray<TagTypes>


export type QueryDefinition<
  QueryArg,
  BaseQuery extends BaseQueryFn,
  TagTypes extends string,
  ResultType,
  ReducerPath extends string = string,
> = {
  query(arg: QueryArg): BaseQueryArg<BaseQuery>

  /* either `query` or `queryFn` can be present, but not both simultaneously */
  queryFn(
    arg: QueryArg,
    api: BaseQueryApi,
    extraOptions: BaseQueryExtraOptions<BaseQuery>,
    baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>,
  ): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>

  /* transformResponse only available with `query`, not `queryFn` */
  transformResponse?(
    baseQueryReturnValue: BaseQueryResult<BaseQuery>,
    meta: BaseQueryMeta<BaseQuery>,
    arg: QueryArg,
  ): ResultType | Promise<ResultType>

  /* transformErrorResponse only available with `query`, not `queryFn` */
  transformErrorResponse?(
    baseQueryReturnValue: BaseQueryError<BaseQuery>,
    meta: BaseQueryMeta<BaseQuery>,
    arg: QueryArg,
  ): unknown

  extraOptions?: BaseQueryExtraOptions<BaseQuery>

  providesTags?: ResultDescription<
    TagTypes,
    ResultType,
    QueryArg,
    BaseQueryError<BaseQuery>
  >

  keepUnusedDataFor?: number

  onQueryStarted?(
    arg: QueryArg,
    {
      dispatch,
      getState,
      extra,
      requestId,
      queryFulfilled,
      getCacheEntry,
      updateCachedData, // available for query endpoints only
    }: QueryLifecycleApi,
  ): Promise<void>

  onCacheEntryAdded?(
    arg: QueryArg,
    {
      dispatch,
      getState,
      extra,
      requestId,
      cacheEntryRemoved,
      cacheDataLoaded,
      getCacheEntry,
      updateCachedData, // available for query endpoints only
    }: QueryCacheLifecycleApi,
  ): Promise<void>

  argSchema?: StandardSchemaV1<QueryArg>

  /* only available with `query`, not `queryFn` */
  rawResponseSchema?: StandardSchemaV1<BaseQueryResult<BaseQuery>>

  responseSchema?: StandardSchemaV1<ResultType>

  /* only available with `query`, not `queryFn` */
  rawErrorResponseSchema?: StandardSchemaV1<BaseQueryError<BaseQuery>>

  errorResponseSchema?: StandardSchemaV1<BaseQueryError<BaseQuery>>

  metaSchema?: StandardSchemaV1<BaseQueryMeta<BaseQuery>>
}
```

#### Infinite Query endpoint definition

Infinite query endpoints (defined with `build.infiniteQuery()`) are used to cache multi-page data sets from the server. They have all the same callbacks and options as standard query endpoints, but also require an additional [`infiniteQueryOptions`](#infinitequeryoptions) field to specify how to calculate the unique parameters to fetch each page.

For infinite query endpoints, there is a separation between the "query arg" used for the cache key, and the "page param" used to fetch a specific page. For example, a Pokemon API endpoint might have a string query arg like `"fire"` , but use a page number as the param to determine which page to fetch out of the results. The `query` and `queryFn` methods will receive a combined `{queryArg, pageParam}` object as the argument, rather than just the `queryArg` by itself.

```ts title="Infinite Query endpoint definition" no-transpile
export type PageParamFunction<DataType, PageParam, QueryArg> = (
  firstPage: DataType,
  allPages: Array<DataType>,
  firstPageParam: PageParam,
  allPageParams: Array<PageParam>,
  queryArg: QueryArg,
) => PageParam | undefined | null

type InfiniteQueryCombinedArg<QueryArg, PageParam> = {
  queryArg: QueryArg
  pageParam: PageParam
}

export type InfiniteQueryDefinition<
  QueryArg,
  PageParam,
  BaseQuery extends BaseQueryFn,
  TagTypes extends string,
  ResultType,
  ReducerPath extends string = string,
> =
  // Infinite queries have all the same options as query endpoints,
  // but store the `{pages, pageParams}` structure, and receive an object
  // with both `{queryArg, pageParam}` as the arg for `query` and `queryFn`.
  QueryDefinition<
    InfiniteQueryCombinedArg<QueryArg, PageParam>,
    BaseQuery,
    TagTypes,
    InfiniteData<ResultType>
  > & {
    /**
     * Required options to configure the infinite query behavior.
     * `initialPageParam` and `getNextPageParam` are required, to
     * ensure the infinite query can properly fetch the next page of data.
     * `initialPageparam` may be specified when using the
     * endpoint, to override the default value.
     */
    infiniteQueryOptions: {
      /**
       * The initial page parameter to use for the first page fetch.
       */
      initialPageParam: PageParam
      /**
       * This function is required to automatically get the next cursor for infinite queries.
       * The result will also be used to determine the value of `hasNextPage`.
       */
      getNextPageParam: PageParamFunction<DataType, PageParam, QueryArg>
      /**
       * This function can be set to automatically get the previous cursor for infinite queries.
       * The result will also be used to determine the value of `hasPreviousPage`.
       */
      getPreviousPageParam?: PageParamFunction<DataType, PageParam, QueryArg>
      /**
       * If specified, only keep this many pages in cache at once.
       * If additional pages are fetched, older pages in the other
       * direction will be dropped from the cache.
       */
      maxPages?: number
      /**
       * Defaults to `true`. When this is `true` and an infinite query endpoint is refetched
       * (due to tag invalidation, polling, arg change configuration, or manual refetching),
       * RTK Query will try to sequentially refetch all pages currently in the cache.
       * When `false` only the first page will be refetched.
       */
      refetchCachedPages?: boolean
    }
  }
```

#### Mutation endpoint definition

Mutation endpoints (defined with `build.mutation()`) are used to send updates to the server, and force invalidation and refetching of query endpoints.

As with queries, you must specify either the `query` option or the `queryFn` async method.

```ts title="Mutation endpoint definition" no-transpile
export type MutationDefinition<
  QueryArg,
  BaseQuery extends BaseQueryFn,
  TagTypes extends string,
  ResultType,
  ReducerPath extends string = string,
  Context = Record<string, any>,
> = {
  query(arg: QueryArg): BaseQueryArg<BaseQuery>

  /* either `query` or `queryFn` can be present, but not both simultaneously */
  queryFn(
    arg: QueryArg,
    api: BaseQueryApi,
    extraOptions: BaseQueryExtraOptions<BaseQuery>,
    baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>,
  ): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>

  /* transformResponse only available with `query`, not `queryFn` */
  transformResponse?(
    baseQueryReturnValue: BaseQueryResult<BaseQuery>,
    meta: BaseQueryMeta<BaseQuery>,
    arg: QueryArg,
  ): ResultType | Promise<ResultType>

  /* transformErrorResponse only available with `query`, not `queryFn` */
  transformErrorResponse?(
    baseQueryReturnValue: BaseQueryError<BaseQuery>,
    meta: BaseQueryMeta<BaseQuery>,
    arg: QueryArg,
  ): unknown

  extraOptions?: BaseQueryExtraOptions<BaseQuery>

  invalidatesTags?: ResultDescription<TagTypes, ResultType, QueryArg>

  onQueryStarted?(
    arg: QueryArg,
    {
      dispatch,
      getState,
      extra,
      requestId,
      queryFulfilled,
      getCacheEntry,
    }: MutationLifecycleApi,
  ): Promise<void>

  onCacheEntryAdded?(
    arg: QueryArg,
    {
      dispatch,
      getState,
      extra,
      requestId,
      cacheEntryRemoved,
      cacheDataLoaded,
      getCacheEntry,
    }: MutationCacheLifecycleApi,
  ): Promise<void>
}
```

#### How endpoints get used

When defining a key like `getPosts` as shown below, it's important to know that this name will become exportable from `api` and be able to referenced under `api.endpoints.getPosts.useQuery()`, `api.endpoints.getPosts.initiate()` and `api.endpoints.getPosts.select()`. The same thing applies to `mutation`s but they reference `useMutation` instead of `useQuery`.

```ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
  id: number
  name: string
}
type PostsResponse = Post[]

const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  tagTypes: ['Posts'],
  endpoints: (build) => ({
    getPosts: build.query<PostsResponse, void>({
      query: () => 'posts',
      providesTags: (result) =>
        result ? result.map(({ id }) => ({ type: 'Posts', id })) : [],
    }),
    addPost: build.mutation<Post, Partial<Post>>({
      query: (body) => ({
        url: `posts`,
        method: 'POST',
        body,
      }),
      invalidatesTags: ['Posts'],
    }),
  }),
})

// Auto-generated hooks
export const { useGetPostsQuery, useAddPostMutation } = api

// Possible exports
export const { endpoints, reducerPath, reducer, middleware } = api
// reducerPath, reducer, middleware are only used in store configuration
// endpoints will have:
// endpoints.getPosts.initiate(), endpoints.getPosts.select(), endpoints.getPosts.useQuery()
// endpoints.addPost.initiate(), endpoints.addPost.select(), endpoints.addPost.useMutation()
// see `createApi` overview for _all exports_
```

### `extractRehydrationInfo`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.extractRehydrationInfo)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.extractRehydrationInfo)

See also [Server Side Rendering](../usage/server-side-rendering.mdx) and
[Persistence and Rehydration](../usage/persistence-and-rehydration.mdx).

### `tagTypes`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.tagTypes)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.tagTypes)

### `reducerPath`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.reducerPath)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.reducerPath)

### `serializeQueryArgs`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.serializeQueryArgs)

By default, this function will take the query arguments, sort object keys where applicable, stringify the result, and concatenate it with the endpoint name. This creates a cache key based on the combination of arguments + endpoint name (ignoring object key order), such that calling any given endpoint with the same arguments will result in the same cache key.

### `invalidationBehavior`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.invalidationBehavior)

### `keepUnusedDataFor`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.keepUnusedDataFor)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.keepUnusedDataFor)

### `refetchOnMountOrArgChange`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.refetchOnMountOrArgChange)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `refetchOnMountOrArgChange` to each individual hook call or similarly by passing `forceRefetch: true` when dispatching the [`initiate`](./created-api/endpoints.mdx#initiate) action.
:::

### `refetchOnFocus`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.refetchOnFocus)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `refetchOnFocus` to each individual hook call or when dispatching the [`initiate`](./created-api/endpoints.mdx#initiate) action.

If you specify `track: false` when manually dispatching queries, RTK Query will not be able to automatically refetch for you.
:::

### `refetchOnReconnect`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.refetchOnReconnect)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `refetchOnReconnect` to each individual hook call or when dispatching the [`initiate`](./created-api/endpoints.mdx#initiate) action.

If you specify `track: false` when manually dispatching queries, RTK Query will not be able to automatically refetch for you.
:::

### `onSchemaFailure`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.onSchemaFailure)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.onSchemaFailure)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `onSchemaFailure` to each individual endpoint definition.
:::

### `catchSchemaFailure`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.catchSchemaFailure)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.catchSchemaFailure)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `catchSchemaFailure` to each individual endpoint definition.
:::

### `skipSchemaValidation`

[summary](docblock://query/createApi.ts?token=CreateApiOptions.skipSchemaValidation)

[examples](docblock://query/createApi.ts?token=CreateApiOptions.skipSchemaValidation)

:::note
You can set this globally in `createApi`, but you can also override the default value and have more granular control by passing `skipSchemaValidation` to each individual endpoint definition.
:::

## Endpoint Definition Parameters

### `query`

_(required if no `queryFn` provided)_

```ts title="query signature" no-transpile
export type query = <QueryArg>(
  arg: QueryArg,
) => string | Record<string, unknown>

// with `fetchBaseQuery`
export type query = <QueryArg>(arg: QueryArg) => string | FetchArgs
```

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.query)

[examples](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.query)

### `queryFn`

_(required if no `query` provided)_

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQueryFn.queryFn)

Called with the same arguments as `baseQuery`, as well as the provided `baseQuery` function itself. It is expected to return an object with either a `data` or `error` property, or a promise that resolves to return such an object.

See also [Customizing queries with queryFn](../usage/customizing-queries.mdx#customizing-queries-with-queryfn).

```ts title="queryFn signature" no-transpile
queryFn(
  arg: QueryArg,
  api: BaseQueryApi,
  extraOptions: BaseQueryExtraOptions<BaseQuery>,
  baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>
): MaybePromise<
| {
    error: BaseQueryError<BaseQuery>
    data?: undefined
  }
| {
    error?: undefined
    data: ResultType
  }
>

export interface BaseQueryApi {
  signal: AbortSignal
  dispatch: ThunkDispatch<any, any, any>
  getState: () => unknown
}
```

#### `queryFn` function arguments

- `args` - The argument provided when the query itself is called
- `api` - The `BaseQueryApi` object, containing `signal`, `dispatch` and `getState` properties
  - `signal` - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) object that may be used to abort DOM requests and/or read whether the request is aborted.
  - `dispatch` - The `store.dispatch` method for the corresponding Redux store
  - `getState` - A function that may be called to access the current store state
- `extraOptions` - The value of the optional `extraOptions` property provided for the endpoint
- `baseQuery` - The `baseQuery` function provided to the api itself

[examples](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQueryFn.queryFn)

### `infiniteQueryOptions`

_(only for `infiniteQuery` endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=InfiniteQueryExtraOptions.infiniteQueryOptions)

The `infiniteQueryOptions` field includes:

- `initialPageParam`: the default page param value used for the first request, if this was not specified at the usage site
- `getNextPageParam`: a required callback you must provide to calculate the next page param, given the existing cached pages and page params
- `getPreviousPageParam`: an optional callback that will be used to calculate the previous page param, if you try to fetch backwards.
- `maxPages`: an optional limit to how many fetched pages will be kept in the cache entry at a time

[examples](docblock://query/endpointDefinitions.ts?token=InfiniteQueryExtraOptions.infiniteQueryOptions)

### `transformResponse`

_(optional, not applicable with `queryFn`)_

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.transformResponse)

In some cases, you may want to manipulate the data returned from a query before you put it in the cache. In this instance, you can take advantage of `transformResponse`.

See also [Customizing query responses with `transformResponse`](../usage/customizing-queries.mdx#customizing-query-responses-with-transformresponse)

```ts title="Unpack a deeply nested collection" no-transpile
transformResponse: (response, meta, arg) =>
  response.some.deeply.nested.collection
```

### `transformErrorResponse`

_(optional, not applicable with `queryFn`)_

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.transformErrorResponse)

In some cases, you may want to manipulate the error returned from a query before you put it in the cache. In this instance, you can take advantage of `transformErrorResponse`.

See also [Customizing query responses with `transformErrorResponse`](../usage/customizing-queries.mdx#customizing-query-responses-with-transformerrorresponse)

```ts title="Unpack a deeply nested error object" no-transpile
transformErrorResponse: (response, meta, arg) =>
  response.data.some.deeply.nested.errorObject
```

### `extraOptions`

_(optional)_

Passed as the third argument to the supplied `baseQuery` function

### `providesTags`

_(optional, only for query endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.providesTags)

See also [Providing cache data](../usage/automated-refetching.mdx#providing-cache-data).

[examples](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.providesTags)

### `invalidatesTags`

_(optional, only for mutation endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=MutationExtraOptions.invalidatesTags)

See also [Invalidating cache data](../usage/automated-refetching.mdx#invalidating-cache-data).

[examples](docblock://query/endpointDefinitions.ts?token=MutationExtraOptions.invalidatesTags)

### `keepUnusedDataFor`

_(optional, only for query endpoints)_

Overrides the api-wide definition of `keepUnusedDataFor` for this endpoint only.

[summary](docblock://query/createApi.ts?token=CreateApiOptions.keepUnusedDataFor)

[examples](docblock://query/core/buildMiddleware/cacheCollection.ts?token=CacheCollectionQueryExtraOptions)

### `serializeQueryArgs`

_(optional, only for query endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.serializeQueryArgs)

[examples](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.serializeQueryArgs)

### `merge`

_(optional, only for query endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.merge)

[examples](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.merge)

### `forceRefetch`

_(optional, only for query endpoints)_

```ts title="forceRefetch signature" no-transpile
type forceRefetch = (params: {
  currentArg: QueryArg | undefined
  previousArg: QueryArg | undefined
  state: RootState<any, any, string>
  endpointState?: QuerySubState<any>
}) => boolean
```

[summary](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.forceRefetch)

[examples](docblock://query/endpointDefinitions.ts?token=QueryExtraOptions.forceRefetch)

### `onQueryStarted`

_(optional)_

Available to both [queries](../usage/queries.mdx) and [mutations](../usage/mutations.mdx).

A function that is called when you start each individual query or mutation. The function is called with a lifecycle api object containing properties such as `queryFulfilled`, allowing code to be run when a query is started, when it succeeds, and when it fails (i.e. throughout the lifecycle of an individual query/mutation call).

Can be used in `mutations` for [optimistic updates](../usage/manual-cache-updates.mdx#optimistic-updates).

#### Lifecycle API properties

- `dispatch` - The dispatch method for the store.
- `getState` - A method to get the current state for the store.
- `extra` - `extra` as provided as `thunk.extraArgument` to the `configureStore` `getDefaultMiddleware` option.
- `requestId` - A unique ID generated for the query/mutation.
- `queryFulfilled` - A Promise that will resolve with a `data` property (the transformed query result),
  and a `meta` property (`meta` returned by the `baseQuery`).
  If the query fails, this Promise will reject with the error. This allows you to `await` for the query to finish.
- `getCacheEntry` - A function that gets the current value of the cache entry.
- `updateCachedData` _(query endpoints only)_ - A function that accepts a 'recipe' callback specifying how to update the data for the corresponding cache at the time it is called. This uses `immer` internally, and updates can be written 'mutably' while safely producing the next immutable state.

```ts title="Mutation onQueryStarted signature" no-transpile
async function onQueryStarted(
  arg: QueryArg,
  {
    dispatch,
    getState,
    extra,
    requestId,
    queryFulfilled,
    getCacheEntry,
  }: MutationLifecycleApi,
): Promise<void>
```

```ts title="Query onQueryStarted signature" no-transpile
async function onQueryStarted(
  arg: QueryArg,
  {
    dispatch,
    getState,
    extra,
    requestId,
    queryFulfilled,
    getCacheEntry,
    updateCachedData, // available for query endpoints only
  }: QueryLifecycleApi,
): Promise<void>
```

```ts title="onQueryStarted query lifecycle example"
// file: notificationsSlice.ts noEmit
export const messageCreated = (msg: string) => ({
  type: 'notifications/messageCreated',
  payload: msg,
})

// file: api.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
import { messageCreated } from './notificationsSlice'

export interface Post {
  id: number
  name: string
}

const api = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: '/',
  }),
  endpoints: (build) => ({
    getPost: build.query<Post, number>({
      query: (id) => `post/${id}`,
      async onQueryStarted(id, { dispatch, queryFulfilled }) {
        // `onStart` side-effect
        dispatch(messageCreated('Fetching post...'))
        try {
          const { data } = await queryFulfilled
          // `onSuccess` side-effect
          dispatch(messageCreated('Post received!'))
        } catch (err) {
          // `onError` side-effect
          dispatch(messageCreated('Error fetching post!'))
        }
      },
    }),
  }),
})
```

### `onCacheEntryAdded`

_(optional)_

Available to both [queries](../usage/queries.mdx) and [mutations](../usage/mutations.mdx).

A function that is called when a new cache entry is added, i.e. when a new subscription for the endpoint + query parameters combination is created. The function is called with a lifecycle api object containing properties such as `cacheDataLoaded` & `cacheDataRemoved`, allowing code to be run when a cache entry is added, when cache data is loaded, and when the cache entry is removed (i.e. throughout the lifecycle of a cache entry).

Can be used for [streaming updates](../usage/streaming-updates.mdx).

#### Cache Lifecycle API properties

- `dispatch` - The dispatch method for the store.
- `getState` - A method to get the current state for the store.
- `extra` - `extra` as provided as `thunk.extraArgument` to the `configureStore` `getDefaultMiddleware` option.
- `requestId` - A unique ID generated for the cache entry.
- `cacheEntryRemoved` - A Promise that allows you to wait for the point in time when the cache entry has been removed from the cache, by not being used/subscribed to any more in the application for too long or by dispatching `api.util.resetApiState`.
- `cacheDataLoaded` - A Promise that will resolve with the first value for this cache key. This allows you to `await` until an actual value is in the cache.  
  Note: If the cache entry is removed from the cache before any value has ever been resolved, this Promise will reject with `new Error('Promise never resolved before cacheEntryRemoved.')` to prevent memory leaks. You can just re-throw that error (or not handle it at all) - it will be caught outside of `cacheEntryAdded`.
- `getCacheEntry` - A function that gets the current value of the cache entry.
- `updateCachedData` _(query endpoints only)_ - A function that accepts a 'recipe' callback specifying how to update the data at the time it is called. This uses `immer` internally, and updates can be written 'mutably' while safely producing the next immutable state.

```ts title="Mutation onCacheEntryAdded signature" no-transpile
async function onCacheEntryAdded(
  arg: QueryArg,
  {
    dispatch,
    getState,
    extra,
    requestId,
    cacheEntryRemoved,
    cacheDataLoaded,
    getCacheEntry,
  }: MutationCacheLifecycleApi,
): Promise<void>
```

```ts title="Query onCacheEntryAdded signature" no-transpile
async function onCacheEntryAdded(
  arg: QueryArg,
  {
    dispatch,
    getState,
    extra,
    requestId,
    cacheEntryRemoved,
    cacheDataLoaded,
    getCacheEntry,
    updateCachedData, // available for query endpoints only
  }: QueryCacheLifecycleApi,
): Promise<void>
```

### Schema Validation

Endpoints can have schemas for runtime validation of query args, responses, and errors. Any [Standard Schema](https://standardschema.dev/) compliant library can be used.

When used with TypeScript, schemas can also be used to [infer the type of that value instead of having to declare it](../usage-with-typescript.mdx#schema-validation).

:::warning

By default, schema failures are treated as _fatal_, meaning that normal error handling such as tag invalidation will not be executed.

In order for schema failures to be treated as non-fatal, you must provide a [`catchSchemaFailure`](#catchschemafailure) function, to convert the schema failure into an error shape matching the base query errors.

```ts title="catchSchemaFailure example" no-transpile
const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  catchSchemaFailure: (error, info) => ({
    status: 'CUSTOM_ERROR',
    error: error.schemaName + ' failed validation',
    data: error,
  }),
  endpoints: (build) => ({
    // ...
  }),
})
```

:::

#### `argSchema`

_(optional)_

[summary](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.argSchema)

[examples](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.argSchema)

#### `responseSchema`

_(optional)_

[summary](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.responseSchema)

[examples](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.responseSchema)

#### `rawResponseSchema`

_(optional, not applicable with `queryFn`)_

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.rawResponseSchema)

[examples](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.rawResponseSchema)

#### `errorResponseSchema`

_(optional)_

[summary](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.errorResponseSchema)

[examples](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.errorResponseSchema)

#### `rawErrorResponseSchema`

_(optional, not applicable with `queryFn`)_

[summary](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.rawErrorResponseSchema)

[examples](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQuery.rawErrorResponseSchema)

#### `metaSchema`

_(optional)_

[summary](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.metaSchema)

[examples](docblock://query/endpointDefinitions.ts?token=CommonEndpointDefinition.metaSchema)

## Return value

See [the "created Api" API reference](./created-api/overview)