CSTM-2 Developer API
The world's most advanced career-native AI platform. Seven independent model families, fully isolated credentials, OpenAI-compatible interface.
Quick Start
Go from zero to your first API call in under 3 minutes.
Open the API Key Manager
Go to the API Key Manager tab, choose a model family, and generate your credentials — no separate sign-up required.
Generate model-specific API keys
Each model family has isolated credentials. A cstm_lm_ key only works on CareerLM endpoints.
Make your first call
Use the code examples below or the interactive playground to make a live request.
Scale with confidence
Rate limits, usage analytics, and webhook events keep you in control at any scale.
# Install nothing — just curl
curl https://api.careerstudiomax.com/v1/careerlm/chat \
-H "Authorization: Bearer cstm_lm_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role":"user","content":"Write a cover letter for a Senior Product Manager role"}],
"career_context": "Product Management",
"country": "UK"
}'
Model Overview
Authentication
CSTM-2 uses model-isolated API keys. Every model family has its own key prefix — a CareerLM key cannot access CareerVision endpoints, and vice versa.
Key Prefixes
cstm_lm_sk_lm_cstm_vc_sk_vc_cstm_vi_sk_vi_cstm_em_sk_em_cstm_ag_sk_ag_cstm_sc_sk_sc_cstm_wb_sk_wb_Usage
Authorization: Bearer cstm_lm_Kx9mPqR8vT2nLsY5wBrD7...
401 WRONG_MODEL_KEY, not a generic auth error.
This is by design — it tells you exactly which model's key you need.
{
"code": "WRONG_MODEL_KEY",
"message": "This endpoint requires a careervision key (prefix: cstm_vi_)"
}
API Key Manager
Generate New Credentials
Your Keys
Using Your API Keys
Everything you need to know about generating, securing, rotating, and troubleshooting CSTM-2 API credentials.
Key Anatomy
Every CSTM-2 key encodes its purpose in its prefix:
cstm_lm_Kx9mPqR8vT2nLsY5wBrD7hJcF1eNgA0iUoXvQz
│ │ └─── random 32-char base-58 token (cryptographically secure)
│ └────── model family identifier
└────────────── CSTM-2 platform prefix
cstm_lm_ → CareerLM cstm_vc_ → CareerVoice
cstm_vi_ → CareerVision cstm_em_ → CareerEmbed
cstm_ag_ → CareerAgent cstm_sc_ → CareerScore
cstm_wb_ → CareerWebAPI
Your Three Credentials
cstm_lm_Authorization header on every request. Safe for server-side code.sk_lm_Server-to-server signing. Never expose in client-side or browser environments.wh_lm_Validates HMAC-SHA256 signatures on incoming webhook payloads.Making a Request
Authorization: Bearer cstm_lm_YOUR_KEY ← model-specific key
Content-Type: application/json
Optional:
X-Request-ID: your-trace-id ← echoed back for tracing
X-End-User-ID: user-123 ← per-user rate limit attribution
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1720000060 ← Unix timestamp when window resets
X-CareerStudio-Model: careerlm
X-Request-ID: req_abc123
Security Best Practices
Never hardcode keys in source code
Use environment variables. Add .env to .gitignore before your first commit.
IP-whitelist production keys
Set ipWhitelist to your server's egress IPs. Requests from unlisted IPs return 403 IP_NOT_WHITELISTED.
Set expiry dates on temporary keys
Use expiresAt for partner integrations and hackathon keys. Expired keys return 401 KEY_EXPIRED — not a generic error.
Rotate on suspected compromise
Hit Rotate in the API Key Manager. The old key is invalidated instantly; model ID and plan settings carry over to the new key.
One key per integration, not per user
Use X-End-User-ID header for per-user attribution. Create separate keys for prod, staging, CI, and external partners.
Zero-Downtime Key Rotation
Generate a second key
You can have up to 10 active keys per model. Both accept requests simultaneously.
Deploy the new key
Update your env var in staging, verify, then roll to production while traffic is still split.
Revoke the old key
Once migration is complete, revoke. All old-key requests immediately return 401 KEY_REVOKED.
Handling 429 — Exponential Backoff
async function callWithRetry(fn, maxRetries = 4) {
for (let i = 0; i < maxRetries; i++) {
try { return await fn(); }
catch (err) {
if (err.status !== 429) throw err;
const reset = err.headers?.get('x-ratelimit-reset');
const wait = reset ? Math.max(0, Number(reset) * 1000 - Date.now()) : (2 ** i) * 1000;
await new Promise(r => setTimeout(r, wait));
}
}
throw new Error('Max retries exceeded');
}
Streaming Responses (SSE)
CareerLM and CareerAgent support Server-Sent Events. Append /stream to any endpoint path:
const res = await fetch('/api/cstm2/v1/careerlm/chat/stream', {
method: 'POST',
headers: { Authorization: 'Bearer cstm_lm_YOUR_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: [{ role: 'user', content: 'Write a cover letter' }] }),
});
const reader = res.body.getReader(), dec = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
for (const line of dec.decode(value).split('\n')) {
if (!line.startsWith('data:') || line === 'data: [DONE]') continue;
const chunk = JSON.parse(line.slice(6));
process.stdout.write(chunk.choices?.[0]?.delta?.content ?? '');
}
}
Error Codes
All CSTM-2 endpoints return structured JSON errors. The code field is machine-readable; message is human-readable.
Rate Limits
Rate limits are enforced per API key. Response headers tell you exactly how many requests remain in the current window.
| Plan | RPM (standard) | RPM (CareerVoice) | RPM (CareerVision) | Max Keys/Model |
|---|---|---|---|---|
| Starter | 60 | 30 | 20 | 2 |
| Growth | 300 | 150 | 80 | 5 |
| Pro | 1,000 | 500 | 300 | 10 |
| Enterprise | 5,000+ | 2,000+ | 1,000+ | Unlimited |
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1720000060
Webhooks
Verify webhook payloads using HMAC-SHA256 with your model-specific webhook secret.
CareerStudio-Signature: t=1720000060,v1=5257a869559d4...
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const [tPart, vPart] = signature.split(',');
const t = tPart.replace('t=', '');
const v1 = vPart.replace('v1=', '');
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${JSON.stringify(payload)}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(v1, 'hex'),
Buffer.from(expected, 'hex')
);
}
SDKs & Libraries
CSTM-2 endpoints are OpenAI-compatible — any OpenAI SDK works by pointing baseURL at the CSTM-2 host. Below are install commands and minimal examples for every supported language.
npm install @careerstudiomax/cstm2 · pip install careerstudiomax-cstm2.
The rest aren't published to their package registries yet — source and install instructions: github.com/owolat4real/career-studio/sdks.
https://api.careerstudiomax.com/api/cstm2
/v1/<modelid>/ — e.g. /v1/careerlm/chat, /v1/careerscore/score.JavaScript / TypeScript
npm install openai # OpenAI-compatible SDK (recommended)
# or: yarn add openai
# or: pnpm add openai
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'cstm_lm_YOUR_KEY',
baseURL: 'https://api.careerstudiomax.com/api/cstm2/v1/careerlm',
});
const res = await client.chat.completions.create({
model: 'careerlm-large',
messages: [{ role: 'user', content: 'Write a cover letter for a Senior PM role' }],
});
console.log(res.choices[0].message.content);
Python
pip install openai # OpenAI-compatible SDK
# or: pip install requests # raw HTTP
from openai import OpenAI
client = OpenAI(
api_key = "cstm_lm_YOUR_KEY",
base_url = "https://api.careerstudiomax.com/api/cstm2/v1/careerlm",
)
res = client.chat.completions.create(
model = "careerlm-large",
messages = [{"role":"user","content":"Write a cover letter for a Senior PM role"}],
)
print(res.choices[0].message.content)
Go
go get github.com/openai/openai-go # OpenAI-compatible Go SDK
# or use net/http directly — no external dependency needed
Ruby
gem 'ruby-openai' # OpenAI-compatible
# or: gem 'faraday' # raw HTTP
require 'openai'
client = OpenAI::Client.new(
access_token: 'cstm_lm_YOUR_KEY',
uri_base: 'https://api.careerstudiomax.com/api/cstm2/v1/careerlm'
)
resp = client.chat(
parameters: { model: 'careerlm-large', messages: [{ role: 'user', content: 'Write a cover letter' }] }
)
puts resp.dig('choices', 0, 'message', 'content')
PHP
composer require openai-php/client # OpenAI-compatible
# or: composer require guzzlehttp/guzzle # raw HTTP
use OpenAI;
$client = OpenAI::factory()
->withApiKey('cstm_lm_YOUR_KEY')
->withBaseUri('https://api.careerstudiomax.com/api/cstm2/v1/careerlm')
->make();
$result = $client->chat()->create([
'model' => 'careerlm-large',
'messages' => [['role' => 'user', 'content' => 'Write a cover letter']],
]);
echo $result->choices[0]->message->content;
Java
<!-- Maven pom.xml -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
// Gradle build.gradle
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
Rust
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
C# / .NET
dotnet add package OpenAI # OpenAI-compatible .NET SDK
# or use System.Net.Http.HttpClient directly — built-in
Swift
// Uses URLSession — no external package required
// For OpenAI-compatible SDK:
.package(url: "https://github.com/MacPaw/OpenAI.git", from: "0.3.0")
Kotlin (Android / JVM)
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.json:json:20240303")
Dart / Flutter
dependencies:
http: ^1.2.0 # native HTTP client — no bloat
Elixir
defp deps do
[{:req, "~> 0.5"}] # modern HTTP client with JSON built-in
end
Shell / Bash
# Linux/macOS — usually pre-installed
brew install curl jq # macOS (Homebrew)
apt-get install curl jq # Debian/Ubuntu
PowerShell
# PowerShell 7+ (pwsh) — Invoke-RestMethod is built-in, no install needed
# Install PowerShell 7: https://aka.ms/pscore6
Platform Status
Changelog
v2.1.0 — CareerVideo (CSVM-1)
New model family: video career-intelligence extraction from real YouTube transcripts, AI-generated animation grounded in a video's own insight, and Cinematic Reel — a multi-scene, narrated, multilingual reel directed by an LLM reasoning layer. 5 new endpoints under cstm_vd_* keys.
v2.0.0 — CSTM-2 Release
Complete credential isolation architecture. Each model family now has independent API keys, secret keys, and webhook secrets. Wrong-prefix detection with WRONG_MODEL_KEY error code. 7 new model-scoped endpoints.
v1.5.0 — CAMP Engine Integration
CAMP engine promoted to ENGINE 0. All inference routes attempt CAMP first with intelligent model routing (nano → xl based on prompt complexity). Groq pool (7 models) as fallback.
v1.4.0 — CareerScore v2
Batch scoring added (up to 10 items). ATS score separated from overall score. Rewrite suggestions generated per scored item.
v1.0.0 — Initial Release
CareerLM, CareerEmbed, CareerScore, CareerAgent, CareerVoice, CareerVision, CareerWebAPI. CAMP key integration. 15-module cover letter platform.