Skip to main content

Bulk-invite members via the API

Invite tens or hundreds of people into your organisation from your own backend (an HR system, an onboarding pipeline, a campaign tool) without clicking through the portal. Each invite is an access code. Whoever opens its accept link joins your organisation as a member, and the code can optionally start an assessment for them the moment they join.

Prerequisites​

  • An API client with these permissions:
    • access_codes:write to create and revoke invite codes
    • access_codes:read to list codes and their usage
    • tenant_methodologies:read to list your adopted methodologies
    • tags:read if you group invites (optional)
    • tenant_users:read to reconcile who joined (optional)
  • A bearer token minted from that client, as described in Authentication. The token carries every permission the client was granted, whichever single scope you name in the request. The examples below assume it is in $TOKEN.

Permissions are fixed for the life of a client. If an existing client lacks these, create a new one.

1. Pick a methodology​

If each new member should receive an assessment on arrival, the invite must name one of your organisation's adopted methodologies. Any other id is rejected with a 422.

curl "https://$WISELOOK_HOST/v1/adopted-methodologies" \
-H "Authorization: Bearer $TOKEN"
{
"items": [
{
"methodology_id": "009f91ce-…",
"name": "Eric One",
"version": "1.0",
"subscribed_at": "2026-07-27T06:04:24Z"
}
]
}

Use the methodology_id of your chosen methodology as assessment_methodology_id when creating the invite in step 4.

2. Group the campaign with tags (optional)​

Tags are your organisation's own labels (teams, departments, offices, cohorts), defined on the portal's Tags page. Attach them to an invite and everyone who joins through it is tagged on arrival, so a campaign lands pre-grouped for search, reporting and manager scoping.

curl "https://$WISELOOK_HOST/v1/tags" \
-H "Authorization: Bearer $TOKEN"
[
{
"id": "6f2d8a10-…",
"tenant_id": "b4a1c2d3-…",
"type": "department",
"name": "Sales",
"created_at": "2026-08-14T09:12:05Z"
},
{
"id": "9c07e4b2-…",
"tenant_id": "b4a1c2d3-…",
"type": "cohort",
"name": "2026-Q4 onboarding",
"created_at": "2026-09-01T14:30:41Z"
}
]

type is the axis and name the value. Filter one axis with ?type=department. Pass the chosen id values as tag_ids when creating the invite in step 4. An id that is not yours is rejected with a 422. Defining new tags stays a portal action.

3. Choose your invite shape​

ShapeHowGood forLimitation
One multi-use codeone create with max_uses: Nmass campaigns: one link in one email blastredemptions are anonymous until people join, and a leaked link is usable by anyone until you revoke it or it expires
Per-person single-use codesN creates with max_uses: 1tracked rollouts: each code maps to one known inviteeone call and one link per person

Always set expires_at, and set max_uses explicitly. An unbounded code with no expiry stays redeemable until you revoke it.

4. Create the invite​

One multi-use code for a 50-person sales-team campaign, every joiner tagged into the team and given an assessment on arrival:

curl -X POST "https://$WISELOOK_HOST/v1/access-codes" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"max_uses": 50,
"expires_at": "2026-10-01T00:00:00Z",
"tag_ids": ["<TAG_UUID>"],
"assessment_methodology_id": "<ADOPTED_METHODOLOGY_UUID>",
"assessment_channel": "text"
}'
{
"id": "3e5f7a90-…",
"tenant_id": "b4a1c2d3-…",
"code": "K7QXM2P9",
"expires_at": "2026-10-01T00:00:00Z",
"max_uses": 50,
"used_count": 0,
"target_role": "member",
"tag_ids": ["6f2d8a10-…"],
"assessment_methodology_id": "009f91ce-…",
"assessment_channel": "text",
"created_by_tenant_user_id": null,
"created_at": "2026-09-11T10:22:37Z",
"updated_at": "2026-09-11T10:22:37Z"
}

The code is what you build the accept link from in step 5; keep the id if you plan to revoke the invite later (step 7). Notes:

  • Everyone who joins through an API-created code gets the member role. Admin and manager invites are portal-only, on purpose.
  • The assessment spec is both-or-neither: assessment_methodology_id and assessment_channel together, or omit both for a plain invite.
  • The channel must be enabled for your organisation (422 otherwise).

For per-person codes, loop the same call with "max_uses": 1. Retries are safe if you send an Idempotency-Key header (any unique string per logical request; a replay returns the stored response instead of minting a second code).

Build the link from the returned code:

https://$WISELOOK_HOST/tenant-ui/accept?code=<CODE>

Distribution is yours from here. That is the point of this API: Wiselook does not email your invitees. Your backend sends the link through whatever channel your people actually read: the campaign email blast, your corporate messenger (Slack, Teams), an onboarding portal, a QR code on a workshop slide. With per-person single-use codes, each invitee gets their own link, so your system can also track exactly who has and has not acted on it.

Opening the link walks the invitee through single sign-on, creates their Wiselook account if needed, joins them to your organisation and, if the code carries an assessment spec, creates their assessment on the spot.

6. Monitor redemptions​

curl "https://$WISELOOK_HOST/v1/access-codes" \
-H "Authorization: Bearer $TOKEN"
[
{
"id": "3e5f7a90-…",
"tenant_id": "b4a1c2d3-…",
"code": "K7QXM2P9",
"expires_at": "2026-10-01T00:00:00Z",
"max_uses": 50,
"used_count": 12,
"target_role": "member",
"tag_ids": ["6f2d8a10-…"],
"assessment_methodology_id": "009f91ce-…",
"assessment_channel": "text",
"created_by_tenant_user_id": null,
"created_at": "2026-09-11T10:22:37Z",
"updated_at": "2026-09-18T08:03:12Z"
}
]

Here 12 of the 50 uses are consumed: 12 people have joined through this code. New members appear on the Members page as they join.

To reconcile exactly who joined (rather than how many), list your organisation's users through the API. With the tenant_users:read permission:

curl "https://$WISELOOK_HOST/v1/tenant-users?email=ana@example.com" \
-H "Authorization: Bearer $TOKEN"

A matching row means that address is a member of your organisation; an empty list means it is not. Without the email filter the same endpoint lists everyone, with their roles and tags, so your backend can diff the invitee list against actual joiners.

Two behaviours worth knowing:

  • Auto-assessment fires only for new joiners. An already-active member who opens the link again gets no duplicate assessment and consumes no use. (A previously removed member rejoining counts as a new joiner: one use, and the assessment fires.)
  • A use is consumed at the moment of a successful join, not when the link is opened.

7. Revoke​

curl -X DELETE "https://$WISELOOK_HOST/v1/access-codes/$CODE_ID" \
-H "Authorization: Bearer $TOKEN"

Revoking (or expiry) stops future redemptions immediately; people who already joined are unaffected. Revoking is idempotent. A second delete is a no-op 204.

See also​