AlphaAlpha Docs

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

  1. 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.
  2. 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's tenantId identifies the tenant it belongs to.
  3. X-Tenant-Id header — for every follow-up call (start/status/upload/finish/fail, project lookup, /tenants/me, blob downloads, …) the worker sends the job's tenant as an X-Tenant-Id header. 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.
  4. Job dispatch — the daemon passes the job's tenantId to 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

  1. 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"] }
    }
  2. Put the key in the worker machine's ~/Alpha/settings.json as usual (apiKey / productionApiKey / …). No other daemon configuration is needed — the tenantId setting is now only a fallback for manual (non-job) runs.

  3. 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/me with 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.

On this page