API Tokens
API tokens let you access the Builder Backend API programmatically without browser sessions. Essential for automation, scripts, and integrations.
What Are API Tokens?
API tokens are long-lived credentials that replace username/password for programmatic access.
Format: bb_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Key differences from session tokens:
- Long-lived: Up to 365 days (you choose)
- Revocable: Instant revocation anytime
- Scoped: Limit what the token can do
- Shown once: Can't retrieve after creation
Use Cases
1. CI/CD Pipelines
Generate backends automatically in GitHub Actions, GitLab CI, etc.
# .github/workflows/generate-backend.yml
- name: Generate Backend
run: |
curl -X GET $API_URL/projects/$PROJECT_ID/generate/download \
-H "Authorization: Bearer $\{\{ secrets.BB_TOKEN \}\}" \
-o backend.zip
2. Command-Line Scripts
#!/bin/bash
# create-customer-backend.sh
BB_TOKEN=bb_pat_xxxxx
curl -X POST https://builder.yourdomain.com/projects \
-H "Authorization: Bearer $BB_TOKEN" \
-d '{"name": "Customer Backend"}'
3. Template Systems
# Generate 50 backends from templates
for customer in $(cat customers.txt); do
BB_TOKEN=$TOKEN ./generate-backend.sh "$customer"
done
4. AI Tool Integrations
Tools like Lovable, Claude Desktop, or other AI assistants can use tokens to:
- Read your project specs
- Create/modify entities
- Generate backends on your behalf
Note: MCP (Model Context Protocol) integration is planned but not yet available.
Creating a Token
Via Dashboard
- Log in to Builder Backend
- Click your email (top right) → Account
- Navigate to API Tokens tab
- Click Create Token
- Fill in details:
- Name: Descriptive name (e.g., "GitHub Actions", "Lovable")
- Scopes: What this token can do (see below)
- Expires: 1-365 days
- Pin to project: (Optional) Restrict to one project
- Click Create
- COPY THE TOKEN NOW - you can't see it again!
Via API
# First, get a session token by logging in
ACCESS_TOKEN=$(curl -X POST https://api.builder.dumbpotato.com/account/login \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "password": "your-password"}' \
| jq -r '.access_token')
# Create API token
curl -X POST https://api.builder.dumbpotato.com/account/tokens \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Script",
"scopes": ["read", "write", "generate"],
"expires_in_days": 90,
"project_id": null
}' | jq '.'
Response:
{
"id": "uuid-here",
"name": "My Script",
"public_id": "bb_pat_abc123...",
"token": "bb_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scopes": ["generate", "read", "write"],
"expires_at": "2027-01-23T10:30:00Z",
"created_at": "2026-10-25T03:30:00Z"
}
⚠️ Save token immediately - it's never shown again!
Scopes
Tokens have scopes that limit what they can do. Choose the minimum scopes needed.
| Scope | What It Allows | Use Case |
|---|---|---|
read | View projects, specs, entities, generations | Read-only access, monitoring |
write | Create/modify projects, entities, fields, relations | Full editing, templates |
generate | Generate and download backends | CI/CD, automation |
Examples:
| Use Case | Scopes |
|---|---|
| Read-only monitoring | ["read"] |
| Full editing (no downloads) | ["read", "write"] |
| CI/CD (generate only) | ["read", "generate"] |
| Full access | ["read", "write", "generate"] |
Validation:
- Can't create a token with no scopes
- Can't use scope you don't have (viewers can't create
writetokens) - Unknown scopes are rejected
Pinning to a Project
Optional: Restrict a token to a single project.
When to pin:
- Giving contractors limited access
- Per-project CI/CD tokens
- Security: token can't access other projects even if stolen
How:
{
"name": "Contractor Token",
"scopes": ["read", "write"],
"expires_in_days": 30,
"project_id": "uuid-of-project"
}
Restrictions:
- Can only pin to projects you're a member of
- Viewers can't create pinned tokens with
writescope - Token only works on that project's API endpoints
Using a Token
Replace session token with API token:
curl -X GET https://api.builder.dumbpotato.com/projects \
-H "Authorization: Bearer bb_pat_your_token_here"
Where tokens work:
- ✅ All
/projects/*endpoints - ✅ All
/account/*endpoints (except creating other tokens) - ✅ Entity/field/relation operations
- ✅ Generate and download
- ❌ NOT admin console (
/admin/*)
Security Best Practices
1. Store Securely
DO:
- GitHub Secrets, GitLab CI Variables
- Environment variables (
.envfile, never committed) - Password managers
DON'T:
- Hardcode in source code
- Commit to Git
- Share in Slack/email
2. Use Minimum Scopes
Give only the permissions needed:
// Bad: full access when you only need read
{"scopes": ["read", "write", "generate"]}
// Good: minimum needed
{"scopes": ["read"]}
3. Set Expiration
Don't use 365 days unless necessary.
| Use Case | Recommended Expiry |
|---|---|
| Short-term testing | 7 days |
| Personal scripts | 30-90 days |
| CI/CD | 90-180 days |
| Production integrations | 180-365 days |
Set calendar reminder to rotate before expiry.
4. Revoke Unused Tokens
Regularly audit and revoke:
- Tokens you don't recognize
- Tokens not used in 30+ days (check
last_used_at) - Tokens for departed team members
5. Pin When Possible
If token only needs access to one project, always pin it.
Managing Tokens
List All Tokens
Dashboard: Account → API Tokens tab
API:
curl -X GET https://api.builder.dumbpotato.com/account/tokens \
-H "Authorization: Bearer $SESSION_TOKEN"
Response:
[
{
"id": "uuid",
"name": "GitHub Actions",
"public_id": "bb_pat_abc123...",
"scopes": ["read", "generate"],
"project_id": null,
"created_at": "2026-10-01T10:00:00Z",
"expires_at": "2027-01-01T10:00:00Z",
"last_used_at": "2026-10-24T15:30:00Z",
"revoked_at": null
}
]
Note: The actual token value (bb_pat_xxx) is never returned. Only the last 8 chars (public_id).
Check Token Activity
See last_used_at to find unused tokens.
Never used: "last_used_at": null
Used recently: "last_used_at": "2026-10-24T15:30:00Z"
Revoke a Token
Dashboard: Account → API Tokens → click revoke icon
API:
curl -X DELETE https://api.builder.dumbpotato.com/account/tokens/{token_id} \
-H "Authorization: Bearer $SESSION_TOKEN"
Effect: Immediate. All requests with that token fail with 401 Unauthorized.
Limits
Per-User Limits
- Max active tokens: 25
- Max scopes per token: 8 (you'll never need this many)
- Max expiry: 365 days
- Min expiry: 1 day
To create a 26th token: Revoke one first.
Can't Do With Tokens
- ❌ Create more API tokens (must use browser session)
- ❌ Access admin console (
/admin/*) - ❌ Reset own password
- ❌ Delete own account
Reason: These are sensitive operations requiring active login.
Troubleshooting
401 Unauthorized
Causes:
- Token expired
- Token revoked
- Token not copied correctly (check for extra spaces)
- Using token on admin endpoint (not supported)
Fix:
# Check token in dashboard (Account → API Tokens)
# See if it's expired or revoked
# If yes, create new token
403 Forbidden
Causes:
- Token missing required scope
- Example: Using
read-only token forPOST /projects
- Example: Using
- Token pinned to different project
- Viewer trying to write
Fix:
# Check token scopes
# Ensure operation matches scope:
# - GET = read
# - POST/PUT/PATCH/DELETE = write
# - /generate/download = generate
Token Not Working on Admin Console
Expected behavior. API tokens only work on customer endpoints.
Admin console requires admin session login (separate authentication).
Rotation Strategy
When to Rotate
- Every 90 days (best practice)
- Immediately if:
- Token leaked (committed to Git, posted in Slack)
- Team member left
- Suspected compromise
How to Rotate
- Create new token with same scopes
- Update everywhere old token is used:
- GitHub Secrets
- Environment variables
- CI/CD configs
- Test with new token
- Revoke old token
- Update documentation
Automation
# Script to remind you to rotate
# Add to cron: 0 9 1 * * /path/to/remind-rotate.sh
if [ $(curl -s https://api.builder.dumbpotato.com/account/tokens \
-H "Authorization: Bearer $TOKEN" \
| jq '[.[] | select(.last_used_at != null)] | length') -gt 0 ]; then
echo "Tokens older than 90 days: rotate them!"
fi
Audit Trail
Every token operation is logged:
- Token creation (with scopes, expiry)
- Token usage (every API call, with
last_used_atupdate) - Token revocation
View audit log: Admin Console → Audit (admin-only)
What's logged:
- Who created/revoked
- When
- From which IP
- Which project (if pinned)
NOT logged:
- The token value itself
- API request bodies
Examples
GitHub Actions
name: Generate Backend
on: [push]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- name: Download Backend
run: |
curl -X GET https://builder.yourdomain.com/projects/$PROJECT_ID/generate/download \
-H "Authorization: Bearer $\{\{ secrets.BB_API_TOKEN \}\}" \
-o backend.zip
unzip backend.zip
- name: Deploy
run: |
cd backend
# Your deployment steps
Setup:
- Create token with
["read", "generate"]scopes - Add to GitHub: Settings → Secrets → New secret
- Name:
BB_API_TOKEN - Value:
bb_pat_xxx
GitLab CI
generate:
script:
- curl -X GET https://builder.yourdomain.com/projects/$PROJECT_ID/generate/download
-H "Authorization: Bearer $BB_API_TOKEN"
-o backend.zip
variables:
BB_API_TOKEN: $BB_API_TOKEN # Set in GitLab CI/CD variables
Local Script
#!/bin/bash
# ~/.config/builder-backend/generate.sh
set -e
# Token from environment or config file
BB_TOKEN=${BB_TOKEN:-$(cat ~/.config/builder-backend/token)}
PROJECT_ID=${1:?Usage: $0 PROJECT_ID}
curl -X GET https://builder.yourdomain.com/projects/$PROJECT_ID/generate/download \
-H "Authorization: Bearer $BB_TOKEN" \
-o "backend-$(date +%Y%m%d).zip"
echo "Downloaded: backend-$(date +%Y%m%d).zip"
Next Steps
- API Quickstart - use your token
- API Reference - all endpoints
- CI/CD Integration - automate deployments