Workspaces: one workspace per brand, agency-master keys across many
How CitationBench isolates each brand's SEO/GEO data into a workspace, with agency master keys for portfolio-wide operations and bulk actions across clients.
A workspace is a single brand or domain. All keywords, content, integrations, rank history, link-building relationships, and AI-citation tracking live inside one workspace. Agencies create many workspaces under one master account; in-house teams typically use one workspace per brand.
The short version
- One workspace = one brand = one set of isolated SEO/GEO data
- One API key is either workspace-scoped (default) or agency master (can act on any sub-workspace)
- Agency master keys pass
X-Workspace-Id: ws_***to target a specific workspace, or useworkspaces.bulk_actionto target many at once - Each workspace has its own integrations (GSC, Ahrefs, DataForSEO, Apollo, Instantly), its own brand profile, and its own credit pool (unless pooled at agency level)
Why we modeled it this way
Three design constraints shaped this:
1. Agencies are the primary buyer. A growth agency might run SEO ops for 30, 50, even 100 client brands. They need full row-level isolation per client — keywords don't bleed across, rank history doesn't bleed across, billing roll-ups are clean — and they need to operate across the portfolio with one API call.
2. In-house teams shouldn't pay the agency tax. A single in-house team running one brand shouldn't have to think about workspace plumbing. So workspace-scoped keys exist for them: one key, one workspace, no headers required.
3. Brand context is heavyweight. Each workspace carries product description, ICPs, pillars, refiners, brand voice, default models. Every agent invocation auto-injects this context. Forcing this onto every API call would be repetitive and error-prone; making it workspace-scoped means you set it once and every downstream tool inherits it.
The data model
| Resource | Workspace-scoped? | Notes |
|---|---|---|
| Keyword | ✓ | Including labels, tags, rank history |
| BlogPost / Content | ✓ | — |
| LandingPage / LandingPagePillar | ✓ | — |
| Refiner | ✓ | System refiners are global; workspace refiners are scoped |
| LinkBuildingRelationship | ✓ | Per-workspace pipeline |
| LinkBuildingAccount | global | Shared system-wide (unique by domain) — agencies benefit from cross-portfolio knowledge of partner reputability |
| LinkBuildingContact | global | Tied to account |
| GoogleSearchConsoleConfig | ✓ | Per-workspace OAuth |
| AiQuery / AiQueryResponse | ✓ | Per-workspace citation tracking |
| ApiKey | scoped or agency | The scope field determines |
| Invocation / AgentSession | ✓ | Every invocation belongs to one workspace |
Workspace properties
{
"id": "ws_acme",
"name": "Acme PM",
"primaryDomain": "acme.com",
"createdAt": "2026-02-01T00:00:00Z",
"agencyAccountId": "agency_***",
"settings": {
"primaryLocation": "us",
"primaryLanguage": "en",
"defaultModel": "claude-sonnet-4-6",
"approvalPolicy": {
"publish": "auto",
"outreach_send": "require_approval",
"indexing_submit": "auto"
},
"creditPool": "workspace",
"byok": {
"ahrefs": false,
"dataforseo": true,
"anthropic": false
}
},
"brand": {
"shortDescription": "Engineering-team project management software with capacity tracking",
"detailedDescription": "...",
"icps": [
/* ICP segments */
],
"primaryKeywords": ["project management software for engineering teams"],
"voice": "Confident, technical, second-person; avoid corporate cliches."
}
}How agencies use workspaces
Three patterns.
Pattern A: Master account, many workspaces, separate billing
Agency Master Account (one Stripe relationship)
├── ws_client-alpha — own credit pool, own integrations
├── ws_client-beta — own credit pool, own integrations
├── ws_client-gamma — own credit pool, own integrations
└── ws_internal — for the agency's own marketingEach client gets transparency into their own usage; the agency manages billing and account-level access.
Pattern B: Pooled credits
Same structure as A, but settings.creditPool: "agency". Credits are pooled — useful when the agency buys credits in bulk and allocates per client as the work demands.
Pattern C: White-label sub-tenants
Same structure, plus the workspace has whiteLabel settings — branded dashboards, branded reports, branded outreach footers. (Roadmap.)
How invocations interact with workspaces
Every agent invocation belongs to exactly one workspace. The workspace's brand profile, integrations, default refiners, and approval policies are auto-injected as context.
Cross-workspace operations don't exist at the invocation level — they're handled by workspaces.bulk_action, which fans out one child invocation per workspace.
Code samples
List workspaces an agency master key can access
curl -H "Authorization: Bearer sk_live_agency_***" \
https://api.citationbench.com/v1/workspacesCreate a new workspace
curl -X POST -H "Authorization: Bearer sk_live_agency_***" \
https://api.citationbench.com/v1/workspaces \
-d '{
"name": "Beta Project Management",
"primaryDomain": "betapm.com",
"settings": { "primaryLocation": "uk", "primaryLanguage": "en" }
}'Act on a specific workspace (agency master key)
curl -X POST -H "Authorization: Bearer sk_live_agency_***" \
-H "X-Workspace-Id: ws_beta" \
https://api.citationbench.com/v1/research/keyword \
-d '{ "seed": "project management for design teams" }'Bulk action across many
curl -X POST -H "Authorization: Bearer sk_live_agency_***" \
https://api.citationbench.com/v1/workspaces/bulk-action \
-d '{
"action": "agent.invoke",
"workspaces": "all",
"config": {
"skill": "rank_monitor",
"input": { "alertOn": { "drop": 5 } }
}
}'Common patterns
1. Bootstrap a new workspace from a domain
curl -X POST .../v1/agent/invoke -d '{
"skill": "bootstrap_brand",
"input": { "domain": "newclient.com", "workspace": "auto" }
}'workspace: "auto" creates a new workspace named after the domain and fills in ICPs, keywords, competitors, and content plan in ~20 minutes.
2. Per-workspace integration setup
Each workspace has its own connected accounts — GSC, Apollo, Instantly, etc. Visit each workspace's dashboard or use the per-integration config endpoints (e.g., Indexing · gsc index § config).
3. Agency-wide approval policies
Set the agency's default approval policy and have each workspace inherit:
# Agency-level default (workspaces inherit unless overridden)
curl -X PATCH .../v1/agency/settings -d '{
"defaultApprovalPolicy": { "outreach_send": "require_approval", "publish": "auto" }
}'4. Audit across workspaces
curl -G .../v1/workspaces -H "Authorization: Bearer sk_live_agency_***" \
--data-urlencode "include=usage,health,lastActiveAt"Returns each workspace's credit usage, integration health, and most recent activity — the agency dashboard's source of truth.
Related
- API: Workspaces
- API: Inventory
- Concept: Agent
- Concept: Approval Workflows
- Get started: Authentication
Agent
How CitationBench's single generic agent loads skills, calls tools, pauses for approval, and persists every decision — the three-layer mental model for autonomous SEO ops.
Keywords
How CitationBench models the Keyword resource — lifecycle states, source provenance, priority, pillar mapping, and rank history — separately from the 2D labeling system.