Skip to main content

Authentication

Complete guide to authenticating with the B4M Completions API and securing your integration.

Authentication Methods

The API supports two authentication methods, which are tried in this order:

Use an API key for production integrations and server-to-server communication. API keys provide fine-grained access control through scopes and rate limiting.

Header formats (any of these work):

# Option 1: X-API-Key header (recommended)
X-API-Key: b4m_live_xxxxxxxxxxxx

# Option 2: Authorization with ApiKey prefix
Authorization: ApiKey b4m_live_xxxxxxxxxxxx

# Option 3: Authorization with Bearer prefix (if key starts with b4m_)
Authorization: Bearer b4m_live_xxxxxxxxxxxx

Example request:

curl -X POST https://app.bike4mind.com/api/ai/v1/completions \
-H "X-API-Key: b4m_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"model": "claude-3-5-sonnet", "messages": [...]}'

2. JWT Token (Fallback)

Use JWT tokens for user-context requests where you need to authenticate on behalf of a specific user.

Header format:

Authorization: Bearer <jwt-token>

Example request:

curl -X POST https://app.bike4mind.com/api/ai/v1/completions \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{"model": "claude-3-5-sonnet", "messages": [...]}'

Obtaining an API Key

Follow these steps to create an API key:

Step 1: Navigate to API Keys Settings

  1. Log in to your B4M account
  2. Go to SettingsAPI Keys
  3. Click Create API Key

Step 2: Configure API Key

Name your key:

  • Give it a descriptive name (e.g., "Production API", "Development Server")
  • This helps you identify keys later

Select required scopes:

The API requires at least one of these scopes:

ScopeDescription
ai:generateFull AI generation capabilities (recommended)
ai:chatChat-specific operations

Configure rate limits:

Set appropriate rate limits for your use case:

  • Requests per minute - Limit short-term burst traffic
  • Requests per day - Control daily usage

Step 3: Save and Secure Your Key

  1. Click Create
  2. Copy your API key immediately - it's only shown once
  3. Store it securely (see Security Best Practices below)
Important

API keys are shown only once during creation. If you lose your key, you'll need to create a new one.


Required Scopes

Your API key must have at least one of these scopes:

ai:generate

Full AI generation capabilities. Recommended for most use cases.

Grants access to:

  • AI completions
  • All model types
  • Tool calling
  • Extended thinking

ai:chat

Chat-specific operations.

Grants access to:

  • Chat-based completions
  • Conversational AI features

Authentication Flow

The API checks authentication in this order:

1. Check for API key in headers
├─ X-API-Key header
├─ Authorization: ApiKey
└─ Authorization: Bearer b4m_*

2. If API key found:
├─ Validate key
├─ Check required scopes (ai:generate or ai:chat)
├─ Apply rate limiting
└─ Proceed to request

3. If no API key found:
├─ Check for JWT token
├─ Validate JWT
└─ Proceed to request

4. If neither found:
└─ Return 401 Unauthorized

Security Best Practices

Never Commit API Keys to Version Control

❌ Bad:

// config.js
export const API_KEY = 'b4m_live_xxxxxxxxxxxx'; // DON'T DO THIS

✅ Good:

// config.js
export const API_KEY = process.env.B4M_API_KEY;

Add API keys to .gitignore:

# .gitignore
.env
.env.local
.env.production

Use Environment Variables

Store API keys in environment variables, never in code.

Node.js:

const apiKey = process.env.B4M_API_KEY;

Python:

import os
api_key = os.environ.get("B4M_API_KEY")

Docker:

docker run -e B4M_API_KEY=b4m_live_xxx myapp

Example .env file:

# .env
B4M_API_KEY=b4m_live_xxxxxxxxxxxx

Rotate Keys Regularly

  1. Generate a new API key
  2. Update your application to use the new key
  3. Test thoroughly
  4. Revoke the old key

Recommended rotation schedule:

  • Production: Every 90 days
  • Development: Every 180 days
  • Immediately after: suspected compromise, team member departure

Monitor Usage for Anomalies

Regularly check your API usage for unexpected patterns:

  • Unusual request volume - Spike in requests
  • Failed authentication attempts - Possible key compromise
  • Requests from unexpected IPs - Unauthorized usage
  • Rate limit violations - Potential abuse

Use Minimal Required Scopes

