Let members run their user organization
A user organization is a group of your users that holds access for its members, such as an employer that buys
seats for its staff. Staff open one and seat its first admin in the console; see
User organizations. From then on, its own owners and admins run it from your
site, through /v1/org/*. What a seat gives access to is a grant the organization holds; see
Subscriptions for selling one.
Every /v1/org/* route acts as the signed-in user and needs their session. The routes answer at edgekit_only and
dual sites, and 404 not_found at an external_only site. The browser client’s org methods wrap them; see
createClient and the
Organizations operations.
| Role | Can |
|---|---|
owner |
Everything an admin can. The last owner cannot leave. |
admin |
Invite and remove members, change roles between admin and member, cancel invitations, list seat refusals, rename the organization. |
member |
Read the organization and its members, and leave. |
owner cannot be given through /v1/org/update-member-role, which takes admin or member only. A role changes
what a person can manage, never what they can read: the organization’s grants reach every seat.
Invite someone
Section titled “Invite someone”-
An owner or admin sends the invitation, with the role it offers:
Terminal window curl -X POST https://your-tenant-host/v1/org/invite-member \-H 'x-edgekit-site-id: site_example' \-H 'Authorization: Bearer <session-token>' \-H 'content-type: application/json' \-d '{"email": "grace@example.com", "role": "member"}'EdgeKit emails the invitee:
You've been invited to join <organization>, telling them to sign in to accept. The email carries no link. It goes out under your transactional mail settings, like sign-in emails. -
The invitee signs in on your site with that address. Your page lists their invitations with
GET /v1/org/list-user-invitations. -
The invitee accepts with
POST /v1/org/accept-invitationand the invitation’sinvitationId, or declines withPOST /v1/org/reject-invitation.
const site = { 'x-edgekit-site-id': 'site_example' };
const { invitations } = await fetch('/edgekit/v1/org/list-user-invitations', { credentials: 'include', headers: site,}).then((response) => response.json());
const accepted = await fetch('/edgekit/v1/org/accept-invitation', { method: 'POST', credentials: 'include', headers: { ...site, 'content-type': 'application/json' }, body: JSON.stringify({ invitationId: invitations[0].id }),});Accepting takes the seat and makes the organization the user’s active one. It is refused unless the user signed in with the address the invitation went to, and that address is verified, so an invitation cannot be claimed by someone else.
- An invitation expires after 48 hours. Send a new one after that.
- A user organization holds at most 50 pending invitations at once.
- Inviting an address that already has a pending invitation replaces it with a new one, with a new id. Set
resendto choose whether the email goes out again. - An outstanding invitation holds no seat. The seat ceiling is checked when it is accepted.
When the organization is full
Section titled “When the organization is full”Accepting answers 403 seat_limit_reached, This organization has no free seats., when the organization has no
free seat. EdgeKit records the person as a seat refusal, as it does for someone refused a seat through an
auto-join domain. Owners and admins list them, most recent first, until each person holds a seat:
curl 'https://your-tenant-host/v1/org/list-seat-refusals?organizationId=01926f3a-8b4e-7b33-a944-5e6f7a8b9c0d' \ -H 'x-edgekit-site-id: site_example' \ -H 'Authorization: Bearer <session-token>'Anyone else gets 404 not_found. For how the ceiling is set, see
Seats and the seat limit.
Manage members
Section titled “Manage members”- List members:
GET /v1/org/list-members, paged withlimitandoffset. Each member carries their role, when they joined, and the user’s id, email and name. - Change a role:
POST /v1/org/update-member-rolewith thememberIdandrole. - Remove a member:
POST /v1/org/remove-memberwithmemberIdOrEmail. The seat is free at once. The removed user keeps their own record and their own grants. Decide can keep reading the organization’s access from their access cookie for up to an hour after it was last refreshed; see How quickly an ended session stops working. - Leave:
POST /v1/org/leavewith theorganizationId, by the member themselves. - Rename:
POST /v1/org/updatewithname, up to 200 characters, and optionallylogo;logo: nullclears it. The slug cannot change.
Remove, leave, accept and reject cannot be retried after they succeed: the member or the invitation is gone.
The active organization
Section titled “The active organization”A user can belong to several user organizations. POST /v1/org/set-active with an organizationId makes one active
for the session, and the routes above that take an optional organizationId act on it when none is sent. null clears it, and the user acts
for themselves again. GET /v1/org/get-active-member answers the user’s own membership in it, which is what a page
reads to decide whether to show team management at all.
Your site’s users cannot create or delete a user organization: it exists because seats were bought.