Private betaZynth Auth is currently in private beta testing.New organizations are created by invitation only, and no plan can be purchased yet.Request early access

Team members & invitations

Every tenant starts with one person: the owner who signed up. This guide covers the invitation flow that brings the rest of the team in, and the member-management API that governs them afterwards. (If your organization provisions users from an identity provider, see SCIM provisioning — the two coexist, and SCIM-managed members are the IdP's to change, not the console's.)

Getting 403 on everything here, in a brand-new organization? If your organization was opened for you by an AI agent, it stays quarantined until you approve the setup on the verification page — invitations, roles and member domains are all refused until then, with that reason in the message. Approving lifts it immediately. See Agent-driven onboarding.

Inviting a teammate

POST /api/v1/members/invites (requires the members:manage permission):

{ "email": "teammate@example.com", "role": "admin" }

The teammate receives an email with a single-use acceptance link, valid for 7 days. The invitation carries the role you chose — any system role except two:

  • owner can never be granted by invitation. Ownership transfer is a separate, deliberate operation (not yet available).
  • customer is the end-user population's role, never a workforce grant.

Re-inviting the same email re-issues the invitation: the previous link stops working, the expiry restarts, and the role is updated to whatever you chose the second time. A pending invitation counts toward your plan's member limit — seats can't be stockpiled past the plan by leaving invitations open.

Revoke a pending invitation with DELETE /api/v1/members/invites/{invite_id}; the emailed link dies immediately.

Accepting

The link opens an acceptance page showing the organization, the role, and the invited email. A new user sets a password and lands signed in (we suggest adding a passkey right away); an invitee who already has a Zynth Auth account signs in first and confirms — the invitation only works for the exact email it was sent to.

Domain auto-join (optional)

If your whole team shares an email domain, you can skip per-person invitations:

  1. POST /api/v1/members/domains with {"domain": "acme.com"} — the response contains a zynth-verify=… value.
  2. Publish it as a TXT record on the domain, then POST /api/v1/members/domains/{id}/verify.
  3. Turn on the tenant setting members.domain_join_enabled (it is off by default).

From then on, anyone with a matching email address can join Acme through the API's join call (there is no "join Acme" prompt on the sign-up page today — the door is API-only), and they land as a baseline member — elevation stays a human decision made afterwards. The proof is re-checked continuously: if the TXT record disappears, the door closes by itself. Public email providers (gmail.com and friends) can never be claimed, and only one organization can hold a domain verified at a time.

Managing members

  • GET /api/v1/members (members:read) — every workforce member, their role, status, and whether they are SCIM-managed.
  • PATCH /api/v1/members/{membership_id} (members:manage) — change a member's role.
  • DELETE /api/v1/members/{membership_id} (members:manage) — remove a member. Removal is immediate and total: the membership ends and every session the member had is revoked in the same operation — there is no window where a removed member's open tab keeps working.

The guardrails

Three refusals you will eventually be glad of:

  • The sole owner can neither be removed nor demoted. A tenant can never be left with nobody who can administer it. Add a second owner-capable admin before offboarding the first.
  • An invitation whose role breaks your own separation-of-duties rule is refused at the moment it is accepted, naming the rule. The invitation is not used up: reassign the conflicting role (or grant an override through an access request decided by a second approver) and the same link still works. Before v0.33 this refusal was applied to the access but not to the invitation — the person joined with baseline access while this list displayed the role they were invited to.
  • SCIM-managed members are refused here with a clear error — changing them in the console would silently fight your IdP's next sync. Change them at the IdP.
  • Every action is audited and monitored. Invitations, acceptances, role changes and removals land in the tamper-evident audit log with SOC 2 / ISO 27001 control mappings, and anomaly detection watches for the ugly patterns (invite floods, token guessing, mass removals) out of the box.