Tenant resolution: the Host header
The tenant is resolved from the HTTP Host header of the incoming request. Each organization has either a subdomain on orgo.space or a fully-custom domain:
The OpenAPI spec lists
https://app.orgo.space as the base URL only because the API playground needs some URL. For real requests, swap that for your tenant’s host.Why this matters for tokens
Tokens are tenant-scoped at the moment they are issued:- Api-Token: tied to the user who created it; that user belongs to one tenant; the token only works against that tenant’s host.
- JWT (from
/login-checkor/verify-login-otp): contains asession_idclaim bound to the tenant of the host the login was performed against. - OAuth access tokens: bound to the tenant where the OAuth application was registered.
401 Unauthorized.
Cross-tenant access is blocked at the persistence layer
Inside Orgo’s backend, Doctrine extensions automatically addWHERE entity.tenant = current_tenant to every read. Even if a developer wrote SELECT * FROM users without a tenant filter, the extension would inject the filter before the query runs. This is enforced at the ORM level so no API endpoint can leak across tenants.
The one exception is OTP-issued JWTs used by the event-app surface (members opening an event landing page from a different tenant they were invited to). Those JWTs carry an auth_strength: OTP claim and a verified_email instead of a session_id, and they can cross tenants but only for the event-attendance endpoints.
Resolving your tenant host
Every tenant admin can find their host in the admin UI under Settings → Organisation → Domains. Common shapes:
The default subdomain always works, even when a custom domain is also configured. Use it for integrations to avoid breakage if the admin changes the custom-domain setup.
What happens when the tenant is missing or wrong
The 404 in the last row is intentional. From outside, “not found” and “exists in another tenant” are indistinguishable. This is the same pattern GitHub uses for private repos.
Tenant context in webhook deliveries
Webhook payloads carry a top-leveltenant_id field so a single receiver subscribed to multiple tenants can route events. See Webhooks.
Common scenarios
I'm getting 401 errors with a valid-looking token
I'm getting 401 errors with a valid-looking token
Check that the host you are calling matches the tenant the token was issued for. The same token against the wrong host produces 401, not 403.
I want one integration to serve many tenants
I want one integration to serve many tenants
Generate one Api-Token per tenant (each from an admin user in that tenant) and route by hostname server-side. There is no “super-token” that crosses tenants.
The tenant's admin changed the custom domain — my integration broke
The tenant's admin changed the custom domain — my integration broke
Switch to the
*.orgo.space default subdomain. It is permanent and never changes.Can I look up a tenant's host programmatically?
Can I look up a tenant's host programmatically?
Yes —
GET /api/v1/tenant-host/{slug} returns the current canonical host for a tenant slug. This endpoint is public (no auth needed).Related
- Authentication — how tokens carry tenant scope
- Errors — what each tenant-mismatch error looks like

