Platform

Access Control

VectorAxis organises everything into organizations and workspaces, and controls who can do what with roles. People and applications act through platform API keys (va_…), and each key’s scope and role decide exactly which features and actions it can reach. This page covers the model end-to-end: the hierarchy, the roles, how to create a key for each role, the full permission matrix, and the developer API for every resource.

The hierarchy

An organization is the billing & identity boundary. Inside it, workspaces are isolated environments (think dev and prod, or one per team or customer), and every resource lives in a workspace.

text
Organization
  ├─ Workspace A  (dev)
  └─ Workspace B  (prod)
       ├─ Virtual keys
       ├─ Prompts
       ├─ Routing configs
       └─ Guardrails
Two kinds of key — don’t mix them up
KeyWhat it is
va_… platform API keyYour identity & permissions. Authenticates to the management and inference APIs and decides what you may do. Carries a scope + role. This page.
vk-… virtual keyA safe stand-in for a provider credential, used as the api_key on inference requests. Holds no management permissions. See Virtual Keys.
Dashboard users sign in with a Cognito session (Google or email/password); that session is used for the console. For machine-to-machine and API access, use a va_… platform key as Authorization: Bearer va_…. Inference endpoints additionally accept a virtual key directly. (Not to be confused with the PLATFORM credit mode for virtual keys — see Platform Keys.)
Scope & roles — the two dials

When you create a platform key (or invite a person) you choose a scope (how wide it reaches) and a role (how much it can do within that reach).

ScopeReachesCarries a…
orgThe whole organization — every workspace and all org-level settings.an organization role (owner / admin / member)
workspaceA single workspace and the resources inside it.a workspace role (admin / member)
RoleIn plain terms
owner orgEverything an admin can do, plus money & lifecycle: subscriptions, credits, and deleting the organization.
admin orgRuns the org: manage workspaces, members, and platform keys; full control of every workspace’s resources.
member orgRead-only at the org level. Has no access to a workspace unless separately added to it.
admin workspaceFull control of one workspace: create & manage its keys, prompts, configs, guardrails, and members.
member workspaceCan view a workspace’s resources and make inference calls, but can’t create or change them.
Org admins are workspace admins everywhere. An owner or org admin automatically has admin rights in every workspace — no need to be added to each. An org member, by contrast, gets no workspace access until they’re explicitly added to a workspace with a workspace role.
Creating a platform key in the dashboard

Open API Keys and choose Create key. You’ll set:

  • Name — a label so you can recognise the key later (e.g. “CI pipeline”, “Eng workspace admin”).
  • Scopeorg for an organization-wide key, or workspace to confine it to one workspace.
  • Roleadmin or member. For an org-scoped key that level applies across every workspace; for a workspace key it applies within that one workspace. This is what grants the permissions in the matrix below. (A key never carries the org owner role — owner is a person-only membership role for billing & lifecycle.)
  • Expiry (optional) — a date after which the key stops working.
The raw key is shown once. On create you get the full va_… secret back a single time — copy it then. Afterwards only a 4-character hint is stored, so it can never be retrieved again. Lost it? Revoke and create a new one. Only an org admin (or, for a workspace-scoped key, that workspace’s admin) can create or revoke keys.

What each role can do

full = create, edit, and delete · view = read & use only · = no access.

Inside a workspace

These act on resources that live in a workspace. Org owners and admins have admin here in every workspace automatically.

Feature / actionWorkspace adminWorkspace member
Virtual keys — create / edit / deletefull
Virtual keys — view & usefullview
Prompts — create / edit / delete / publishfull
Prompts — view & runfullview
Routing configs — create / edit / deletefull
Routing configs — viewfullview
Guardrails — create / edit / delete / enablefull
Guardrails — viewfullview
Workspace members — invite / change role / removefull
Workspace members — viewfullview
Logs & analytics — viewfullview
Make inference calls (chat, prompts)fullfull
The classic example: a workspace member can read a prompt and call it, but cannot create or edit one — that takes a workspace admin. The same split applies to virtual keys, routing configs, and guardrails.
Across the organization
Feature / actionOrg ownerOrg adminOrg member
Workspaces — createfullfull
Workspaces — view (list)fullfullview
Org members — invite / change role / removefullfull
Org members — viewfullfullview
Platform API keys — create / revokefullfull
Platform API keys — view (list)fullfullview
Logs — exportfullfull
Billing & subscription — viewfullfullview
Credits — buy / withdraw / auto-rechargefull
Subscription — change plan / checkout / portalfull
Delete the organizationfull
Money is owner-only. Anything that spends or moves money — buying or withdrawing credits, changing the subscription — is restricted to org owners, even though admins run everything else. A workspace-scoped key’s admin can also create/revoke keys and edit/delete its own workspace, but can’t touch org-level settings.

