Team Key Isolation
Separate API keys, spend, and logs by team or project.
Overview
Teams let you carve Stockyard into isolated namespaces. Each team gets its own API keys, and every request made with a team key is automatically tagged in logs, traces, and spend tracking. No configuration needed beyond creating the team and generating keys.
This is the recommended way to give separate projects, environments, or teams their own slice of your Stockyard instance without running multiple instances.
Create a Team
curl -X POST https://your-host/api/teams \
-H "X-Admin-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Frontend", "description": "Frontend web app"}'
Response:
{
"id": 1,
"name": "Frontend",
"slug": "frontend",
"description": "Frontend web app",
"created_by": 0,
"created_at": "2026-03-28T12:00:00Z",
"updated_at": "2026-03-28T12:00:00Z"
}
Generate a Team Key
curl -X POST https://your-host/api/teams/1/keys \
-H "X-Admin-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "production"}'
The response includes the full API key. Copy it immediately — it is only shown once.
{
"id": 5,
"user_id": 1,
"team_id": 1,
"key_prefix": "sk-sy-aBcDeF...",
"name": "production",
"scopes": "*",
"key": "sk-sy-aBcDeFgHiJkLmNoPqRsTuVwXyZ..."
}
Use the Key
Team keys work exactly like regular Stockyard keys. Just set the Authorization header:
curl https://your-host/v1/chat/completions \
-H "Authorization: Bearer sk-sy-YOUR_TEAM_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}]
}'
Stockyard automatically detects the team key, tags the request with the team ID, and routes it through all configured middleware. Nothing else changes.
View Team Spend
curl https://your-host/api/teams/1/spend \ -H "X-Admin-Key: $ADMIN_KEY"
{
"team_id": "1",
"total": {
"requests": 1482,
"cost_usd": 12.4830,
"tokens_in": 892400,
"tokens_out": 341200
},
"this_month": {
"requests": 340,
"cost_usd": 3.2100
},
"today": {
"requests": 42,
"cost_usd": 0.3800
}
}
View Team Logs
curl "https://your-host/api/teams/1/logs?limit=20" \ -H "X-Admin-Key: $ADMIN_KEY"
Returns only requests made with keys belonging to team 1. Supports limit and offset query parameters for pagination.
Manage Keys
| Action | Endpoint | Method |
|---|---|---|
| List keys | /api/teams/{id}/keys | GET |
| Create key | /api/teams/{id}/keys | POST |
| Revoke key | /api/teams/{id}/keys/{keyId} | DELETE |
| Rotate key | /api/teams/{id}/keys/{keyId}/rotate | POST |
Rotating a key atomically revokes the old key and generates a new one with the same name. The old key stops working immediately.
Manage Teams
| Action | Endpoint | Method |
|---|---|---|
| List teams | /api/teams | GET |
| Create team | /api/teams | POST |
| Get team + keys | /api/teams/{id} | GET |
| Update team | /api/teams/{id} | PUT |
| Delete team | /api/teams/{id} | DELETE |
Deleting a team automatically revokes all its keys.
Dashboard
The Teams tab in the dashboard (at /ui) provides a full UI for creating teams, generating keys, viewing spend, and managing everything without touching the API directly.
How It Works
When a request arrives with a team-scoped API key:
1. The auth middleware validates the key and looks up the associated team.
2. The team and user are injected into the request context.
3. The proxy handler copies the team ID onto the request metadata.
4. All downstream systems — request logging, trace recording, spend tracking — include the team ID automatically.
Existing user keys (without a team) continue to work exactly as before. Team isolation is purely additive.
user_id in the request body.