Handlers / remote functions
Handlers (also called remote functions in older docs) are typed server entrypoints authored in tenant workspace source. They run in the pod runtime with the same collection API and request scope as hooks and automations.
remote/*.handler.ts and register through invoke: on defineWorkspace. Core's internal remote_functions/*.remote.ts and defineRemoteQuery are host-only — do
not use them in tenant templates.Source layout
remote/
├── holiday.handler.ts # defineQueryHandler
└── notify.handler.ts # defineCommandHandler Definition
Import defineQueryHandler or defineCommandHandler from @norbital-ai/pod/authoring. Query handlers are read-only; command handlers may mutate
via the handler api argument.
import { defineQueryHandler } from '@norbital-ai/pod/authoring';
import { z } from '@norbital-ai/pod/zod';
export const holidayFeed = defineQueryHandler({
schema: z.object({ country_code: z.string() }),
handler: async ({ country_code }, api) => {
// read collections via api, call external services, return typed output
return { country_code, holidays: [] };
}
}); Registration
Export handlers from workspace.api.ts under invoke: when calling defineWorkspace:
const { api, ws } = defineWorkspace(schema, {
collections: [/* … */],
invoke: {
holidayFeed,
computeEntitlements: computeEntitlementsRemote
},
automations: [statutoryDriftCheck]
});
export { api, ws }; The invoke key becomes the client method name. Tenant apps import api from workspace
source and call:
const result = await api.invoke.holidayFeed({ country_code: 'SG' }); Workspace Studio
Registered handlers appear in Workspace Studio → Manifest → Handlers with a function-square icon. Use Manifest to confirm registration without opening each
source file.
When to use handlers
- Integrations that do not map cleanly to collection CRUD
- Aggregations or reports that span multiple collections
- Server actions invoked from tenant apps via
api.invoke
Prefer collection hooks for mutation side effects, automations for scheduled or background work, and SDK collection reads for UI data — handlers when you need a dedicated typed server entrypoint.