Docs Guides API Keys API keys are the primary way to authenticate with the Weavz API from your backend services. Each key is scoped to an organization and provides full access to that organization's resources.
All Weavz API keys use the wvz_ prefix followed by a random string:
This prefix makes it easy to identify Weavz keys in your codebase and allows secret scanners to detect leaked credentials.
Dashboard Code
Open Settings Navigate to Settings → API Keys in the Weavz dashboard.
Create a new key Click Create API Key and enter a descriptive name (e.g., production-backend, staging-server).
Set expiration (optional) Optionally set an expiration date for automatic key rotation.
Copy the key Click Create and copy the key immediately — it will only be shown once.
curl TypeScript SDK Python SDK TypeScript Python
curl -X POST https://api.weavz.io/api/v1/api-keys \
-H "Authorization: Bearer wvz_your_existing_key" \
-H "Content-Type: application/json" \
-d '{
"name": "production-backend",
"expiresAt": "2026-12-31T23:59:59Z"
}' Response:
{
"apiKey" : {
"id" : "key_abc123" ,
"name" : "production-backend" ,
"expiresAt" : "2026-12-31T23:59:59Z" ,
"createdAt" : "2025-01-15T10:30:00Z"
},
"plainKey" : "wvz_abc123def456..."
} The plainKey field contains the full API key. This is the only time it will be returned — Weavz stores a hashed version at rest.
import { WeavzClient } from '@weavz/sdk'
const client = new WeavzClient ({ apiKey: 'wvz_your_key' })
const { apiKey , plainKey } = await client.apiKeys. create ({
name: 'staging-server' ,
expiresAt: '2026-06-01T00:00:00Z' ,
})
console. log ( 'New key:' , plainKey) from weavz_sdk import WeavzClient
client = WeavzClient( api_key = "wvz_your_key" )
result = client.api_keys.create( name = "staging-server" )
print ( "New key:" , result[ "plainKey" ]) const res = await fetch ( 'https://api.weavz.io/api/v1/api-keys' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_existing_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
name: 'production-backend' ,
expiresAt: '2026-12-31T23:59:59Z' ,
}),
})
const { apiKey , plainKey } = await res. json ()
console. log ( 'New key:' , plainKey) import httpx
res = httpx.post(
"https://api.weavz.io/api/v1/api-keys" ,
headers = { "Authorization" : "Bearer wvz_your_existing_key" },
json = {
"name" : "production-backend" ,
"expiresAt" : "2026-12-31T23:59:59Z" ,
},
)
data = res.json()
print ( "New key:" , data[ "plainKey" ])
Include your API key in the Authorization header of every request:
curl https://api.weavz.io/api/v1/workspaces \
-H "Authorization: Bearer wvz_your_key"
curl TypeScript SDK Python SDK TypeScript Python
curl https://api.weavz.io/api/v1/api-keys \
-H "Authorization: Bearer wvz_your_key" const keys = await client.apiKeys. list () keys = client.api_keys.list() const res = await fetch ( 'https://api.weavz.io/api/v1/api-keys' , {
headers: { 'Authorization' : 'Bearer wvz_your_key' },
})
const keys = await res. json () import httpx
res = httpx.get(
"https://api.weavz.io/api/v1/api-keys" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
)
keys = res.json()
curl TypeScript SDK Python SDK TypeScript Python
curl -X DELETE https://api.weavz.io/api/v1/api-keys/key_abc123 \
-H "Authorization: Bearer wvz_your_key" await client.apiKeys. delete ( 'key_abc123' ) client.api_keys.delete( "key_abc123" ) const res = await fetch ( 'https://api.weavz.io/api/v1/api-keys/key_abc123' , {
method: 'DELETE' ,
headers: { 'Authorization' : 'Bearer wvz_your_key' },
}) import httpx
res = httpx.delete(
"https://api.weavz.io/api/v1/api-keys/key_abc123" ,
headers = { "Authorization" : "Bearer wvz_your_key" },
)
To rotate an API key without downtime:
Create a new key Generate a new API key via the dashboard or API.
Update your application Deploy the new key to your environment variables.
Verify the new key Confirm the new key works in production.
Delete the old key Revoke the old key once the new one is verified.
// 1. Create new key
const { plainKey : newKey } = await client.apiKeys. create ({
name: 'production-backend-v2' ,
})
// 2. Update your environment variables with the new key
// 3. Verify the new key works
// 4. Delete the old key
await client.apiKeys. delete ( 'old_key_id' )
By default, API keys have org-wide access. For tighter security, you can scope a key to specific workspaces — the key will only be able to access resources (connections, MCP servers, triggers, actions) within those workspaces.
curl TypeScript SDK Python SDK TypeScript Python
curl -X POST https://api.weavz.io/api/v1/api-keys \
-H "Authorization: Bearer wvz_your_existing_key" \
-H "Content-Type: application/json" \
-d '{
"name": "checkout-service",
"permissions": {
"scope": "workspace",
"workspaceIds": ["WORKSPACE_UUID_1"]
}
}' import { WeavzClient } from '@weavz/sdk'
const client = new WeavzClient ({ apiKey: 'wvz_your_key' })
const { apiKey , plainKey } = await client.apiKeys. create ({
name: 'checkout-service' ,
permissions: {
scope: 'workspace' ,
workspaceIds: [ 'WORKSPACE_UUID_1' ],
},
})
console. log ( 'Scoped key:' , plainKey) from weavz_sdk import WeavzClient
client = WeavzClient( api_key = "wvz_your_key" )
result = client.api_keys.create(
name = "checkout-service" ,
permissions = {
"scope" : "workspace" ,
"workspaceIds" : [ "WORKSPACE_UUID_1" ],
},
)
print ( "Scoped key:" , result[ "plainKey" ]) const res = await fetch ( 'https://api.weavz.io/api/v1/api-keys' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer wvz_your_existing_key' ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
name: 'checkout-service' ,
permissions: {
scope: 'workspace' ,
workspaceIds: [ 'WORKSPACE_UUID_1' ],
},
}),
})
const { apiKey , plainKey } = await res. json ()
console. log ( 'Scoped key:' , plainKey) import httpx
res = httpx.post(
"https://api.weavz.io/api/v1/api-keys" ,
headers = { "Authorization" : "Bearer wvz_your_existing_key" },
json = {
"name" : "checkout-service" ,
"permissions" : {
"scope" : "workspace" ,
"workspaceIds" : [ "WORKSPACE_UUID_1" ],
},
},
)
data = res.json()
print ( "Scoped key:" , data[ "plainKey" ])
If a workspace-scoped key tries to access a resource outside its allowed workspaces, the API returns 403 with code SCOPE_DENIED. Org-level administration endpoints (API key management, org settings) also require org-wide keys.
When sending connectionExternalId/externalId for action execution or connection resolution, include the correct workspaceId (and endUserId when applicable). Explicit connection IDs are still validated against that context and are rejected on scope mismatch.
Use workspace-scoped keys for least-privilege access — each service should only access the workspaces it needs
Use environment variables — never hardcode API keys in source code
Separate keys per environment — use different keys for development, staging, and production
Set expiration dates — rotate keys periodically for better security
Never expose keys in client-side code — API keys should only be used in server-side applications
Monitor usage — check the Activity page to track API key usage
Revoke compromised keys immediately — if a key is leaked, delete it and create a new one
PreviousPlan Limits & Quotas Next Setting Up Connections