Getting Started
Substacker provides two ways to track OpenAI API usage:
SDK Wrapper (Recommended)
Automatically intercept OpenAI calls and track usage with one line of code.
REST API
Manually POST usage data for custom integrations or non-OpenAI providers.
Real-time Dashboard
View team costs, model usage, and anomaly alerts in real-time.
API Key Management
Create and revoke API keys from the admin dashboard.
Quick Links
- Production URL: http://localhost:8000
- Admin Dashboard: http://localhost:8000/admin/dashboard
- SDK Keys: http://localhost:8000/admin/sdk-keys
- Health Check: http://localhost:8000/health
SDK Integration (Python)
Installation
pip install substacker-sdk
Basic Usage
from openai import OpenAI
from substacker import track_openai
# Initialize OpenAI client
openai_client = OpenAI(api_key="your-openai-api-key")
# Wrap with Substacker tracking
openai = track_openai(
openai_client,
api_key="sk_substacker_xxxx", # Get from admin dashboard → SDK Keys
team="engineering"
# endpoint defaults to http://localhost:8000/api/track
)
# Use OpenAI normally - tracking happens automatically
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "What is machine learning?"}
]
)
print(response.choices[0].message.content)
# Tracking sent silently in background
Advanced Configuration
from openai import OpenAI
from substacker import track_openai
openai = track_openai(
OpenAI(api_key="sk-..."),
api_key="sk_substacker_xxxx",
team="data-science",
endpoint="http://localhost:8000/api/track" # Override if needed
)
REST API
Authentication
All API requests require the X-API-Key header:
curl http://localhost:8000/api/track \
-H "X-API-Key: sk_substacker_xxxx" \
-H "Content-Type: application/json" \
-d '{...}'
Track API Usage
Log an API call to Substacker.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
team |
string | Yes | Team name for cost attribution (e.g., "engineering", "marketing") |
model |
string | Yes | Model name (e.g., "gpt-4", "gpt-3.5-turbo", "claude-3-opus") |
prompt_tokens |
integer | Yes | Number of tokens in prompt |
completion_tokens |
integer | Yes | Number of tokens in completion |
response_time |
float | No | Response time in seconds (optional) |
provider |
string | No | Provider (e.g., "openai", "anthropic", "google") |
Example Request
curl -X POST http://localhost:8000/api/track \
-H "X-API-Key: sk_substacker_abc123..." \
-H "Content-Type: application/json" \
-d '{
"team": "engineering",
"model": "gpt-4",
"prompt_tokens": 150,
"completion_tokens": 250,
"response_time": 2.3
}'
Example Response (Success)
{
"status": "tracked",
"cost": 0.0125,
"provider": "openai",
"model_recognized": true
}
Example Response (Unknown Model)
{
"status": "tracked",
"cost": 0.0,
"provider": "openai",
"model_recognized": false,
"warning": "Unknown model 'gpt-5-future'. Cost set to $0. Please update pricing data or contact support."
}
Get Real-time Dashboard Data
Fetch real-time team cost breakdown and recent usage.
Example Request
curl -X GET http://localhost:8000/api/dashboard/realtime \
-H "X-API-Key: sk_substacker_abc123..."
Example Response
{
"total_cost": 125.45,
"today_cost": 12.30,
"team_breakdown": {
"engineering": 75.20,
"marketing": 35.10,
"data-science": 15.15
},
"recent_activity": [
{
"model": "gpt-4",
"team": "engineering",
"cost": 0.0125,
"timestamp": "2025-10-30T14:23:45Z",
"response_time": 2.3
}
],
"last_updated": "2025-10-30T14:30:12Z"
}
Admin API
Generate API Key
Request
curl -X POST http://localhost:8000/api/generate-key \
-H "Cookie: admin_token=..." \
-d "[email protected]"
Response
{
"success": true,
"api_key": "sk_substacker_abc123...",
"key_prefix": "sk_substacker_abc"
}
Revoke API Key
Request
curl -X POST http://localhost:8000/api/revoke-key \
-H "Cookie: admin_token=..." \
-d "key_prefix=sk_substacker_abc"
Response
{
"success": true,
"message": "Key revoked"
}
Error Codes
| Code | Meaning | Solution |
|---|---|---|
| 401 | Invalid or missing API key | Check X-API-Key header. Regenerate key if expired/revoked. |
| 400 | Missing required fields | Ensure team, model, prompt_tokens, completion_tokens are provided. |
| 429 | Rate limit exceeded | Wait before making next request. Default: 1000 req/min for /api/track. |
| 500 | Server error | Check status page or contact support. |
Code Examples
Python (with SDK)
from openai import OpenAI
from substacker import track_openai
# Create tracked client
client = track_openai(
OpenAI(api_key="sk-..."),
api_key="sk_substacker_...",
team="engineering"
)
# Use normally
for i in range(10):
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": f"Question {i}"}]
)
print(f"Answer: {response.choices[0].message.content}")
Python (REST API)
import requests
api_key = "sk_substacker_..."
endpoint = "http://localhost:8000/api/track"
payload = {
"team": "engineering",
"model": "gpt-4",
"prompt_tokens": 150,
"completion_tokens": 250,
"response_time": 2.3
}
response = requests.post(
endpoint,
json=payload,
headers={"X-API-Key": api_key}
)
print(response.json())
Node.js (REST API)
const axios = require('axios');
const apiKey = 'sk_substacker_...';
const endpoint = 'http://localhost:8000/api/track';
const payload = {
team: 'engineering',
model: 'gpt-4',
prompt_tokens: 150,
completion_tokens: 250,
response_time: 2.3
};
axios.post(endpoint, payload, {
headers: { 'X-API-Key': apiKey }
}).then(response => {
console.log(response.data);
}).catch(error => {
console.error(error.response.data);
});
cURL
curl -X POST http://localhost:8000/api/track \
-H "X-API-Key: sk_substractor_..." \
-H "Content-Type: application/json" \
-d '{
"team": "engineering",
"model": "gpt-4",
"prompt_tokens": 150,
"completion_tokens": 250,
"response_time": 2.3
}'
FAQ
How do I get started?
1. Sign up for an account at the landing page. 2. Go to /admin/dashboard and login. 3. Navigate to SDK Keys. 4. Generate an API key. 5. Integrate with SDK (Python) or REST API.
How is cost calculated?
Costs are based on official OpenAI pricing for each model. Prompt tokens and completion tokens are multiplied by their respective rates. For custom models, contact support.
Can I use Substacker with non-OpenAI providers?
Yes! Use the REST API and set the provider field to "anthropic", "google", or "azure". We'll calculate costs based on each provider's pricing.
What if I need to revoke an API key?
Go to /admin/sdk-keys and click "Revoke" next to the key. It will be immediately deactivated. Any requests using that key will return 401 Unauthorized.
Is tracking synchronous or asynchronous?
The SDK sends tracking asynchronously in the background with a 2-second timeout. Your application will never be blocked by tracking failures.
How often are costs updated?
Costs are logged immediately upon tracking. The real-time dashboard updates in seconds.
What about data privacy?
Substacker never logs prompt/completion text—only token counts and metadata. All data is encrypted in transit (HTTPS) and at rest in Supabase.