Workspaces
Multi-tenant data isolation with workspaces
Every piece of data in nodestash belongs to a workspace. Workspaces provide complete data isolation — contacts, companies, deals, and all other resources are automatically scoped to the workspace of the authenticated API key.
How Workspaces Work
When you create an account, a workspace is created for you. Each API key belongs to exactly one workspace, and every API request is automatically filtered to that workspace's data.
Workspace (ws_abc123)
├── API Keys
├── Contacts
├── Companies
├── Deals
├── Pipelines & Stages
├── Activities
├── Custom Field Definitions
└── Custom Field ValuesThere's no need to pass a workspace ID in your requests — it's derived from your API key.
Workspace Isolation
- Data isolation — you can never access data from another workspace, even with a valid API key
- Unique constraints — uniqueness rules (e.g., contact email, company domain, custom field slug) are enforced per workspace
- Rate limits — rate limits are applied per workspace, not per API key
- Custom fields — custom field definitions are workspace-scoped, so different workspaces can have different field schemas
Plans and Rate Limits
Each workspace has a plan that determines its rate limits:
| Plan | Daily Limit | Burst Limit |
|---|---|---|
| Free | 1,000 | 5 req/s |
| Starter | 25,000 | 25 req/s |
| Pro | 250,000 | 50 req/s |
| Scale | 2,000,000 | 200 req/s |
| Enterprise | Unlimited | 500 req/s |
See Rate Limits for details.
Multiple API Keys
You can create multiple API keys for a single workspace, each with different scopes and expiration dates. This is useful for:
- Separate keys per integration — one key for your backend, another for a Zapier integration
- Least privilege — give each key only the scopes it needs
- Key rotation — create a new key before revoking the old one
# Create a read-only key for your dashboard
curl -X POST https://api.nodestash.io/v1/api-keys \
-H "Authorization: Bearer $NODESTASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Dashboard (read-only)",
"scopes": ["contacts:read", "companies:read", "deals:read"]
}'const dashboardKey = await client.apiKeys.create({
name: 'Dashboard (read-only)',
scopes: ['contacts:read', 'companies:read', 'deals:read'],
})