Cross-Tenant Worker
Run one worker daemon for all tenants with a cross-tenant API key
Cross-Tenant Worker
By default an API key belongs to exactly one tenant: the worker daemon polling /jobs/next with
that key only ever sees that tenant's configuration jobs. A cross-tenant worker key lifts that
restriction so a single daemon + Revit machine can serve the job queues of all active tenants.
How it works
- Cross-tenant API key — an API key created with
isCrossTenant: true. Only super admins can create one (POST /api-key). It still has a home tenant (the creator's organization), which applies whenever no tenant header is sent. - Queue scan across tenants — when a cross-tenant key polls
GET /jobs/next, the backend scans the house, block, and option-sales queues of all tenants and returns the highest-priority job. The job payload'stenantIdidentifies the tenant it belongs to. X-Tenant-Idheader — for every follow-up call (start/status/upload/finish/fail, project lookup,/tenants/me, blob downloads, …) the worker sends the job's tenant as anX-Tenant-Idheader. The backend validates the tenant (must exist and be active) and runs the request in that tenant's context — including tenant settings such as coordinate system, Revit template, and default Revit version.- Job dispatch — the daemon passes the job's
tenantIdto the Revit add-in over the named pipe (configure,configure-block,configure-option-sales). The add-in keeps it as the ambient job tenant and stamps all of its own API calls with the same header until the job ends.
Regular (single-tenant) keys are rejected with 403 if they send an X-Tenant-Id other than
their own tenant, and unknown or inactive tenants are rejected with 400. Every applied override
is audit-logged on the backend.
Setting it up
-
As a super admin, create a cross-tenant API key:
POST /api-key { "daysTillExpiration": 365, "name": "revit-worker-fleet", "isCrossTenant": true, "permissions": { "configuratorPermissions": ["READ_QUEUEJOBS"] } } -
Put the key in the worker machine's
~/Alpha/settings.jsonas usual (apiKey/productionApiKey/ …). No other daemon configuration is needed — thetenantIdsetting is now only a fallback for manual (non-job) runs. -
Restart the AlphaWorkerDaemon. The log line
Claimed <TYPE> job <id> (tenant=<tenantId>)confirms per-job tenant resolution is active.
Notes
- Manual runs in Revit (UI or CLI dispatch without a job) are unaffected: no job tenant is set, so calls run against the key's home tenant exactly as before.
- Revit versions per tenant still resolve per job:
project.revitVersion→ tenant default (/tenants/mewith the job's tenant) → daemon settings. - Heartbeat/registration still registers the agent under the tenant from local settings; the queue agent list shows which machine ran which job via worker events on the job itself.