Managing End Users

Register users, generate connect URLs, and execute actions on behalf of your customers.

This guide walks through the full lifecycle of managing end users in Weavz — from registering a user to executing actions with their connections.

1. Create a Workspace

End users live within workspaces. Start by creating a workspace and configuring its integrations.

bash
# Create a workspace
curl -X POST https://api.weavz.io/api/v1/workspaces \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "My App", "slug": "my-app"}'
 
# Add Slack with per-user connections
curl -X POST https://api.weavz.io/api/v1/workspaces/{workspaceId}/integrations \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "integrationName": "slack",
    "connectionStrategy": "per_user"
  }'

2. Register an End User

When a new customer signs up for your product, register them as an end user. Use their ID from your system as the externalId.

bash
curl -X POST https://api.weavz.io/api/v1/end-users \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "externalId": "user_123",
    "displayName": "Alice Johnson",
    "email": "[email protected]"
  }'

3. Generate a Connect URL

Create a connect token so the end user can connect their Slack account through the hosted connect portal.

Use the Weavz endUser.id UUID in /end-users/{endUserUuid} resource paths. When you later execute actions, pass your product user ID as endUserId; that value is the end user's externalId.

If the workspace contains multiple configured aliases for the same integration, pass workspaceIntegrationId instead of only integrationName.

bash
curl -X POST https://api.weavz.io/api/v1/end-users/{endUserUuid}/connect-token \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"integrationName": "slack"}'

Open connectUrl in a popup or redirect the end user to it. The hosted connect page guides them through the OAuth2 consent flow. Once they approve, the connection is automatically linked to the end user.

4. Execute Actions as the End User

Once the end user has connected their Slack, you can execute actions on their behalf by passing endUserId:

bash
curl -X POST https://api.weavz.io/api/v1/actions/execute \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "integrationName": "slack",
    "actionName": "send_channel_message",
    "input": {
      "channel": "C0123456789",
      "text": "Hello from Alice!"
    },
    "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "endUserId": "user_123"
  }'

Weavz resolves Alice's Slack connection automatically based on the endUserId and the workspace's per_user connection strategy.

5. Send Email Invitations

Instead of generating connect URLs programmatically, you can send email invitations directly:

bash
curl -X POST https://api.weavz.io/api/v1/end-users/{endUserUuid}/invite \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "integrationName": "slack"
  }'

The email contains a link to the connect portal where Alice can authorize her Slack account.

6. View End User Connections

Check which integrations an end user has connected:

bash
curl https://api.weavz.io/api/v1/end-users/{endUserUuid} \
  -H "Authorization: Bearer wvz_your_api_key"

7. Create MCP Servers for End Users

MCP OAuth is the preferred way to give agents end-user-scoped access when the MCP client can complete sign-in. The MCP server stays attached to the workspace, while each OAuth session resolves tool calls to a specific end user's connections. For provisioned clients that cannot run OAuth, use a bearer-enabled MCP server and issue one mcp_ bearer token per end user.

Use endUserAccess to control who can authorize the server:

  • restricted — only pre-existing workspace end users can authorize. Weavz matches the signed-in user by linked account or email and links the record when needed
  • open — a new end user can be created during MCP OAuth sign-in when the user is not already known
1

Create an end user

Register the end user as shown in step 2 above.

2

Create an OAuth or bearer-enabled MCP server

bash
curl -X POST https://api.weavz.io/api/v1/mcp/servers \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Agent for Alice",
    "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "mode": "TOOLS",
    "authMode": "oauth_and_bearer",
    "endUserAccess": "restricted"
  }'
3

Connect the client

Give the AI agent the MCP endpoint. OAuth-capable clients can sign in through Weavz when the server uses OAuth. Provisioned clients can use an end-user bearer token.

4

Or issue a programmatic end-user token

If you are provisioning MCP access from your own product, create a bearer token for a known end user:

bash
curl -X POST https://api.weavz.io/api/v1/mcp/servers/{serverId}/access-tokens \
  -H "Authorization: Bearer wvz_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "endUserId": "user_123",
    "scopes": ["mcp:tools"],
    "expiresIn": 2592000
  }'
5

Handle missing connections

When a tool call fails because the end user hasn't connected the required integration, the error includes a setup URL. Share this URL with the end user so they can connect their account and the agent can retry.

Static MCP bearer tokens are still available for service-style clients that cannot complete OAuth, but they do not identify the connecting MCP client. Use MCP OAuth or API-created end-user bearer tokens when each client should resolve to a particular end user.

Multi-Tenant Patterns

One workspace per customer

Best for strict isolation. Each customer gets their own workspace with separate integrations, connections, and end users.

graph TD
    Org[Organization: My SaaS]
    Org --> A[Workspace: Customer A]
    Org --> B[Workspace: Customer B]
    A --> Alice[alice - alice_123]
    A --> Bob[bob - bob_456]
    Alice --> AC[Alice's Slack]
    Bob --> BC[Bob's Slack]
    B --> Charlie[charlie - charlie_789]
    Charlie --> CC[Charlie's Gmail]

Shared workspace with per-user connections

Best for simpler setups where all customers share the same integration configuration.

graph TD
    Org[Organization: My SaaS]
    Org --> WS[Workspace: Production]
    WS --> S[slack - per_user]
    WS --> G[gmail - per_user_with_fallback]
    WS --> Alice[alice]
    WS --> Bob[bob]
    WS --> Charlie[charlie]
    Alice --> AS[Slack conn.]
    Alice --> AG[Gmail conn.]
    Bob --> BS[Slack conn.]
    Bob -.- BG[Gmail fallback]
    Charlie --> CG[Gmail conn.]
    Charlie -.- CS[no Slack yet]
    style BG stroke-dasharray: 5 5
    style CS stroke-dasharray: 5 5

With per_user_with_fallback, end users who haven't connected their own account still get functionality through the workspace's default connection.

Cleanup

When you delete an end user, all their connections are automatically cleaned up:

bash
curl -X DELETE https://api.weavz.io/api/v1/end-users/{endUserUuid} \
  -H "Authorization: Bearer wvz_your_api_key"

Next Steps