Skip to content

Authentication

Learn how to authenticate API requests using API keys.

Overview

The Bedrock Billing API uses API keys for authentication. API keys provide secure, organization-scoped access to API resources.


Authentication Method

API Keys

Best for: Backend services, CLI tools, automated scripts, data pipelines

How it works: 1. Organization admin generates an API key in the web UI 2. The key is shown once and must be stored securely 3. Include the key in the X-API-Key header or Authorization header on API requests

Key Format:

sk_live_<43_random_characters>

Example: sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

Security Features:

  • HMAC-SHA256 hashing - Keys are hashed with a server-side pepper before storage
  • Prefix indexing - Fast lookup using key prefix (first 20 characters)
  • Constant-time comparison - Prevents timing attacks
  • One-time display - Full key shown only once during creation
  • Revocation - Keys can be deactivated without deletion
  • Usage tracking - Last used timestamp recorded

Usage:

# X-API-Key header (recommended)
curl -H "X-API-Key: sk_live_abc123..." \
  https://api.example.com/api/v1/fee-schedules/search?code=99213

# Authorization header (alternative)
curl -H "Authorization: sk_live_abc123..." \
  https://api.example.com/api/v1/fee-schedules/search?code=99213

Generate an API Key (UI)

To create an API key in the UI:

  1. Sign in as an organization admin.
  2. Open User Settings.
  3. Go to API Keys.
  4. Click Create API Key.

⚠️ Important: The full key is shown only once. Copy it and store it securely.


Organization Context & Row-Level Security

API keys provide organization-scoped access:

  • Organization ID stored with the key at creation time
  • Role set to api_key (treated as member for most operations)
  • Inherits organization of the admin who created the key

Row-Level Security (RLS):

All database queries automatically filter by organization:

SELECT set_config('app.current_org', :org_id, true)

This ensures users only access data belonging to their organization.


Best Practices

For API Keys

DO: - Store keys in environment variables or secret managers (AWS Secrets Manager, HashiCorp Vault) - Rotate keys regularly (quarterly or after security incidents) - Use descriptive names to identify key purpose - Monitor last_used_at timestamps for anomalies - Revoke unused keys promptly - Create separate keys for dev/staging/production

DON'T: - Commit keys to version control - Share keys between projects or environments - Use the same key across multiple services - Log full API keys (only log prefixes)

Security Checklist

  • Enable HTTPS/TLS for all API requests
  • Rotate API keys quarterly
  • Monitor key usage via last_used_at timestamps
  • Revoke keys immediately after security incidents
  • Use principle of least privilege (create keys only when needed)
  • Document which services use which keys
  • Set up alerts for unusual API activity

Common Errors

401 Unauthorized

Cause: Missing or invalid authentication

Solutions: - Verify Authorization or X-API-Key header is present - Check for typos in the API key - Ensure JWT token hasn't expired - Verify key hasn't been revoked (is_active: false)

Example Error:

{
  "detail": "No valid authentication provided"
}

400 Invalid API Key Format

Cause: API key doesn't match expected format

Solutions: - Verify key starts with sk_live_ - Check for whitespace or newlines - Ensure complete key was copied (not truncated)

Example Error:

{
  "detail": "Invalid API key format"
}

Rate Limiting

API keys are subject to rate limiting:

  • Limit: 100 requests per minute per user/key
  • Headers: Check X-RateLimit-Remaining and X-RateLimit-Reset in responses
  • 429 Status: Returned when limit exceeded

Handling Rate Limits:

import time
import requests

def make_request_with_retry(url, headers):
    response = requests.get(url, headers=headers)

    if response.status_code == 429:
        # Wait for rate limit reset
        retry_after = int(response.headers.get('Retry-After', 60))
        time.sleep(retry_after)
        return make_request_with_retry(url, headers)

    return response

Support & Resources


FAQ

Q: How do I rotate API keys without downtime?

A: Create a new key, update configurations to use it, monitor for 24-48 hours, then revoke the old key.

Q: What happens if my API key is compromised?

A: Immediately revoke the key and create a new one via the org admin UI.

Q: Can I set expiration dates for API keys?

A: Not currently. Manual revocation is required. Monitor last_used_at and revoke inactive keys.

Q: Do API keys inherit user permissions?

A: API keys inherit organization-level access but are treated as member role for permission checks (not admin). They access all org data but can't manage other API keys.