Skip to content

tRPC API Reference

Plugins can add server-side API endpoints using tRPC routers. These endpoints are automatically integrated into the platform’s API.

packages/plugins/my-plugin/src/server/router.ts
import { z } from 'zod';
import { prisma } from '@aether/database';
export const myPluginRouter = (t: any) => t.router({
// Query endpoint
getData: t.procedure
.input(z.object({
id: z.string(),
organizationId: z.string(),
}))
.query(async ({ input }) => {
return await prisma.myPluginData.findMany({
where: {
workUnitId: input.id,
organizationId: input.organizationId,
},
});
}),
// Mutation endpoint
createData: t.procedure
.input(z.object({
workUnitId: z.string(),
organizationId: z.string(),
data: z.any(),
}))
.mutation(async ({ input }) => {
return await prisma.myPluginData.create({
data: {
workUnitId: input.workUnitId,
organizationId: input.organizationId,
data: input.data,
},
});
}),
});
import { myPluginRouter } from './server/router';
export const myPlugin = definePlugin({
slug: 'my-plugin',
name: 'My Plugin',
version: '1.0.0',
// Register server router
serverRouter: myPluginRouter,
extensions: [/* ... */],
});
import { trpc } from '@/lib/trpc/client';
export function MyComponent({ workUnitId }: { workUnitId: string }) {
const { data, isLoading } = trpc.myPlugin.getData.useQuery({
id: workUnitId,
organizationId: 'org-123',
});
const createMutation = trpc.myPlugin.createData.useMutation({
onSuccess: () => {
// Invalidate and refetch
trpc.myPlugin.getData.invalidate();
},
});
if (isLoading) return <Loader />;
return (
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<Button onClick={() => createMutation.mutate({ /* ... */ })}>
Create
</Button>
</div>
);
}
  • Always validate inputs with Zod schemas
  • Use organization ID for multi-tenancy
  • Handle errors gracefully
  • Invalidate queries after mutations
  • Use transactions for multi-step operations