Skip to main content

Overview

The cloud tRPC API (packages/trpc/src/) provides server-side procedures for user management, organizations, integrations, and cloud sync. Root Router: packages/trpc/src/root.ts:17
export const appRouter = createTRPCRouter({
  admin: adminRouter,
  agent: agentRouter,
  apiKey: apiKeyRouter,
  analytics: analyticsRouter,
  chat: chatRouter,
  device: deviceRouter,
  integration: integrationRouter,
  organization: organizationRouter,
  project: projectRouter,
  task: taskRouter,
  user: userRouter,
  workspace: workspaceRouter,
});

export type AppRouter = typeof appRouter;

Procedure Types

Defined in packages/trpc/src/trpc.ts:33:

publicProcedure

No authentication required.
export const publicProcedure = t.procedure;

protectedProcedure

Requires valid session.
export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
  if (!ctx.session) {
    throw new TRPCError({
      code: "UNAUTHORIZED",
      message: "Not authenticated. Please sign in.",
    });
  }
  return next({ ctx: { session: ctx.session } });
});

adminProcedure

Requires admin email domain (e.g., @superset.sh).
export const adminProcedure = protectedProcedure.use(async ({ ctx, next }) => {
  if (!ctx.session.user.email.endsWith(COMPANY.EMAIL_DOMAIN)) {
    throw new TRPCError({
      code: "FORBIDDEN",
      message: `Admin access requires ${COMPANY.EMAIL_DOMAIN} email.`,
    });
  }
  return next({ ctx });
});

User Router

Source: packages/trpc/src/router/user/

user.get

none
void
Get current authenticated user
user
User
Example:
const { data: user } = api.user.get.useQuery();

Workspace Router (Cloud)

Source: packages/trpc/src/router/workspace/workspace.ts:16

workspace.ensure

Upsert project and workspace in a transaction.
organizationId
string
required
Organization UUID
project
object
required
Project details
workspace
object
required
Workspace details
result
object
projectId
string
Created/existing project UUID
workspaceId
string
Created/existing workspace UUID
txid
string
Transaction ID
Example:
const result = await api.workspace.ensure.mutate({
  organizationId: 'org-123',
  project: {
    name: 'My Project',
    slug: 'my-project',
    repoOwner: 'acme',
    repoName: 'app',
    repoUrl: 'https://github.com/acme/app',
    defaultBranch: 'main'
  },
  workspace: {
    id: 'ws-123',
    name: 'feature-auth',
    type: 'worktree',
    config: { branchName: 'feature/auth' }
  }
});

workspace.create

projectId
string
required
Project UUID
organizationId
string
required
Organization UUID
name
string
required
Workspace name
type
'worktree' | 'main'
required
Workspace type
config
object
required
Workspace configuration
Returns: Created workspace object

workspace.delete

id
string
required
Workspace UUID
organizationId
string
required
Organization UUID (for authorization)
Returns: { success: true }

Integration Router

Source: packages/trpc/src/router/integration/ Supports GitHub, Linear, and Slack integrations.

GitHub Integration

integration.github.listRepos

organizationId
string
required
Organization UUID
Returns: Array of accessible GitHub repositories

integration.github.createWebhook

organizationId
string
required
Organization UUID
repoOwner
string
required
Repository owner
repoName
string
required
Repository name
events
string[]
required
Webhook events (e.g., ['push', 'pull_request'])

Linear Integration

integration.linear.listIssues

organizationId
string
required
Organization UUID
teamId
string
Filter by Linear team
Returns: Array of Linear issues

Slack Integration

integration.slack.sendMessage

organizationId
string
required
Organization UUID
channel
string
required
Slack channel ID
text
string
required
Message text

Device Router

Source: packages/trpc/src/router/device/ Manage multiple devices for multi-machine workflows.

device.list

organizationId
string
required
Organization UUID
Returns: Array of registered devices

device.register

organizationId
string
required
Organization UUID
name
string
required
Device name
platform
'mac' | 'windows' | 'linux'
required
Operating system
Returns: Created device object with API key

Task Router

Source: packages/trpc/src/router/task/

task.create

organizationId
string
required
Organization UUID
title
string
required
Task title
description
string
Task description
assigneeId
string
User UUID to assign

task.list

organizationId
string
required
Organization UUID
status
string
Filter by status
Returns: Array of tasks

Analytics Router

Source: packages/trpc/src/router/analytics/

analytics.track

event
string
required
Event name
properties
object
Event properties
Example:
await api.analytics.track.mutate({
  event: 'workspace_created',
  properties: {
    workspaceId: 'ws-123',
    projectId: 'proj-456'
  }
});

Usage Patterns

Client Setup (Next.js)

File: apps/web/src/trpc/react.tsx
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '@superset/trpc';

export const api = createTRPCReact<AppRouter>();

export function TRPCProvider({ children }: { children: React.ReactNode }) {
  const [queryClient] = useState(() => new QueryClient());
  const [trpcClient] = useState(() =>
    api.createClient({
      links: [
        httpBatchLink({
          url: '/api/trpc',
        }),
      ],
    })
  );

  return (
    <api.Provider client={trpcClient} queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    </api.Provider>
  );
}

Server Setup (Next.js App Router)

File: apps/web/src/trpc/server.tsx
import { createCaller } from '@superset/trpc';
import { auth } from '@superset/auth/server';

export const api = async () => {
  const session = await auth();
  
  return createCaller({
    session,
    auth,
    headers: new Headers(),
  });
};

React Component Usage

import { api } from '@/trpc/react';

function WorkspaceList() {
  const { data: workspaces, isLoading } = api.workspace.list.useQuery({
    organizationId: 'org-123'
  });
  
  const createWorkspace = api.workspace.create.useMutation({
    onSuccess: () => {
      console.log('Workspace created!');
    }
  });
  
  return (
    <div>
      {workspaces?.map(ws => <div key={ws.id}>{ws.name}</div>)}
      <button onClick={() => createWorkspace.mutate({
        organizationId: 'org-123',
        projectId: 'proj-123',
        name: 'New Workspace',
        type: 'worktree',
        config: {}
      })}>
        Create Workspace
      </button>
    </div>
  );
}

Server Component Usage (Next.js 15+)

import { api } from '@/trpc/server';

export default async function Page() {
  const caller = await api();
  const workspaces = await caller.workspace.list({
    organizationId: 'org-123'
  });
  
  return (
    <ul>
      {workspaces.map(ws => <li key={ws.id}>{ws.name}</li>)}
    </ul>
  );
}

Type Inference

import type { AppRouter } from '@superset/trpc';
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';

type RouterInputs = inferRouterInputs<AppRouter>;
type RouterOutputs = inferRouterOutputs<AppRouter>;

// Input type for workspace.create
type CreateWorkspaceInput = RouterInputs['workspace']['create'];

// Output type for workspace.list
type WorkspaceList = RouterOutputs['workspace']['list'];

Error Handling

import { TRPCError } from '@trpc/server';

try {
  await api.workspace.create.mutate({ /* ... */ });
} catch (error) {
  if (error instanceof TRPCError) {
    switch (error.code) {
      case 'UNAUTHORIZED':
        // Redirect to login
        break;
      case 'FORBIDDEN':
        // Show permission error
        break;
      case 'BAD_REQUEST':
        // Validate input
        break;
    }
  }
}

Next Steps

Desktop API

Electron IPC APIs for local operations

MCP Servers

Build custom MCP servers for AI agents