Tenant API
The tenant router manages the current tenant's profile and settings. Every authenticated user belongs to an organization (tenant) resolved from their Clerk session.
Router namespace: tenant
Source: src/server/trpc/routers/tenant.ts
Procedures
| Procedure | Type | Access | Description |
|---|---|---|---|
getCurrent | query | tenant | Get the current tenant record |
updateSettings | mutation | admin | Update tenant settings |
getCurrent
Returns the full tenant record for the authenticated user's organization. The tenant is resolved from the Clerk orgId via the hasTenant middleware.
tenant.getCurrent.queryOptions()
Input
None.
Response
{
"id": "tenant_789",
"clerkOrgId": "org_abc123",
"name": "Acme Corporation",
"slug": "acme-corp",
"plan": "professional",
"settings": {
"defaultScoringInterval": "daily",
"notificationsEnabled": true,
"timezone": "America/New_York"
},
"createdAt": "2026-01-15T08:00:00.000Z",
"updatedAt": "2026-03-05T10:00:00.000Z"
}
Returns null if the tenant record cannot be found (this should not occur under normal conditions since the middleware auto-provisions tenants).
Example
import { useTRPC } from "@/lib/trpc";
import { useQuery } from "@tanstack/react-query";
function TenantHeader() {
const trpc = useTRPC();
const { data: tenant } = useQuery(trpc.tenant.getCurrent.queryOptions());
return (
<header>
<h1>{tenant?.name}</h1>
<span className="badge">{tenant?.plan}</span>
</header>
);
}
updateSettings
Updates the tenant's settings object. Accepts a free-form JSON record that replaces the existing settings.
tenant.updateSettings.mutationOptions(options)
Access: Admin only
Input
| Field | Type | Required | Description |
|---|---|---|---|
settings | Record<string, unknown> | Yes | New settings object (replaces existing) |
Response
Returns the updated tenant record:
{
"id": "tenant_789",
"clerkOrgId": "org_abc123",
"name": "Acme Corporation",
"slug": "acme-corp",
"plan": "professional",
"settings": {
"defaultScoringInterval": "weekly",
"notificationsEnabled": false,
"timezone": "America/Los_Angeles"
},
"createdAt": "2026-01-15T08:00:00.000Z",
"updatedAt": "2026-03-05T12:00:00.000Z"
}
The settings field is replaced entirely, not merged. Always include all settings keys when updating to avoid losing existing values.
Example
const trpc = useTRPC();
const queryClient = useQueryClient();
const mutation = useMutation(
trpc.tenant.updateSettings.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: trpc.tenant.getCurrent.queryKey(),
});
},
})
);
// Read current settings first, then merge
const currentSettings = queryClient.getQueryData(
trpc.tenant.getCurrent.queryKey()
)?.settings ?? {};
mutation.mutate({
settings: {
...currentSettings,
defaultScoringInterval: "weekly",
},
});
Always read the current settings before updating to avoid accidentally overwriting existing values. The pattern above shows how to merge new settings with existing ones.
Tenant Schema
The tenant record contains these fields:
| Field | Type | Description |
|---|---|---|
id | string | Internal tenant identifier (UUID) |
clerkOrgId | string | Clerk organization ID |
name | string | Organization display name |
slug | string | URL-safe organization slug |
plan | string | SaaS plan tier |
settings | Record<string, unknown> | Free-form tenant settings |
createdAt | Date | Tenant creation timestamp |
updatedAt | Date | Last update timestamp |
Related Pages
- Authentication -- How tenants are resolved from Clerk sessions
- Audit API -- Track settings changes in the audit log
- tRPC Overview -- Client setup and procedure types