Developer API reference

Authenticate every call with Authorization: Bearer va_…. Management endpoints live under /v1. Each resource lists its endpoints with the role required, then the create payload and response. Required fields are marked *. For field-by-field detail, see each resource’s own page: virtual keys, routing configs, guardrails.

Virtual keys
MethodPathWho can call it
POST/v1/virtual-keysWorkspace admin
GET/v1/virtual-keysWorkspace member
GET/v1/virtual-keys/{slug}Workspace member
PUT/v1/virtual-keys/{slug}Workspace admin
DELETE/v1/virtual-keys/{slug}Workspace admin
POST/v1/virtual-keys/{slug}/disableWorkspace admin
POST/v1/virtual-keys/{slug}/enableWorkspace admin

Create payload * = required:

json
{
  "name": "OpenAI Production",            // *
  "organization": "acme",                 // *
  "workspace_id": "<workspace-uuid>",
  "credential_mode": "BYOK",              // BYOK | PLATFORM
  "credentials": [
    { "provider": "OPENAI", "key": "sk-..." }
  ],
  "model_allowlist": ["gpt-4o", "gpt-4o-mini"],
  "rate_limit_rpm": 100,
  "credit_limit_usd": 50.0,
  "credit_reset_policy": "MONTHLY",
  "expires_at": "2026-12-31T00:00:00Z"
}

Create response — the slug is what you use as an api key:

json
{ "slug": "vk-1a2b3c4d5e6f7a8b", "key_hint": "...abcd" }
Routing configs
MethodPathWho can call it
POST/v1/configsWorkspace admin
GET/v1/configsWorkspace member
GET/v1/configs/{slug}Workspace member
PUT/v1/configs/{slug}Workspace admin
DELETE/v1/configs/{slug}Workspace admin
POST/v1/configs/validateAny member
GET/v1/configs/{slug}/audit-logWorkspace member
GET/v1/configs/{slug}/analyticsWorkspace member
json
{
  "name": "Premium router",               // *
  "organization": "acme",                 // *
  "workspace_id": "<workspace-uuid>",
  "strategy_mode": "FALLBACK",            // * SINGLE | LOADBALANCE | FALLBACK | CONDITIONAL
  "on_status_codes": [429, 500, 502, 503, 504],
  "targets": [                            // *
    { "name": "primary", "virtual_key_slug": "vk-1a2b3c4d5e6f7a8b" },
    { "name": "backup",  "virtual_key_slug": "vk-c7d4e1f2a3b95a8b" }
  ]
}

Response is the full config detail, including its slug. Reference it on requests with x-config.

Prompts
MethodPathWho can call it
POST/v1/promptsWorkspace admin
GET/v1/promptsWorkspace member
GET/v1/prompts/{slug}Workspace member
PUT/v1/prompts/{slug}Workspace admin
DELETE/v1/prompts/{slug}Workspace admin
POST/v1/prompts/{slug}/versionsWorkspace admin
GET/v1/prompts/{slug}/versionsWorkspace member
POST/v1/prompts/{slug}/versions/{n}/publishWorkspace admin

Create a prompt (the container), then add a version with the actual messages:

json
// POST /v1/prompts
{ "name": "Summarize Article", "description": "Summarizes an article",
  "organization": "acme", "workspace_id": "<workspace-uuid>" }   // name & organization required

// POST /v1/prompts/{slug}/versions
{ "messages": [
    { "role": "system", "content": "You summarize articles." },
    { "role": "user",   "content": "Summarize: {{article}}" }
  ],
  "model": "gpt-4o-mini", "temperature": 0.3 }

Run a published prompt at POST /v1/prompts/{slug}/completions (authenticated by a virtual key or routing config, like any inference call).

