Skip to main content

Syndicate Join Sessions

A join session lets you invite someone from your own site and have them become a member of a syndicate you manage — without ever handling their password, accreditation, or membership record. You mint a session bound to one email, the person completes the join on Wefunder, and you learn the outcome by polling the session or receiving join_session.* webhooks.

Sessions are addressed by their js_ id. They are install-scoped: you only ever see the sessions your own app's installation minted on the syndicate.

Preview

These endpoints are in preview. The hosted join page is rolling out; the shape below is stable.

Create a join session​

POST /syndicates/:id/join_sessions

Requires write:syndicate_members (included in write:syndicates), at least operator standing in the syndicate, and an active installation of your app on it. Phase 1 supports mode: hosted only.

curl -X POST "https://api.wefunder.com/syndicates/syn_aB3xQ9k2vF8mNp1zT5wY7Qc4/join_sessions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"join_session": {
"email": "[email protected]",
"name": "Jane Smith",
"require_approval": false,
"success_url": "https://partner.example.com/ok",
"cancel_url": "https://partner.example.com/cancel"
}
}'
FieldRequiredNotes
emailyesThe address the session is bound to.
namenoPrefills the recipient's name.
modenohosted only (the default).
displaynoredirect (default) or popup.
require_approvalnoWhether the resulting membership needs manager approval before it is joined.
success_urlnoHTTPS URL the recipient returns to after finishing.
cancel_urlnoHTTPS URL the recipient returns to if they cancel.

Response:

{
"data": {
"id": "js_3StSZhDjMHzn8NzEkX0kgEuN",
"type": "join_session",
"attributes": {
"status": "pending",
"email": "[email protected]",
"name": "Jane Smith",
"mode": "hosted",
"display": null,
"ineligible_reason": null,
"require_approval": false,
"success_url": "https://partner.example.com/ok",
"cancel_url": "https://partner.example.com/cancel",
"url": "https://wefunder.com/join/session/js_3StSZhDjMHzn8NzEkX0kgEuN",
"expires_at": "2025-03-08T12:00:00Z",
"created_at": "2025-03-01T12:00:00Z"
}
}
}

Send the recipient to url. Each mint creates a fresh session; re-minting the same email reuses the underlying invitation (so the person is not emailed twice) but returns a new session.

Status values​

pending · pending_approval · joined · rejected · ineligible · canceled · expired. When a session ends ineligible, ineligible_reason is one of accreditation_required, jurisdiction, blocked, club_unavailable (the syndicate is no longer joinable — it was deleted or converted to a group), or requires_investment (the syndicate requires a fund investment or paid subscription to join, which hosted join sessions don't support).

Errors​

error.typeMeaning
app_not_installedYour app is not installed on this syndicate.
syndicate_requires_subscriptionThis syndicate requires an annual subscription to join.
unsupported_modeOnly hosted is supported in this phase.
invalid_success_url / invalid_cancel_urlThe URL is not https.

List join sessions​

GET /syndicates/:id/join_sessions

Returns the sessions your installation minted on this syndicate, newest first, paginated with the standard cursor / per_page contract. Needs read:syndicates.

Get a join session​

GET /syndicates/:id/join_sessions/:id

Fetch one session by its js_ id to poll its current status. Needs read:syndicates.

Was this page helpful?