Skip to content

Team Members API

Team members are the users who have access to your Synapse workspace. Each member has a role that determines their permissions within the workspace. You can invite new members by email, update roles, deactivate access, and manage pending invitations through this API.

Note

For a user guide on managing team members in the dashboard, see Team Roles & Permissions.


Endpoints

MethodPathDescription
GET/v1/workspace/membersList team members
POST/v1/workspace/members/inviteInvite a new member
PUT/v1/workspace/members/{member_id}/roleUpdate a member's role
DELETE/v1/workspace/members/{member_id}Deactivate a member
POST/v1/workspace/members/{member_id}/activateRe-activate a member
GET/v1/workspace/members/invitationsList pending invitations for current user
POST/v1/workspace/members/invitations/{invitation_id}/acceptAccept a pending invitation

List Members

Returns all team members for the current workspace, including both active members and pending invitations by default.

bash
curl "https://synapse-api.pyrx.tech/v1/workspace/members?include_inactive=true" \
-H "Authorization: Bearer <jwt>"

Auth: JWT (dashboard). Requires members:read permission.

Query Parameters

ParameterTypeDefaultDescription
include_inactivebooleantrueInclude inactive members (pending invitations, deactivated members)

Response

json
{
"members": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Jane Nguyen",
"email": "[email protected]",
"role": "owner",
"is_active": true,
"created_at": "2026-01-10T08:00:00Z",
"invite_accepted_at": "2026-01-10T08:05:00Z"
},
{
"id": "b2c3d4e5-f678-9012-abcd-ef1234567890",
"name": "Alex Chen",
"email": "[email protected]",
"role": "admin",
"is_active": true,
"created_at": "2026-01-15T10:00:00Z",
"invite_accepted_at": "2026-01-15T10:30:00Z"
},
{
"id": "c3d4e5f6-7890-1234-abcd-ef1234567890",
"name": "",
"email": "[email protected]",
"role": "marketing",
"is_active": false,
"created_at": "2026-04-20T14:00:00Z",
"invite_accepted_at": null
}
],
"total": 3
}

Members with is_active: false and invite_accepted_at: null are pending invitations that have not yet been accepted.


Invite a Member

Sends an invitation to a new team member. The invited user appears as an inactive member until they accept. Plan limits on member count are enforced at invite time.

Invitations expire after 14 days

An invitation is acceptable for 14 days from when it is sent. After that it expires: it can no longer be accepted (the accept endpoint returns 410 Gone), it is excluded from the pending-invitations list, and its seat is freed (an expired invite no longer counts toward the members plan limit). Re-inviting the same email resets the 14-day window.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/workspace/members/invite \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"role": "developer",
"name": "Sam Park"
}'

Auth: JWT (dashboard). Requires members:write permission.

Request Body

FieldTypeRequiredDescription
emailstringYesEmail address of the person to invite (must be a valid email)
rolestringYesRole to assign: admin, developer, marketing, operations, or viewer
namestringNoDisplay name for the invited member (max 255 characters)
Note

You cannot invite someone with the owner role. Each workspace has exactly one owner, enforced at the database level.

Response (201 Created)

json
{
"id": "d4e5f678-9012-3456-abcd-ef1234567890",
"name": "Sam Park",
"email": "[email protected]",
"role": "developer",
"is_active": false,
"created_at": "2026-04-25T09:00:00Z",
"invite_accepted_at": null
}

Error: Duplicate Invite (409 Conflict)

json
{
"detail": "A member with this email already exists in the workspace"
}

Error: Plan Limit Reached (403 Forbidden)

json
{
"detail": "Member limit reached for your plan. Upgrade to add more members.",
"code": "plan_limit_reached"
}

Update Member Role

Change the role of an existing team member. You cannot change your own role, and you cannot assign the owner role.

bash
curl -X PUT https://synapse-api.pyrx.tech/v1/workspace/members/b2c3d4e5-f678-9012-abcd-ef1234567890/role \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"role": "developer"
}'

Auth: JWT (dashboard). Requires members:write permission.

Request Body

FieldTypeRequiredDescription
rolestringYesNew role: admin, developer, marketing, operations, or viewer

Response (200 OK)

json
{
"id": "b2c3d4e5-f678-9012-abcd-ef1234567890",
"name": "Alex Chen",
"email": "[email protected]",
"role": "developer",
"is_active": true,
"created_at": "2026-01-15T10:00:00Z",
"invite_accepted_at": "2026-01-15T10:30:00Z"
}

Error: Invalid Operation (400 Bad Request)

Returned when attempting to change your own role or change the owner's role:

