API Reference
APIs for defining calls, fetching data, and generating code.
Reference for the public Callsheet APIs.
Defining Calls
These APIs are available from both @callsheet/react-query and @callsheet/swr. Import them from the adapter your app uses.
defineCalls
Creates the shared call tree. Takes a nested object of calls and returns the same shape along with call metadata attached.
import { defineCalls, query, mutation } from '@callsheet/react-query';
// or from '@callsheet/swr'
export const calls = defineCalls({
films: {
featured: query(FeaturedFilmsDocument),
byId: query(FilmByIdDocument, {
family: ['films', 'detail'],
key: ({ input }) => [input.id],
staleTime: 30_000,
}),
update: mutation(UpdateFilmDocument, {
invalidates: [
['films', 'list'],
['films', 'detail'],
],
}),
},
});query
Defines a query call. Can take a typed source (GraphQL document, ts-rest route) or be called with just options for manual calls.
// From a typed source
query(FilmByIdDocument);
query(FilmByIdDocument, { family: ['films', 'detail'] });
// Manual (no source)
query<MyInput, MyOutput>({ staleTime: 30_000 });mutation
Defines a mutation call. Same signature pattern as query.
// From a typed source
mutation(UpdateFilmDocument);
mutation(UpdateFilmDocument, { invalidates: [['films', 'list']] });
// Manual (no source)
mutation<MyInput, MyOutput>();call
Defines a call and infers whether it is a query or mutation from the source. Useful when the source already carries kind information.
call(FilmByIdDocument); // inferred as query
call(contract.films.update); // inferred as mutationUsing Calls in React Query
These APIs come from @callsheet/react-query and are used wherever you interact with React Query.
queryOptions
Builds a query config from a call definition. The result can be passed to useQuery and also includes the canonical Callsheet queryKey for imperative QueryClient workflows.
import { queryOptions } from '@callsheet/react-query';
const options = queryOptions(calls.films.byId, {
input: { id: 'wall-e' },
select: (data) => data.film,
});The input field is required when the call expects input, else optional when it doesn't. All standard React Query options (enabled, staleTime, select, initialData, etc.) can be passed as well.
For strict-input calls, enabled: false can be used without input until the query is ready to execute.
The returned config can also be reused with QueryClient:
const filmQuery = queryOptions(calls.films.byId, {
input: { id: 'wall-e' },
});
queryClient.getQueryData(filmQuery.queryKey);
queryClient.invalidateQueries({ queryKey: filmQuery.queryKey });useQuery
Callsheet's useQuery hook. Thin wrapper around React Query. Takes a query config from queryOptions and returns the standard React Query result. Requires CallsheetProvider in the component tree.
import { queryOptions, useQuery } from '@callsheet/react-query';
const film = useQuery(queryOptions(calls.films.byId, { input: { id } }));useMutation
Callsheet's useMutation hook. Takes a mutation call and optional React Query mutation options. Handles invalidates automatically on success for related queries. Requires CallsheetProvider in the component tree.
import { useMutation } from '@callsheet/react-query';
const updateFilm = useMutation(calls.films.update, {
onSuccess: () => {
/* component-level callback */
},
});createReactQueryAdapter
Creates the adapter that connects Callsheet to React Query. You provide an execute function that knows how to run a call (e.g., make a GraphQL request or REST call).
import { createReactQueryAdapter } from '@callsheet/react-query';
const adapter = createReactQueryAdapter({
execute: async ({ call, input }) => {
// Your request logic here
},
});The adapter is passed to CallsheetProvider.
CallsheetProvider
React context provider that makes the adapter available to useQuery and useMutation.
import { CallsheetProvider } from '@callsheet/react-query';
<CallsheetProvider adapter={adapter}>
<App />
</CallsheetProvider>;Using Calls in SWR
These APIs come from @callsheet/swr and are used in components or wherever you interact with SWR.
useQuery
Callsheet's useQuery hook for SWR. Takes a call and optional options. Returns the standard SWR response. Requires withSWRConfig in the component tree.
import { useQuery } from '@callsheet/swr';
const { data: film } = useQuery(calls.films.byId, {
input: { id: 'wall-e' },
keepPreviousData: true,
});The input field is required when the call expects input, and optional when it doesn't. Local SWR options (fallbackData, revalidateOnMount, keepPreviousData, etc.) can be passed alongside input. Use enabled to conditionally disable the query.
useMutation
Callsheet's useMutation hook for SWR. Takes a mutation call and optional options. Handles invalidates automatically on success. Returns { trigger, ... } matching the SWR mutation response.
import { useMutation } from '@callsheet/swr';
const { trigger } = useMutation(calls.films.update, {
onSuccess: () => {
/* component-level callback */
},
});usePreload
Returns a function that preloads a query's data into the SWR cache before a component mounts. Useful for hover or route prefetch scenarios.
import { usePreload } from '@callsheet/swr';
const preloadFilm = usePreload(calls.films.byId);
preloadFilm({ id: 'wall-e' });Preloaded data is written to the global SWR cache by serialized key. Preload is client-side only.
createSWRAdapter
Creates the adapter that connects Callsheet to SWR.
Options:
execute(required): the function that actually runs a Callsheet callmiddleware(optional): Callsheet execute middleware applied aroundexecute
import { createSWRAdapter } from '@callsheet/swr';
const adapter = createSWRAdapter({
execute: async ({ call, input }) => {
// Your request logic here
},
});withSWRConfig
Attaches the Callsheet adapter to SWRConfig. Use it once at the root of your Callsheet SWR tree, then use the functional form only when you add another nested SWRConfig boundary and want to preserve the existing adapter.
import { SWRConfig } from 'swr';
import { createSWRAdapter, withSWRConfig } from '@callsheet/swr';
const adapter = createSWRAdapter({
execute,
});
<SWRConfig value={withSWRConfig({ dedupingInterval: 5000 }, adapter)}>
<App />
</SWRConfig>;Once that root setup is in place, the functional form inherits the adapter from the parent config:
<SWRConfig
value={withSWRConfig(() => ({
errorRetryCount: 0,
}))}
>
<Settings />
</SWRConfig>ExecuteCallMiddleware
Callsheet's execute middleware runs inside the execution layer and has access to the full call context. Use it for logging, auth headers, metrics, or other behavior that needs to know what call is being made.
import type { ExecuteCallMiddleware } from '@callsheet/swr';
const withLogging: ExecuteCallMiddleware = async (context, next) => {
console.log('executing', context.call.family);
return next();
};
const adapter = createSWRAdapter({
execute: myExecuteFn,
middleware: [withLogging],
});Code Generation
defineConfig
From @callsheet/codegen. Defines the build-time config for generating a calls module.
import { defineConfig } from '@callsheet/codegen';
export default defineConfig({
sources: {
/* ... */
},
output: {
adapter: 'react-query',
file: './src/generated/calls.ts',
},
});For the full config shape, see Codegen Config.
ts-rest Wrappers
These APIs come from @callsheet/ts-rest and are used when manually wrapping ts-rest contract routes without code generation.
query / mutation / call
Wrap a ts-rest contract route as a Callsheet call when you want to use the dedicated manual ts-rest wrapper package.
The main query, mutation, and call exports in @callsheet/react-query and @callsheet/swr also support ts-rest routes directly.
import { query, mutation, call } from '@callsheet/ts-rest';
query(contract.films.byId);
mutation(contract.films.update, { invalidates: [['films', 'list']] });
call(contract.films.byId);For more on when to use these, see Using Callsheet with ts-rest.
Related Docs
- Calls for how the call model works
- Using Callsheet with React Query for shared defaults and overrides
- Using Callsheet with SWR for the SWR adapter guide
- Packages and Imports for package roles
- Codegen Config for the full config reference
- Using Callsheet with ts-rest for the ts-rest workflow