Grant only the scopes your application needs:

❌ Bad: Granting all scopes "just in case"

✅ Good: Only granting ai:generate if that's all you need

This principle of least privilege limits damage if a key is compromised.

Implement Server-Side Proxy

Never expose API keys in client-side code. Instead, proxy requests through your backend.

❌ Bad: Client-side code with API key

// Frontend code (NEVER DO THIS)
const apiKey = 'b4m_live_xxxxxxxxxxxx'; // Exposed to users!

fetch('https://app.bike4mind.com/api/ai/v1/completions', {
headers: { 'X-API-Key': apiKey }
});

✅ Good: Proxy through your backend

// Frontend code
fetch('/api/my-completion-proxy', {
headers: { 'Authorization': `Bearer ${userJWT}` }
});

// Backend code (Node.js/Express)
app.post('/api/my-completion-proxy', authenticateUser, async (req, res) => {
// Validate user has permission
if (!req.user.canUseAI) {
return res.status(403).json({ error: 'Forbidden' });
}

// Forward to B4M API with YOUR API key (server-side)
const response = await fetch('https://app.bike4mind.com/api/ai/v1/completions', {
method: 'POST',
headers: {
'X-API-Key': process.env.B4M_API_KEY, // Safe on server
'Content-Type': 'application/json',
},
body: JSON.stringify(req.body)
});

// Stream response back to client
response.body.pipe(res);
});

Restrict API Key Usage by IP

If your application runs on a fixed set of servers, restrict API key usage to those IPs (feature availability may vary - contact support for details).

Use Separate Keys for Environments

Use different API keys for each environment:

  • Production: b4m_live_xxxxxxxxxxxx
  • Staging: b4m_test_xxxxxxxxxxxx
  • Development: b4m_test_xxxxxxxxxxxx

This way, if a development key is compromised, your production environment remains secure.


Common Authentication Errors

401 Unauthorized

Error message: "Authentication failed. Provide a valid API key or JWT token."

Causes:

  • Missing authentication header
  • Invalid API key format
  • Expired JWT token
  • API key revoked

Solutions:

  1. Verify API key is correctly set in environment variables
  2. Check API key format (should start with b4m_live_ or b4m_test_)
  3. Ensure header format is correct (X-API-Key: <key>)
  4. Regenerate API key if expired or revoked

403 Forbidden

Error message: "API key does not have permission for AI completions"

Causes:

  • API key missing required scopes (ai:generate or ai:chat)

Solutions:

  1. Go to Settings → API Keys
  2. Edit your API key
  3. Add ai:generate or ai:chat scope
  4. Save changes

Authentication Testing

Testing with curl

# Test authentication
curl -X POST https://app.bike4mind.com/api/ai/v1/completions \
-H "X-API-Key: $B4M_API_KEY" \
-H "Content-Type: application/json" \
--no-buffer \
-d '{
"model": "claude-3-5-sonnet",
"messages": [{"role": "user", "content": "test"}]
}'

Expected success: SSE stream with content events

Expected failure (invalid key):

HTTP/1.1 401 Unauthorized
{"type":"error","message":"Authentication failed. Provide a valid API key or JWT token."}

Testing Programmatically

JavaScript:

async function testAuth(apiKey) {
try {
const response = await fetch('https://app.bike4mind.com/api/ai/v1/completions', {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'claude-3-5-sonnet',
messages: [{ role: 'user', content: 'test' }]
})
});

if (response.ok) {
console.log('✓ Authentication successful');
} else {
console.error(`✗ Authentication failed: ${response.status}`);
}
} catch (err) {
console.error('✗ Request failed:', err);
}
}

testAuth(process.env.B4M_API_KEY);

Python:

import os
import requests

def test_auth(api_key):
try:
response = requests.post(
'https://app.bike4mind.com/api/ai/v1/completions',
headers={
'X-API-Key': api_key,
'Content-Type': 'application/json',
},
json={
'model': 'claude-3-5-sonnet',
'messages': [{'role': 'user', 'content': 'test'}]
},
stream=True
)

if response.ok:
print('✓ Authentication successful')
else:
print(f'✗ Authentication failed: {response.status_code}')
except Exception as e:
print(f'✗ Request failed: {e}')

test_auth(os.environ.get('B4M_API_KEY'))

Next Steps