Skip to main content
Cactal has two invitation flows: organization membership for your team, and website-scoped editors for clients who should see only their website.

Prerequisites

Choose the flow

The owner role is not invitable; ownership moves only through a member-role update performed by the current owner. See Access control for the capability each role carries.
1

Invite a teammate to the organization

POST /v1/organizations/{organizationId}/invitations emails an invitation. role defaults to full_editor when omitted; invitations expire after 48 hours unless you pass expiresAt.
Invite an admin
Response
A pending invitation for the same email returns 409; pass "resend": true to cancel it and issue a fresh one. The response always includes the acceptance url. To deliver the link yourself — for example from an agent — pass "sendEmail": false, which creates the invitation without emailing the recipient.The recipient accepts from the email and becomes a member with the invited role. Adjust roles later with PATCH /v1/organizations/{organizationId}/members/{memberPrincipalId} (body { "role": "..." }); assigning owner requires the current owner.
2

Invite a client to one website

This is the agency pattern: the client gets access to their website and nothing else. POST /v1/websites/{websiteId}/editors takes an email and a website role — full or content.
Invite a client as a content editor
The response depends on whether the email already has a Cactal account:
Response when the email is new
  • "status": "pending" — an invitation email was sent; it expires after 48 hours by default.
  • "status": "granted" — the account exists, so the editor grant was applied immediately; the response includes the grant.
  • "status": "already_inherited" — that person is already an organization member and inherits access from their organization role.
A content editor manages CMS items and assets on that website. A full editor also edits source code and publishes. Neither can see other websites, organization settings, members, or API keys.After accepting, the client lands directly on the shared website. It appears in their dashboard’s unified Sites list alongside any sites they already have, under a “Shared with you” sidebar group; clients without an organization of their own get the same Sites page with a “Recently opened” group. In the API, GET /v1/websites?scope=shared returns exactly this shared set.
3

Grant or change access directly

When you already know a person’s principal id — for example from the editors list — set their role without an email round-trip:
Upsert a direct editor grant
Response
The call is an upsert — repeat it with a different role to change access. Granting to an existing organization member returns 400, because members already inherit website access from their organization role.
4

Remove access and cancel invitations

Remove a website editor:
Remove an editor
Access ends immediately; a missing grant returns 404. The same endpoint cancels a pending website invitation: pass { "invitationId": "..." } instead of principalId. Get that id from GET /v1/websites/{websiteId}/editor-invitations?status=pending. Organization invitations cancel with POST /v1/organizations/invitations/{invitationId}/cancel; list their ids with GET /v1/organizations/{organizationId}/invitations?status=pending. Remove an organization member with DELETE /v1/organizations/{organizationId}/members/{memberPrincipalId}.
5

Verify who has access

List website editors
List pending website invitations
List pending organization invitations
The editors endpoint and each invitation endpoint return { "items": [...], "nextCursor": "..." | null }. An editor entry looks like { "principalId": "...", "role": "full" | "content", "name": "...", "email": "...", "createdAt": "..." }. Pass nextCursor back as cursor until it is null; use status=all to retrieve accepted and canceled history as well as pending invitations. Organization members remain separate at GET /v1/organizations/{organizationId}/members.
Every grant, invitation, and removal is recorded in the organization’s audit log.

Troubleshooting

Next steps