Skip to main content

Syndicate Members

The member directory: list and search it, invite, approve, moderate, reorder, and export. Reads need read:syndicates; writes need write:syndicates and at least operator standing in the syndicate (see the permission model).

Members are addressed by their mem_ id. Invitees who have not signed up yet are members too, with user set to null.

Monetary values

investment_total, amount, and total_amount are whole US dollars as strings: "15000" is $15,000.

List members​

GET /syndicates/:id/members
curl "https://api.wefunder.com/syndicates/syn_aB3xQ9k2vF8mNp1zT5wY7Qc4/members?role=member&per_page=25" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response (as seen by a moderator):

{
"data": [
{
"id": "mem_7Hq2kLm9Pw3xZr5tYv8bNc4d",
"type": "syndicate_member",
"attributes": {
"user_id": 456,
"user": "usr_2mNp1zT5wY7Qc4aB3xQ9k2vF",
"user_name": "Jane Smith",
"role": "member",
"invite_role": "member",
"syndicate_permission": "full_access",
"title": null,
"sort_order": null,
"carry_percentage_override": null,
"carry_discount_percentage": null,
"management_fee_discount_percentage": null,
"public_on_syndicate_profile": true,
"joined_at": "2025-11-15T10:30:00Z",
"created_at": "2025-11-15T10:30:00Z",
"updated_at": "2026-02-10T14:00:00Z",
"user_email": "[email protected]",
"avatar_url": "https://uploads.wefunder.com/uploads/user/avatar/456/jane.jpg",
"bio": "Angel investor focused on climate tech",
"last_activity_at": "2026-03-08T09:15:00Z",
"profile_url": "/janesmith",
"tags": ["climate", "deep-tech"],
"interests": ["Climate"],
"stage_preferences": ["Seed"],
"looking_for": [],
"linkedin_url": "https://linkedin.com/in/janesmith",
"twitter_url": null,
"website": null,
"city": "San Francisco",
"state": "CA",
"country": "US",
"accredited": true,
"legal_name": "Jane A. Smith",
"starred": false,
"private_tags": ["LP prospect"],
"investment_total": "15000",
"deal_count": 2
}
}
],
"meta": {
"has_more": true,
"page_count": 25,
"next_cursor": 25
}
}

Pagination is by offset: pass meta.next_cursor back as cursor. per_page defaults to 25 and caps at 100.

Fields​

FieldNotes
roleOne of manager, member, backer, applicant, invitee, resigned, exiled, rejected
syndicate_permissionfull_access or operator. Meaningful only when role is manager; other rows carry the column default full_access, which grants nothing
invite_roleThe role the person was invited as (manager or member)
carry_percentage_overrideInteger 1 to 100, or null
profile_urlA path relative to https://wefunder.com
tagsThe member's public "can help with" tags; interests, stage_preferences, and looking_for come from their investor profile
city, state, countryOmitted when the member keeps their location private
last_activity_atThe user's last login

Profile fields (avatar_url, bio, location, links) are present only when the member has a Wefunder account.

Moderator-only fields​

Users with full_access or operator standing see these; everyone else gets user_email as null and the rest omitted:

FieldDescription
user_emailEmail, or the invite email for an invitee
accreditedWhether the user is an accredited investor
legal_nameFull legal name
starredWhether the calling moderator starred this member
private_tagsLabels moderators have attached to the member
investment_total, deal_countDollars invested and distinct deals, across the syndicate's selected deals (one per company)

Query parameters​

ParamTypeDescription
rolestringFilter by role, for example member, invitee, applicant, exiled
permissionstringfull_access or operator
searchstringMatches name and bio. Moderators also match email and invite email
sortstringnewest, oldest, alphabetical, last_activity, or investment_amount (moderators only). Default is directory order
has_invested"true" or "false"Moderators only. Whether the member has invested in any selected deal
accredited"true" or "false"Moderators only
tagstringA "can help with" tag, matched case-insensitively
locationstringMatches city, state, or country for members with a public location
cursor, per_pageintegerPagination

Moderator-only parameters are ignored, not rejected, for other callers.

Invite a member​

POST /syndicates/:id/members/invite

Creates an invitee row and emails an invitation. The invitee becomes a member when they accept the link in that email.

{
"email": "[email protected]",
"name": "Jane Smith",
"syndicate_permission": "operator"
}
ParamRequiredDescription
emailYesNormalized to lowercase before matching
nameNoDisplay name until the invitee signs up
syndicate_permissionNofull_access invites a manager (invite_role: "manager"). operator, any other value, or omitting the field invites a regular member (invite_role: "member"); the row stores operator, which grants nothing on a non-manager row. Only the syndicate's creator can send a full_access invite

