Skip to main content

API Keys

API keys allow you to authenticate API requests programmatically without using session cookies. API keys are tenant-scoped and support granular permissions via scopes.

Creating an API Key

Via UI

  1. Navigate to AdminAPI (/admin/api)
  2. Click Create Key
  3. Configure:
    • Name: Descriptive name for the key (required)
    • Scopes: Select permissions (required)
  4. Click Create Key
  5. Copy the key immediately - it’s shown only once and cannot be retrieved later
Security: API keys are displayed only once at creation. If lost, you must create a new key. Store keys securely and never commit them to version control.

Via API

curl -X POST "https://app.betterdata.co/api/admin/api-keys" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API Key",
    "scopes": ["inventory:read", "forecast:read"]
  }'
Response:
{
  "apiKey": {
    "id": "key_123",
    "name": "Production API Key",
    "keyPrefix": "bdk_live_ABC123",
    "last4": "XYZ1",
    "scopes": ["inventory:read", "forecast:read"],
    "status": "ACTIVE",
    "createdAt": "2024-01-01T00:00:00Z"
  },
  "plaintextKey": "bdk_live_ABC123_<random>"
}

Using API Keys

Include the API key in the Authorization header as a Bearer token:
curl -X GET "https://app.betterdata.co/api/inventory/channel-location?locationId=loc_123&page=1&limit=50" \
  -H "Authorization: Bearer bdk_live_ABC123_<your-key>" \
  -H "Content-Type: application/json"

Scopes

API keys support granular permissions via scopes:

Inventory

  • inventory:read - Read inventory data
  • inventory:write - Create/update inventory

Forecasting

  • forecast:read - Read forecasts
  • forecast:write - Create/update forecasts

Planning

  • planning:read - Read planning data
  • planning:write - Create/update plans

Procurement

  • procurement:read - Read procurement data
  • procurement:write - Create/update purchase orders

Shipping

  • shipping:read - Read shipping data
  • shipping:write - Create/update shipments

Reports

  • reports:read - Read reports

Admin

  • admin:read - Read admin data
  • admin:write - Admin operations (tenant admin only)

Wildcards

  • inventory:* - All inventory operations
  • * - All operations (use with caution)

Managing API Keys

List Keys

curl -X GET "https://app.betterdata.co/api/admin/api-keys" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Update Key Metadata

curl -X PATCH "https://app.betterdata.co/api/admin/api-keys/key_123" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Name",
    "scopes": ["inventory:read", "inventory:write"]
  }'

Revoke Key

curl -X POST "https://app.betterdata.co/api/admin/api-keys/key_123/revoke" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Rotate Key

Create a new key and optionally revoke the old one:
curl -X POST "https://app.betterdata.co/api/admin/api-keys/key_123/rotate" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "revokeOld": true
  }'

Security Best Practices

  1. Store securely: Never commit API keys to version control
  2. Use environment variables: Store keys in environment variables or secret management systems
  3. Rotate regularly: Rotate keys periodically (e.g., every 90 days)
  4. Limit scopes: Grant minimum permissions required
  5. Set expiration: Use expiration dates for temporary keys
  6. Monitor usage: Review API key usage logs regularly
  7. Revoke unused keys: Delete keys that are no longer needed

Error Codes

CodeStatusDescription
MISSING_AUTHORIZATION401Authorization header missing
INVALID_API_KEY401API key not found or invalid
REVOKED_API_KEY401API key has been revoked
EXPIRED_API_KEY401API key has expired
INACTIVE_ORGANIZATION403Organization is not active
IP_RESTRICTED403API key not authorized for this IP
INSUFFICIENT_SCOPE403Key lacks required scope

Example: Get Channel × Location ATP Matrix

curl -X GET "https://app.betterdata.co/api/inventory/channel-location?locationId=loc_123&page=1&limit=50" \
  -H "Authorization: Bearer bdk_live_ABC123_<your-key>" \
  -H "Content-Type: application/json"
This requires the inventory:read scope.