Guardrails
MethodPathWho can call it
POST/v1/guardrailsWorkspace admin
GET/v1/guardrailsWorkspace member
GET/v1/guardrails/{slug}Workspace member
PUT/v1/guardrails/{slug}Workspace admin
DELETE/v1/guardrails/{slug}Workspace admin
POST/v1/guardrails/{slug}/enableWorkspace admin
POST/v1/guardrails/{slug}/disableWorkspace admin
json
{
  "name": "Safety policy",                // *
  "organization": "acme",                 // *
  "workspace_id": "<workspace-uuid>",
  "enabled": true,
  "checks": [                             // * one or more checks
    { "type": "PII_DETECTOR", "target": "BOTH", "action": "REDACT" },
    { "type": "banned_words", "target": "INPUT", "action": "BLOCK",
      "config": { "words": ["foo", "bar"] } }
  ]
}

Bind guardrails to the virtual key so every request made with it is checked without the caller sending anything, or apply one per request with x-guardrail: <slug> (which adds to the key’s, never replaces them). See the guardrails page for every validator and its config.

Workspaces
MethodPathWho can call it
POST/v1/workspacesOrg admin
GET/v1/workspacesOrg member
GET/v1/workspaces/{slug}Workspace member
PUT/v1/workspaces/{slug}Workspace admin
DELETE/v1/workspaces/{slug}Workspace admin
json
{ "name": "Engineering", "organization": "acme",   // name & organization required
  "slug": "eng", "description": "Eng team workspace" }
json
{ "id": "<uuid>", "organization": "acme", "slug": "eng",
  "name": "Engineering", "created_at": "...", "updated_at": "..." }
Members
MethodPathWho can call it
GET/v1/organizations/{org}/membersOrg member
POST/v1/organizations/{org}/membersOrg admin
PUT/v1/organizations/{org}/members/{userId}Org admin
DELETE/v1/organizations/{org}/members/{userId}Org admin
GET/v1/workspaces/{slug}/membersWorkspace member
POST/v1/workspaces/{slug}/membersWorkspace admin
PUT/v1/workspaces/{slug}/members/{userId}Workspace admin
DELETE/v1/workspaces/{slug}/members/{userId}Workspace admin

Invite to the org (an org member needs a workspace to land in):

json
// POST /v1/organizations/{org}/members
{ "email": "[email protected]", "role": "member",   // email & role required
  "workspace_id": "<workspace-uuid>", "workspace_role": "member" }

// POST /v1/workspaces/{slug}/members
{ "email": "[email protected]", "role": "admin" }    // email & role required

You can invite by email before the person has ever signed in — the membership reconciles to their account on first login.

Platform API keys
MethodPathWho can call it
POST/v1/api-keysOrg admin, or workspace admin (workspace-scoped)
GET/v1/api-keysOrg member
DELETE/v1/api-keys/{keyId}Org admin, or that workspace’s admin
json
{
  "name": "CI pipeline",                  // *
  "organization": "acme",                 // *
  "scope": "workspace",                   // * org | workspace
  "role": "admin",                        // * admin | member
  "workspace_id": "<workspace-uuid>",     // required for workspace scope
  "expires_at": "2026-12-31T00:00:00Z"
}

Create response — raw_key is shown only once:

json
{ "key": { "id": "<uuid>", "name": "CI pipeline", "scope": "workspace",
           "role": "admin", "key_hint": "...wxyz", "status": "ACTIVE" },
  "raw_key": "va_DA3saInUNRHzl19hHC9p42..." }
Billing & credits
MethodPathWho can call it
GET/v1/billing/subscriptionOrg member
GET/v1/billing/creditsOrg member
GET/v1/billing/credits/transactionsOrg member
GET/v1/billing/entitlementsOrg member
POST/v1/billing/credits/purchaseOrg owner
POST/v1/billing/credits/withdrawOrg owner
PUT/v1/billing/credits/auto-rechargeOrg owner
POST/v1/billing/checkoutOrg owner
POST/v1/billing/subscription/changeOrg owner
POST/v1/billing/portalOrg owner
json
// POST /v1/billing/credits/purchase  (and /withdraw)
{ "amount_usd": 100.0 }   // amount required
Logs & analytics (read-only)
MethodPathWho can call it
GET/v1/logsMember
GET/v1/logs/{id}Workspace member
GET/v1/analytics/summaryMember
GET/v1/analytics/timeseriesMember
GET/v1/analytics/breakdownMember
POST/v1/logs/exportOrg admin
GET/v1/logs/export/{jobId}/downloadOrg admin

Scope a read to one workspace with ?workspace_id=…. Org members must scope to a workspace they belong to; org admins can read across the whole org. More on the logs page.

Quick start: create an org admin key to set up workspaces and invite people, then hand each team a workspace-scoped key — admin for the people who build keys, prompts and configs, member for those who only need to call the APIs.