Skip to main content

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

A 404 does not prove an ID is invalid. An ID belonging to another organization produces exactly the same 404 as one that does not exist anywhere.This is deliberate: distinguishing them would confirm the record exists. Do not build logic that treats 404 as “this ID is malformed” — treat it as “not available to this credential”.

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.