This endpoint cannot invite an operator-tier co-manager. Operator standing belongs to a manager row with operator permission; the creator gets there by inviting with full_access (or promoting an existing member) and then demoting. The web app lets any full_access manager grant full_access; the API reserves it for the creator, and this page documents the API.

Returns 201 with the new member. Errors use the standard envelope; the error.type values are:

Statuserror.typeWhen
400bad_requestemail missing
403forbiddenfull_access requested by someone other than the creator (Only the syndicate manager can assign Admin roles)
409conflictThe user is already an active member, or this email already has an open invitation

Update a member​

PATCH /syndicates/:id/members/:member_id
{
"member": {
"title": "Lead Investor",
"carry_percentage_override": 20
}
}

Sets a custom title and a per-member carry override (integer percent, 1 to 100). Requires operator standing, and the target must be someone you can manage: not the creator, and, unless you are the creator or a site admin, only if you hold full_access.

Approve an applicant​

POST /syndicates/:id/members/:member_id/approve

Only rows with role applicant can be approved here; invitees accept their own link. The applicant joins with the role they applied for. Approving someone who applied as a manager requires full_access.

Approval also captures any fund payment the applicant authorized while waiting, so a 409 conflict is returned when the applicant is already approved and paying.

Statuserror.typeWhen
400bad_requestRole is not applicant
409conflictAlready approved

Exile a member​

POST /syndicates/:id/members/:member_id/hide

Sets the role to exiled, cancels any annual-subscription mandate, and releases any held fund payment. Requires operator standing and a manageable target (same rule as update). Returns the updated member.

Promote to manager​

POST /syndicates/:id/members/:member_id/promote

Makes the member a manager with full_access. Creator (or site admin) only. Returns the updated member.

Demote to operator​

POST /syndicates/:id/members/:member_id/demote

Reduces a manager's permission to operator. Requires full_access and a manageable target. Returns the updated member.

Restore a member​

POST /syndicates/:id/members/:member_id/restore

Returns an exiled or resigned row to member. Requires operator standing. Any other role is refused with 400:

{
"error": {
"type": "bad_request",
"message": "Member is not resigned or exiled (role: member)",
"details": {},
"request_id": "req_3f9c2a1e8b7d4e5f9a1b2c3d"
}
}

Resend an invite​

POST /syndicates/:id/members/:member_id/resend_invite

Re-sends the invitation email for a row whose role is still invitee. Returns {"data": {"resent": true}}. A non-invitee gets 400; an invitee with no invitation record gets 404.

Reorder members​

POST /syndicates/:id/members/reorder
{
"member_ids": ["mem_7Hq2kLm9Pw3xZr5tYv8bNc4d", "mem_3dNc8bYv5tZr3xPw9mLk2qH7"]
}

Sets each listed member's sort_order to its position in the array. Returns {"data": {"reordered": true}}.

Remove a member (intent required)​

Removal is irreversible, so DELETE /syndicates/:id/members/:member_id never removes anyone. It always returns 422:

{
"error": {
"type": "use_intents",
"message": "Removing members requires human approval. Use POST /api/v2/intents with action 'syndicates.remove_member'.",
"details": {},
"request_id": "req_3f9c2a1e8b7d4e5f9a1b2c3d"
}
}

The message names the application path; through https://api.wefunder.com that is POST /intents.

The removal itself is a syndicates.remove_member intent on the syndicate (resource_type: "Club"), approved by a human with full_access. To take a member out of the directory today without an intent, exile them with hide; that is reversible with restore.

A member's investments​

GET /syndicates/:id/members/:member_id/investments

Moderators only. Lists the member's active investments in the syndicate's selected deals (one deal per company).

curl "https://api.wefunder.com/syndicates/syn_aB3xQ9k2vF8mNp1zT5wY7Qc4/members/mem_7Hq2kLm9Pw3xZr5tYv8bNc4d/investments" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": [
{
"id": "inv_9kLm2Pw3xZr5tYv8bNc4dHq7",
"type": "member_investment",
"attributes": {
"fundraise_id": 99,
"offering": "ofr_kUlkWcWVugo7cSLD4RdD6gdK",
"company_name": "Acme Corp",
"amount": "15000",
"status": "confirmed",
"created_at": "2026-01-20T14:30:00Z"
}
}
],
"meta": {
"count": 1,
"total_amount": "15000"
}
}

status is pending (committed, not final) or confirmed (final). An invitee with no account returns an empty list. This endpoint is not paginated.

Export CSV​

POST /syndicates/:id/members/export_csv

Moderators only. Responds with the directory as text/csv.

curl -X POST "https://api.wefunder.com/syndicates/syn_aB3xQ9k2vF8mNp1zT5wY7Qc4/members/export_csv" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-o members.csv
Was this page helpful?