acme) and a
display name. A member is one of your own users, by the id you already
identify them with.
The whole setup
1
Name a tenant when you identify a user
Your existing identify call gains one field. The first time a project names a
tenant it does not have, Vendo creates it — the display name starts as the id,
and you rename it in the console.It only ever ADDS. It never removes a membership and never changes a role.
2
Leave `memberships` unset
With
VENDO_API_KEY set and no auth.memberships of your own, the SDK asks the
directory and caches the answer for 60 seconds per user. Everything downstream
is code you already have.If you DO set auth.memberships, your answer wins and the directory is never
called. That is the whole rule.3
That's it
Shared apps,
/orgs/<id>/** workspaces, org policy and the org:<id> limiter
pool all read the same memberships they always did.Caps
Each tenant gets messages/day and generations/month, set in the console. Both reset on the calendar boundary in UTC — the start of the current UTC day and of the current UTC month — not on a rolling lookback, so “for today” is true. Every cap carries a scope:
The project sets defaults; a tenant can override them. A cap you set explicitly
in
createVendo({ limits }) wins over both.
API reference
Reads take your ordinary runtime key. Writes take an admin-scoped key: a runtime key ships inside every deployment of your product, and rearranging who is in which company from it is the same class of power the admin scope already fences.
Tenant writes need the Teams plan. Reads and identify never do — a
downgrade freezes the directory, it does not break your product.
What happens when Cloud is down
The SDK serves the last answer it had, or none. Your product keeps serving; for that window a tenant cap is not enforced and tenant-shared apps are briefly invisible. Removal is the direction that waits: a member you took off the roster keeps matchingorg: grants until Cloud answers again.