The three entities
The distinction matters for integrations in one specific way:
code is unique per organization, email is unique globally. Reconciling against an external system by employee code is safe within one organization and ambiguous across several.
Your key is org-scoped
An API key belongs to an organization. Every request under it is confined to that organization’s data, and there is no parameter that changes which organization you are reading. To integrate with two organizations, hold two keys.Isolation is enforced by the database
Tenant scoping is not a convention that every query is expected to remember. It is enforced by row-level security in PostgreSQL: every request runs inside an organization context, and a query with no context returns zero rows rather than everything. Two consequences you can rely on:Cross-org reads return nothing
Not “forbidden” — nothing. The rows are not visible to your session at all.
A bug fails closed
A missing organization context produces an empty result or a rejected write, never a leak.
What that means for your error handling
Identifiers in practice
1
Store the employee UUID, not the code
The
id is stable. The code is an organization-assigned business key that an administrator can change.2
Match on code only when you must
Reconciling against an external HRIS usually means matching on
code, because that is what both systems share. Do it once, then store the UUID mapping.3
Never assume email identifies an employee
Email identifies the person, who may hold memberships in several organizations. Within one organization it is effectively unique, but it is not the key.
Organization switching
A person belonging to several organizations switches between them without re-authenticating — the session changes which membership it is acting as.This affects interactive sessions only. It has no bearing on API keys, which are bound to one organization and cannot switch.