json
{
"detail": "Cannot change your own role"
}

Deactivate a Member

Soft-deactivates a team member, revoking their access to the workspace. The member record is retained for audit purposes. You cannot deactivate yourself or the workspace owner.

bash
curl -X DELETE https://synapse-api.pyrx.tech/v1/workspace/members/b2c3d4e5-f678-9012-abcd-ef1234567890 \
-H "Authorization: Bearer <jwt>"

Auth: JWT (dashboard). Requires members:write permission.

Response

Returns 204 No Content on success.

Error: Invalid Operation (400 Bad Request)

json
{
"detail": "Cannot deactivate yourself"
}

Re-activate a Member

Restores access for a previously deactivated member, returning them to their original role. Only a member who was previously active and then deactivated can be reactivated. Reactivation consumes a seat, so it is subject to the members plan limit just like a new invite.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/workspace/members/b2c3d4e5-f678-9012-abcd-ef1234567890/activate \
-H "Authorization: Bearer <jwt>"

Auth: JWT (dashboard). Requires members:write permission.

Response (200 OK)

json
{
"id": "b2c3d4e5-f678-9012-abcd-ef1234567890",
"name": "Alex Chen",
"email": "[email protected]",
"role": "developer",
"is_active": true,
"created_at": "2026-01-15T10:00:00Z",
"invite_accepted_at": "2026-01-15T10:30:00Z"
}

Error: Plan Limit Reached (403 Forbidden)

Reactivating would take the workspace over its members plan limit. Free a seat (remove a member or let a stale invitation expire) or upgrade the plan, then retry.

json
{
"detail": "Member limit reached for your plan. Upgrade to add more members.",
"code": "plan_limit_reached"
}

Error: Never Accepted (400 Bad Request)

The target never accepted an invitation, so there is no prior access to restore. A member who is still a pending invite cannot be reactivated — invite them again instead.

json
{
"detail": "Cannot reactivate a member who never accepted an invitation. Send a new invite instead.",
"code": "reactivate_never_accepted"
}

List Pending Invitations

Lists pending workspace invitations for the currently authenticated user across all workspaces. This is used by the dashboard to show the user which workspaces they have been invited to join.

bash
curl https://synapse-api.pyrx.tech/v1/workspace/members/invitations \
-H "Authorization: Bearer <jwt>"

Auth: JWT (dashboard). No specific permission required beyond authentication.

Response

json
{
"invitations": [
{
"invitation_id": "e5f67890-1234-5678-abcd-ef1234567890",
"workspace_name": "Acme Marketing",
"workspace_id": "ws_m4k8j2n6",
"role": "marketing",
"invited_by": "Jane Nguyen",
"invited_at": "2026-04-20T14:00:00Z"
}
]
}

If the user has no pending invitations, invitations is an empty array. Expired invitations (past their 14-day window) are excluded — only invitations that can still be accepted are returned.


Accept an Invitation

Accepts a pending invitation, activating the membership and linking the current user's identity to the new workspace. After accepting, the frontend should switch the workspace context.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/workspace/members/invitations/e5f67890-1234-5678-abcd-ef1234567890/accept \
-H "Authorization: Bearer <jwt>"

Auth: JWT (dashboard). The invitation must belong to the current user's email address.

Response (200 OK)

json
{
"id": "e5f67890-1234-5678-abcd-ef1234567890",
"name": "Alex Chen",
"email": "[email protected]",
"role": "marketing",
"is_active": true,
"created_at": "2026-04-20T14:00:00Z",
"invite_accepted_at": "2026-04-25T09:15:00Z"
}

Error: Not Found (404)

Returned when no matching pending invitation exists for the current user — the invitation never existed, was revoked, or was already accepted.

json
{
"detail": "Invitation not found or already accepted"
}

Error: Invitation Expired (410 Gone)

The invitation existed but has passed its 14-day window and is no longer acceptable. This is distinct from the 404 above (which means "never existed / already consumed"). Ask the workspace Owner or Admin to send a fresh invitation.

json
{
"detail": "This invitation has expired. Ask the workspace owner to send a new one.",
"code": "invite_expired"
}

Roles Reference

RoleDescription
ownerFull access including billing and workspace deletion. One per workspace.
adminAll CRM permissions plus user management. No billing access.
developerFlows, templates, segments, contacts, logs, and dev tools.
marketingFlows, templates, segments, and analytics.
operationsContacts (read-only), email logs, and analytics.
viewerAnalytics read-only.

Plan Limits

PlanMax Members
Free1
Starter3
Growth10
EnterpriseUnlimited

When the member limit is reached, invite requests return 403 with plan_limit_reached.