Docs Guides Setting Up Connections Connections store the authentication credentials needed to interact with third-party services. Weavz supports OAuth2, API key, and custom authentication methods.
Type Use Case Example OAUTH2OAuth2 authorization flow Google, Slack, GitHub PLATFORM_OAUTH2Platform-managed OAuth2 (pre-configured) Slack, Notion, Airtable SECRET_TEXTSingle API key or token OpenAI, Anthropic, SendGrid BASIC_AUTHUsername and password SMTP, legacy APIs CUSTOM_AUTHMulti-field authentication Custom services
OAuth2 connections use the hosted connect flow — a Weavz-hosted page that handles the full authorization process. You create a connect token, open the connect page (as a popup or redirect), and the user completes authorization there. Once finished, you retrieve the session to get the resulting connection.
Dashboard Code
Navigate to Connections Open the Connections page from the sidebar.
Create Connection Click Create Connection and select the integration (e.g., Slack) from the picker.
Authorize Click Authorize — a popup opens with the provider's consent screen.
Approve Access Approve access in the popup — it closes automatically and your connection appears in the list.
The hosted connect flow has three steps: create a token, open the connect page, and retrieve the session result.
Step 1: Create a Connect Token
curl TypeScript SDK Python SDK TypeScript Python
curl -X POST https://api.weavz.io/api/v1/connect/token \
-H "Authorization: Bearer wvz_your_key" \
-H "Content-Type: application/json" \
-d '{
"integrationName": "slack",
"connectionName": "My Slack Workspace",
"externalId": "tenant_123_slack",
"workspaceId": "YOUR_WORKSPACE_ID"
}' import { WeavzClient } from '@weavz/sdk'
const client = new WeavzClient ({ apiKey: 'wvz_your_key' })
const { token , connectUrl } = await client.connect. createToken ({
integrationName: 'slack' ,
connectionName: 'My Slack Workspace' ,
externalId: 'tenant_123_slack' ,
workspaceId: 'YOUR_WORKSPACE_ID' ,
}) from weavz_sdk import WeavzClient
client = WeavzClient( api_key = "wvz_your_key" )
result = client.connect.create_token(
integration_name = "slack" ,
connection_name = "My Slack Workspace" ,
external_id = "tenant_123_slack" ,
workspace_id = "YOUR_WORKSPACE_ID" ,
)
token = result[ "token" ]
connect_url = result[ "connectUrl" ] const res = await fetch ( 'https://api.weavz.io/api/v1/connect/token' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
integrationName: 'slack' ,
connectionName: 'My Slack Workspace' ,
externalId: 'tenant_123_slack' ,
workspaceId: 'YOUR_WORKSPACE_ID' ,
}),
})
const { token , connectUrl } = await res. json () import httpx
res = httpx.post(
"https://api.weavz.io/api/v1/connect/token" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
json = {
"integrationName" : "slack" ,
"connectionName" : "My Slack Workspace" ,
"externalId" : "tenant_123_slack" ,
"workspaceId" : "YOUR_WORKSPACE_ID" ,
},
)
data = res.json()
token = data[ "token" ]
connect_url = data[ "connectUrl" ] Response:
{
"token" : "cst_abc123..." ,
"connectUrl" : "https://api.weavz.io/connect?token=cst_abc123..." ,
"expiresAt" : "2025-01-15T14:30:00.000Z"
} Step 2: Open the Connect Page
Open connectUrl in a popup window or redirect the user to it. The hosted connect page guides them through the OAuth2 consent flow.
In a browser environment, the TypeScript SDK provides a convenience method that handles the popup automatically:
// First create a token, then open popup
const { token , connectUrl } = await client.connect. createToken ({
integrationName: 'slack' ,
connectionName: 'My Slack Workspace' ,
externalId: 'tenant_123_slack' ,
workspaceId: 'YOUR_WORKSPACE_ID' ,
})
// Opens a popup, waits for completion, returns the connection result
const result = await client.connect. popup ({ token, connectUrl })
console. log ( 'Connection created:' , result.connectionId) Step 3: Retrieve the Session
If you opened the connect page manually (not using the popup helper), poll the session endpoint to check when the user has completed authorization:
curl TypeScript SDK Python SDK TypeScript Python
curl https://api.weavz.io/api/v1/connect/session/cs_abc123 \
-H "Authorization: Bearer wvz_your_key" const session = await client.connect. getSession (sessionId)
if (session.status === 'completed' ) {
console. log ( 'Connection created:' , session.connection.id)
} else if (session.status === 'failed' ) {
console. error ( 'Connect failed:' , session.error)
} session = client.connect.get_session(session_id)
if session[ "status" ] == "completed" :
print ( "Connection created:" , session[ "connection" ][ "id" ])
elif session[ "status" ] == "failed" :
print ( "Connect failed:" , session[ "error" ]) const res = await fetch ( `https://api.weavz.io/api/v1/connect/session/${ sessionId }` , {
headers: { 'Authorization' : 'Bearer wvz_your_key' },
})
const session = await res. json ()
if (session.status === 'completed' ) {
console. log ( 'Connection created:' , session.connection.id)
} else if (session.status === 'failed' ) {
console. error ( 'Connect failed:' , session.error)
} import httpx
res = httpx.get(
f "https://api.weavz.io/api/v1/connect/session/ { session_id } " ,
headers = { "Authorization" : "Bearer wvz_your_key" },
)
session = res.json()
if session[ "status" ] == "completed" :
print ( "Connection created:" , session[ "connection" ][ "id" ])
elif session[ "status" ] == "failed" :
print ( "Connect failed:" , session[ "error" ])
For services that use API keys or tokens:
Dashboard Code
Navigate to Connections Open the Connections page from the sidebar.
Create Connection Click Create Connection and select the integration (e.g., OpenAI).
Enter Credentials Enter your API key in the form.
Save Optionally set a display name and external ID, then click Save .
curl TypeScript SDK Python SDK TypeScript Python
curl -X POST https://api.weavz.io/api/v1/connections \
-H "Authorization: Bearer wvz_your_key" \
-H "Content-Type: application/json" \
-d '{
"type": "SECRET_TEXT",
"integrationName": "openai",
"externalId": "tenant_123_openai",
"displayName": "OpenAI Production",
"secretText": "sk-proj-abc123..."
}' const { connection } = await client.connections. create ({
type: 'SECRET_TEXT' ,
integrationName: 'openai' ,
externalId: 'tenant_123_openai' ,
displayName: 'OpenAI Production' ,
secretText: 'sk-proj-abc123...' ,
}) result = client.connections.create(
type = "SECRET_TEXT" ,
integration_name = "openai" ,
external_id = "tenant_123_openai" ,
display_name = "OpenAI Production" ,
secret_text = "sk-proj-abc123..." ,
) const res = await fetch ( 'https://api.weavz.io/api/v1/connections' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
type: 'SECRET_TEXT' ,
integrationName: 'openai' ,
externalId: 'tenant_123_openai' ,
displayName: 'OpenAI Production' ,
secretText: 'sk-proj-abc123...' ,
}),
})
const { connection } = await res. json () import httpx
res = httpx.post(
"https://api.weavz.io/api/v1/connections" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
json = {
"type" : "SECRET_TEXT" ,
"integrationName" : "openai" ,
"externalId" : "tenant_123_openai" ,
"displayName" : "OpenAI Production" ,
"secretText" : "sk-proj-abc123..." ,
},
)
connection = res.json()[ "connection" ]
For integrations requiring multiple fields:
Dashboard Code
Navigate to Connections Open the Connections page from the sidebar.
Create Connection Click Create Connection and select the integration (e.g., Freshsales).
Fill in Fields The form dynamically renders the required fields for the integration. Fill in all required values (e.g., base URL and API key).
Save Set a display name and external ID, then click Save .
curl TypeScript SDK Python SDK TypeScript Python
curl -X POST https://api.weavz.io/api/v1/connections \
-H "Authorization: Bearer wvz_your_key" \
-H "Content-Type: application/json" \
-d '{
"type": "CUSTOM_AUTH",
"integrationName": "freshsales",
"externalId": "tenant_123_freshsales",
"displayName": "Freshsales CRM",
"props": {
"base_url": "https://mycompany.freshsales.io",
"api_key": "abc123..."
}
}' const { connection } = await client.connections. create ({
type: 'CUSTOM_AUTH' ,
integrationName: 'freshsales' ,
externalId: 'tenant_123_freshsales' ,
displayName: 'Freshsales CRM' ,
props: {
base_url: 'https://mycompany.freshsales.io' ,
api_key: 'abc123...' ,
},
}) result = client.connections.create(
type = "CUSTOM_AUTH" ,
integration_name = "freshsales" ,
external_id = "tenant_123_freshsales" ,
display_name = "Freshsales CRM" ,
props = {
"base_url" : "https://mycompany.freshsales.io" ,
"api_key" : "abc123..." ,
},
) const res = await fetch ( 'https://api.weavz.io/api/v1/connections' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
type: 'CUSTOM_AUTH' ,
integrationName: 'freshsales' ,
externalId: 'tenant_123_freshsales' ,
displayName: 'Freshsales CRM' ,
props: {
base_url: 'https://mycompany.freshsales.io' ,
api_key: 'abc123...' ,
},
}),
})
const { connection } = await res. json () import httpx
res = httpx.post(
"https://api.weavz.io/api/v1/connections" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
json = {
"type" : "CUSTOM_AUTH" ,
"integrationName" : "freshsales" ,
"externalId" : "tenant_123_freshsales" ,
"displayName" : "Freshsales CRM" ,
"props" : {
"base_url" : "https://mycompany.freshsales.io" ,
"api_key" : "abc123..." ,
},
},
)
connection = res.json()[ "connection" ]
For multi-tenant applications, use end users to manage per-user connections. Register an end user, then generate a connect URL for them:
TypeScript SDK Python SDK TypeScript Python
// Register the end user
const { endUser } = await client.endUsers. create ({
workspaceId: 'proj_abc123' ,
externalId: 'user_456' ,
displayName: 'Alice Johnson' ,
})
// Generate a connect URL for Slack
const { connectUrl } = await client.endUsers. createConnectToken (
endUser.id,
{ integrationName: 'slack' }
)
// Open connectUrl in a popup for the user to authorize # Register the end user
result = client.end_users.create(
workspace_id = "proj_abc123" ,
external_id = "user_456" ,
display_name = "Alice Johnson" ,
)
end_user = result[ "endUser" ]
# Generate a connect URL for Slack
result = client.end_users.create_connect_token(
end_user[ "id" ],
integration_name = "slack" ,
)
connect_url = result[ "connectUrl" ]
# Open connect_url in a popup for the user to authorize // Register the end user
const userRes = await fetch ( 'https://api.weavz.io/api/v1/end-users' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
workspaceId: 'proj_abc123' ,
externalId: 'user_456' ,
displayName: 'Alice Johnson' ,
}),
})
const { endUser } = await userRes. json ()
// Generate a connect URL for Slack
const tokenRes = await fetch (
`https://api.weavz.io/api/v1/end-users/${ endUser . id }/connect-token` ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({ integrationName: 'slack' }),
}
)
const { connectUrl } = await tokenRes. json () import httpx
headers = { "Authorization" : "Bearer wvz_your_key" }
# Register the end user
res = httpx.post(
"https://api.weavz.io/api/v1/end-users" ,
headers = headers,
json = {
"workspaceId" : "proj_abc123" ,
"externalId" : "user_456" ,
"displayName" : "Alice Johnson" ,
},
)
end_user = res.json()[ "endUser" ]
# Generate a connect URL for Slack
res = httpx.post(
f "https://api.weavz.io/api/v1/end-users/ { end_user[ 'id' ] } /connect-token" ,
headers = headers,
json = { "integrationName" : "slack" },
)
connect_url = res.json()[ "connectUrl" ]
Connections created through the end user connect portal are automatically linked to the end user. When executing actions, pass endUserId to resolve the end user's connection:
TypeScript SDK Python SDK
const result = await client.actions. execute ( 'slack' , 'send_channel_message' , {
workspaceId: 'proj_abc123' ,
endUserId: 'user_456' ,
input: { channel: 'C0123456789' , text: 'Hello!' },
}) result = client.actions.execute(
"slack" ,
"send_channel_message" ,
workspace_id = "proj_abc123" ,
end_user_id = "user_456" ,
input = { "channel" : "C0123456789" , "text" : "Hello!" },
)
See Managing End Users for the full workflow.
External IDs are your identifiers for connections, used for multi-tenant applications. They let you map connections to your users or tenants.
When resolving by external ID in multi-tenant setups, always pass the same context you used when creating/using the connection (workspaceId, and endUserId for user-scoped credentials). Mismatched scope is rejected.
TypeScript SDK Python SDK TypeScript Python
// Create a connection with an external ID
await client.connections. create ({
type: 'SECRET_TEXT' ,
integrationName: 'openai' ,
externalId: 'user_456' , // Your user's ID
displayName: 'User 456 OpenAI Key' ,
secretText: 'sk-...' ,
})
// Later, resolve the connection by external ID
const { connection } = await client.connections. resolve ({
integrationName: 'openai' ,
externalId: 'user_456' ,
}) # Create a connection with an external ID
client.connections.create(
type = "SECRET_TEXT" ,
integration_name = "openai" ,
external_id = "user_456" , # Your user's ID
display_name = "User 456 OpenAI Key" ,
secret_text = "sk-..." ,
)
# Later, resolve the connection by external ID
result = client.connections.resolve(
integration_name = "openai" ,
external_id = "user_456" ,
) // Create a connection with an external ID
await fetch ( 'https://api.weavz.io/api/v1/connections' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
type: 'SECRET_TEXT' ,
integrationName: 'openai' ,
externalId: 'user_456' ,
displayName: 'User 456 OpenAI Key' ,
secretText: 'sk-...' ,
}),
})
// Later, resolve the connection by external ID
const res = await fetch ( 'https://api.weavz.io/api/v1/connections/resolve' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
integrationName: 'openai' ,
externalId: 'user_456' ,
}),
})
const { connection } = await res. json () import httpx
headers = { "Authorization" : "Bearer wvz_your_key" }
# Create a connection with an external ID
httpx.post(
"https://api.weavz.io/api/v1/connections" ,
headers = headers,
json = {
"type" : "SECRET_TEXT" ,
"integrationName" : "openai" ,
"externalId" : "user_456" ,
"displayName" : "User 456 OpenAI Key" ,
"secretText" : "sk-..." ,
},
)
# Later, resolve the connection by external ID
res = httpx.post(
"https://api.weavz.io/api/v1/connections/resolve" ,
headers = headers,
json = {
"integrationName" : "openai" ,
"externalId" : "user_456" ,
},
)
connection = res.json()[ "connection" ]
OAuth2 tokens are automatically refreshed when needed — no manual intervention required.
curl TypeScript SDK Python SDK TypeScript Python
curl https://api.weavz.io/api/v1/connections \
-H "Authorization: Bearer wvz_your_key" const { connections } = await client.connections. list () result = client.connections.list()
connections = result[ "connections" ] const res = await fetch ( 'https://api.weavz.io/api/v1/connections' , {
headers: { 'Authorization' : 'Bearer wvz_your_key' },
})
const { connections } = await res. json () import httpx
res = httpx.get(
"https://api.weavz.io/api/v1/connections" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
)
connections = res.json()[ "connections" ]
curl TypeScript SDK Python SDK TypeScript Python
curl -X DELETE https://api.weavz.io/api/v1/connections/conn_abc123 \
-H "Authorization: Bearer wvz_your_key" await client.connections. delete ( 'conn_abc123' ) client.connections.delete( "conn_abc123" ) await fetch ( 'https://api.weavz.io/api/v1/connections/conn_abc123' , {
method: 'DELETE' ,
headers: { 'Authorization' : 'Bearer wvz_your_key' },
}) import httpx
httpx.delete(
"https://api.weavz.io/api/v1/connections/conn_abc123" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
) PreviousAPI Keys Next Executing Actions