Members & onboarding
A member is one person on your workforce roster. You add members three ways — one at a time in
the portal, by CSV upload, or over the Organization API
(addMembers()). Each member you add gets a stable member id vmem_… — store it against your
own employee/user record; it’s your correlation key between your roster and Valyd.
How a member is invited
When you add someone, Valyd issues an invite. The method depends on the role, and you can force
it with the invite option on add member(s):
invite | What happens |
|---|---|
auto (default) | Valyd picks the right link for the role. A workforce member (role: member) gets a face-activation link — they scan their face once to bind the membership to a real Valyd identity. An admin or developer gets an email claim link to join the console. |
email | Force the email path — an email claim/activation link is sent. |
face | Force the face-activation path — a face link is issued for the person to scan. |
By default (notify: true) Valyd emails the link for you. Pass notify: false and each created
member comes back with its own activation_link in the API response so you can deliver it yourself
(your own email / SMS / in-app message). Note: activation_link is returned only for face
invites — email/claim links are emailed, never handed back.
How a new member is notified
Adding a member (portal, CSV, or addMembers()) emails them their invite link — for the workforce,
a face-activation link. They tap it, scan their face once, and their membership is bound to a
real Valyd identity. Prefer to deliver it yourself? Pass notify: false and read each created
member’s activation_link. Re-send anytime with
resendMemberInvite(memberId). To know when someone
finished, poll getMembers() and watch for
status: "active".
Member lifecycle (status)
A membership moves through exactly four states:
status | Meaning | Billable? |
|---|---|---|
invited | Created, no email sent yet (the notify: false path). | No |
link_sent | Activation email sent, awaiting the person. | No |
active | Face-activated and bound to a Valyd identity. | Yes — the only billable state |
deactivated | Removed from the workforce; app logins revoked, row kept. | No |
Only the active state is billable — a seat turns on the moment the member scans their face.
See Pricing & billing.
Deactivate, remove, reactivate
- Deactivate —
deactivateMember(memberId)stops billing and revokes the member’s app logins, but keeps the row. Their Valyd identity is not deleted. - Remove —
removeMember(memberId)is the same deactivation by default; pass{ permanent: true }to delete the membership row outright, so the email can be re-invited cleanly. The person’s Valyd account is never deleted. - Reactivate —
reactivateMember(memberId)restores a deactivated member toactiveif their Valyd identity still exists, or back toinvited(they must re-activate by face) if it doesn’t. - Re-send an invite — if a member’s invite expired before they connected their Valyd ID,
resendMemberInvite(memberId)issues and emails a fresh face-activation link (and returns it), superseding the old one. It refuses for already-active or deactivated members.
None of these ever touch the person’s Valyd identity or their membership in any other organization.
Only member-role people appear on the roster — use
resolveMember({ valydId }) to check whether someone
is a workforce member vs a developer/admin, or not in your org at all.
In the Developer Portal, the org owner/admin sees the full roster with each member’s status on the
Organization → Members tab, and can re-send invites, deactivate/reactivate, or Remove a
member outright (permanent, same as the API’s permanent: true).
Account recovery
If a member is locked out of your app — they forgot the email/password they sign in with — you
don’t delete the seat or its history. You start an identity-backed recovery: Valyd re-verifies
the person (liveness + a face match against their enrolled face, plus a fresh document/KYC scan on
the with_id variant) and returns a pass/fail to your Verify project’s webhook. Valyd always
emails the verification link to the member’s on-file address. On a pass, your app lets them set a
new password — Valyd stores and sets nothing.
await client.startAccountRecovery({ valydId: "valyd_…", variant: "with_id" });See Account recovery for the full flow, the
startAccountRecovery / bindMember functions, their responses, and the webhook contract.