Skip to content

tRPC v12 isn’t on npm yet. The @trpc12/* packages on this site can’t be installed until it’s released. Use v11 today

tRPC

Query keys and filters

How tRPC's query keys are shaped, the filters that invalidate and read them, and keyPrefix for two APIs in one QueryClient.

On this page

A query key starts with the procedure's path as an array, then its input and what made it: [['post', 'byId'], { input: { id: '1' }, type: 'query' }]. The type is query, infinite, streamed or live, or mutation for a streamed mutation's chunks. A mutation key is the path alone, [['post', 'create']]. Since the path is an array, [['post']] partially matches every key under post.

You rarely write a key: each helper makes its own, and has a function that returns it.

HelperKey or filter for
trpc.pathKey(), trpc.post.pathKey()everything under a path: queries, infinite, streamed and live queries, mutations
trpc.post.pathFilter(filters?)the same, as filters for invalidateQueries, cancelQueries, removeQueries …
trpc.post.byId.queryKey({ input })the exact key queryOptions() uses, typed for getQueryData
trpc.post.byId.queryFilter({ input? })a procedure's queries, every input or one
trpc.post.list.infiniteKey({ input, initialPageParam })the exact key infiniteOptions() uses
trpc.post.create.mutationKey(), mutationFilter()a procedure's mutations, for useIsMutating and useMutationState
trpc.x.streamedKey(), trpc.x.liveKey()a subscription's query-cache forms

Invalidate and update

// every post query, whatever its procedure or input
await const queryClient: QueryClientqueryClient.QueryClient.invalidateQueries<TrpcQueryKey>(filters?: InvalidateQueryFilters<TrpcQueryKey> | undefined, options?: InvalidateOptions): Promise<void>invalidateQueries(
const trpc: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
trpc
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, LinksTypes<...>>>
post
.
PathUtils.pathFilter(filters?: QueryFiltersIn): QueryFiltersIn & {
    queryKey: TrpcQueryKey;
}
pathFilter
());
// post.byId for one input await const queryClient: QueryClientqueryClient.
QueryClient.invalidateQueries<TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}>(filters?: InvalidateQueryFilters<...> | undefined, options?: InvalidateOptions): Promise<void>
invalidateQueries
(
const trpc: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
trpc
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, LinksTypes<...>>>
post
.
byId: QueryProcedureUtils<{
    id: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    ...;
})>, Omit<...>>
byId
.
QueryProcedureUtils<{ id: string; }, { id: string; title: string; author: string | null; createdAt: string; }, NonNullable<(TrpcError<"NOT_FOUND", undefined> & { readonly defined: false; }) | ... 25 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.queryFilter(opts?: ({
    input?: {
        id: string;
    } | undefined;
} & QueryFiltersIn) | undefined): QueryFiltersIn & {
    queryKey: TrpcQueryKey & {
        [dataTagSymbol]: {
            id: string;
            title: string;
            author: string | null;
            createdAt: string;
        };
        [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
            readonly defined: false;
        }) | (TrpcError<"BAD_REQUEST", undefined> & {
            readonly defined: false;
        }) | (TrpcError<"UNAUTHORIZED", undefined> & {
            readonly defined: false;
        }) | ... 23 more ... | (TrpcError<...> & {
            ...;
        })>;
    };
}
queryFilter
({
input?: {
    id: string;
} | undefined
input
: { id: stringid } }),
); // typed by the key: the procedure's output const
const key: TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}
key
=
const trpc: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
trpc
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, LinksTypes<...>>>
post
.
byId: QueryProcedureUtils<{
    id: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    ...;
})>, Omit<...>>
byId
.
QueryProcedureUtils<{ id: string; }, { id: string; title: string; author: string | null; createdAt: string; }, NonNullable<(TrpcError<"NOT_FOUND", undefined> & { readonly defined: false; }) | ... 25 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.queryKey(opts: {
    input: {
        id: string;
    } | unique symbol;
}): TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | ... 22 more ... | (TrpcError<...> & {
        ...;
    })>;
}
queryKey
({
input: {
    id: string;
} | unique symbol
input
: { id: stringid } });
const post = const queryClient: QueryClientqueryClient.
QueryClient.getQueryData<unknown, TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}, {
    ...;
}>(queryKey: TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}): {
    ...;
} | undefined
getQueryData
(
const key: TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}
key
);
const post: {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
} | undefined
const queryClient: QueryClientqueryClient.
QueryClient.setQueryData<unknown, TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}, {
    ...;
}>(queryKey: TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}, updater: Updater<...>, options?: SetDataOptions): NoInfer<{
    ...;
}> | undefined
setQueryData
(
const key: TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
        readonly defined: false;
    }) | ... 21 more ... | (TrpcError<...> & {
        ...;
    })>;
}
key
, (
old: NoInfer<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}> | undefined
old
) =>
old: NoInfer<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}> | undefined
old
? { ...
old: NoInfer<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}>
old
, title: stringtitle: 'Renamed' } : old: undefinedold,
);

Two APIs, one QueryClient

Keys start with the procedure path, so two tRPC APIs with a post.byId would share cache entries. Give one a keyPrefix:

const 
const billing: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
billing
=
createTrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>(opts: CreateTrpcQueryUtilsOptions<...>): TrpcQueryUtils<...>
createTrpcQueryUtils
({
CreateTrpcQueryUtilsOptions<TrpcClient<{ post: { byId: Procedure<{ type: "query"; ctx: Context; meta: {}; input: { id: string; }; output: Post; errors: TrpcError<"NOT_FOUND", { id: string; }> | SchemaValidationError<ZodObject<{ id: ZodString; }, $strip>>; services: never; }>; list: Procedure<...>; create: Procedure<...>; }; }, {}, undefined, LinksTypes<...>>>.client: TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
client
:
const billingClient: TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
billingClient
,
CreateTrpcQueryUtilsOptions<TClient>.keyPrefix?: string | undefinedkeyPrefix: 'billing', });
const billing: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
billing
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, LinksTypes<...>>>
post
.
byId: QueryProcedureUtils<{
    id: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    ...;
})>, Omit<...>>
byId
.
QueryProcedureUtils<{ id: string; }, { id: string; title: string; author: string | null; createdAt: string; }, NonNullable<(TrpcError<"NOT_FOUND", undefined> & { readonly defined: false; }) | ... 25 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.queryKey(opts: {
    input: {
        id: string;
    } | unique symbol;
}): TrpcQueryKey & {
    [dataTagSymbol]: {
        id: string;
        title: string;
        author: string | null;
        createdAt: string;
    };
    [dataTagErrorSymbol]: NonNullable<(TrpcError<"NOT_FOUND", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"BAD_REQUEST", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"UNAUTHORIZED", undefined> & {
        readonly defined: false;
    }) | (TrpcError<"PARSE_ERROR", undefined> & {
        readonly defined: false;
    }) | ... 22 more ... | (TrpcError<...> & {
        ...;
    })>;
}
queryKey
({
input: {
    id: string;
} | unique symbol
input
: { id: stringid } }); // [['billing', 'post', 'byId'], { input: { id }, type: 'query' }]
const billing: TrpcQueryUtils<TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>
billing
.
PathUtils.pathFilter(filters?: QueryFiltersIn): QueryFiltersIn & {
    queryKey: TrpcQueryKey;
}
pathFilter
(); // matches only billing's queries

Every framework's createTrpcContext({ keyPrefix: 'billing' }) and createTrpcRsc({ keyPrefix }) take it too; the server and browser must use the same one.

Next.js cache tags

cacheTags(key) and revalidationTag(key) turn a key into Next.js data-cache tags, so a mutation can revalidate exactly what a query key covers (React Server Components).