Organisation invites
Invite members by email with a first-password hosted flow, optional Wocha mail, or your own email template
Invite a person by email. Wocha finds or creates their identity, adds them to the organisation, and issues a first-password link (not a “forgot password” email). You can let Wocha send a branded “You’ve been invited” message, or skip Wocha mail and put the action URL in your own product email.
Do not overload POST /users/:id/recovery as the invite API, and do not send invitees to a product-owned MFA enrolment page. TOTP on this path is hosted Wocha MFA.
When to use which API
| Goal | API | |
|---|---|---|
| Invite someone into an organisation | POST /v1/organisations/{id}/invites | Wocha invite_link template, or your own mail with action_url |
| Reset password for an existing user | POST /v1/users/{id}/recovery | Wocha recovery_link template, or silent send: false |
| Add an identity that already exists | POST /v1/organisations/{id}/members | None — membership only |
Required scope: organisations:write for invites; users:write for recovery.
Flow
- Your backend calls the invite endpoint with the person’s email and role.
- Wocha creates the identity if needed and writes organisation membership immediately.
- If they have no password,
action_urlis a hosted/invitemagic link (24 hours). If they already have a password,action_urlis hosted/loginwith the org andreturn_toattached. - On
/invitethey set a password. Whenrequire_mfais true (the default), they enrol TOTP before leaving Auth. - Auth then honours
return_to— this should be your product OAuth start URL, not an unauthenticated org home page.
Invite with Wocha email
send defaults to true. Wocha sends the invite_link template via Resend.
If Resend fails after membership and the link already exist, the API still returns 201 with action_url and emailed: false. Retry mail yourself from that URL rather than treating it as a failed invite.
Full field list: Organisation invite API.
Invite with your own email (send: false)
Products that already send invite copy must pass send: false. Wocha does not email. Put action_url in your template.
Never send two emails. If send is omitted, Wocha mails by default.
Provider-branded invites
If your product sells into other organisations (a vendor inviting staff into a
customer's organisation), pass branding_org_id so the invite email, the
hosted invite page and the invitee's later auth mail carry your brand while
membership stays on the customer's organisation:
Both organisations must belong to your tenant; anything else is a 400. The
branding organisation supplies the invite_link template, logo and colours,
custom From sender and the org_id branding hint on the hosted pages. The
invited organisation still supplies {{ .OrganisationName }}. The response
includes branding_org_id when it differs from the path organisation.
For a standing default, set metadata.email_branding_org on the customer's
organisation instead (Console or PATCH /organisations/{id}); every invite into
it, and every courier email to its members, then uses that brand.
Hosted invitee experience
| Situation | Where they land | After password |
|---|---|---|
| New identity, no password | https://id.wocha.ai/invite?flow=&token= | TOTP enrolment when require_mfa is true, then return_to |
| Existing identity with a password | https://id.wocha.ai/login?org_id=&return_to= | Normal sign-in, then return_to |
The invite page sets cookies (auth_invite_pending, auth_flow_return_to, org branding) then completes the magic link on the Auth origin so the session cookie is scoped to id.wocha.ai.
TOTP on this path is Wocha MFA. Complete it on hosted Auth; do not send the invitee to a product-owned MFA settings screen.
return_to
return_to must be https on an allowlisted origin. After the user has a session, send them to the URL that starts OAuth in your app (BFF /api/auth/login, /auth/login, and so on). Hydra can then skip a second login and land them in the product.
Do not use:
- The organisation home page if it is not an OAuth entrypoint
- Product-owned MFA enrolment URLs
If return_to is missing or not allowlisted, the API returns 400 with return_to must be an https URL on an allowlisted application origin. Ask Wocha to add your production and staging origins to RECOVERY_ALLOWED_RETURN_URLS.
Password recovery (not invites)
Use recovery when the identity already exists and you only need a set-password link.
Hosted recovery links go to https://id.wocha.ai/recovery?flow=&token=&return_to=&org_id=. Auth persists return_to and org branding in cookies before completing the token, same pattern as invites.
See User recovery API.
Webhooks and audit
| Event | When |
|---|---|
user.created | Invite created a new identity (source: customer_api.invite) |
organisation.member_added | Membership written (invited: true on this path) |
Audit customer_api.org.invited | Invite succeeded (including when Wocha mail was skipped or failed) |
Subscribe to organisation.member_added if your product keeps a local membership table. See the webhook event catalogue.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | validation_error | Missing email, invalid role, or return_to not allowlisted |
401 | unauthorized | Missing or invalid API key |
403 | forbidden | Token lacks organisations:write |
404 | not_found | Organisation (or recovery identity) not found |
409 | conflict | Email already belongs to another tenant |
429 | quota_exceeded | User / MAU quota when creating a new identity |
Membership is written before mail. A mail-provider outage does not roll back the invite.