Sign in to CareerStudioMax

CSTM-2 Developer API

The world's most advanced career-native AI platform. Seven independent model families, fully isolated credentials, OpenAI-compatible interface.

7
Model Families
13
Model Variants
Engines Online Now
Live Avg Latency

Quick Start

Go from zero to your first API call in under 3 minutes.

1

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.

2

Generate model-specific API keys

Each model family has isolated credentials. A cstm_lm_ key only works on CareerLM endpoints.

3

Make your first call

Use the code examples below or the interactive playground to make a live request.

4

Scale with confidence

Rate limits, usage analytics, and webhook events keep you in control at any scale.

cURL — first call
# 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

ModelAPI Key PrefixSecret Key Prefix
🧠 CareerLMcstm_lm_sk_lm_
🎙️ CareerVoicecstm_vc_sk_vc_
🎬 CareerVisioncstm_vi_sk_vi_
🔍 CareerEmbedcstm_em_sk_em_
🤖 CareerAgentcstm_ag_sk_ag_
🏆 CareerScorecstm_sc_sk_sc_
🌐 CareerWebAPIcstm_wb_sk_wb_

Usage

Authorization Header
Authorization: Bearer cstm_lm_Kx9mPqR8vT2nLsY5wBrD7...
⚠️ Model isolation is enforced at the middleware level. Using a CareerLM key on a CareerVision endpoint returns 401 WRONG_MODEL_KEY, not a generic auth error. This is by design — it tells you exactly which model's key you need.
Error Response — wrong model key
{
  "code": "WRONG_MODEL_KEY",
  "message": "This endpoint requires a careervision key (prefix: cstm_vi_)"
}

API Key Manager

Generate New Credentials

Your Keys

Loading 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:

Key Structure
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

CredentialPrefixPurpose
API Keycstm_lm_Authorization header on every request. Safe for server-side code.
Secret Keysk_lm_Server-to-server signing. Never expose in client-side or browser environments.
Webhook Secretwh_lm_Validates HMAC-SHA256 signatures on incoming webhook payloads.
⚠️ Shown once only. Secret Key and Webhook Secret are never retrievable after generation. Store them immediately in a secrets vault or password manager.

Making a Request

Required Headers — every endpoint
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
CSTM-2 Response Headers
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

1

Generate a second key

You can have up to 10 active keys per model. Both accept requests simultaneously.

2

Deploy the new key

Update your env var in staging, verify, then roll to production while traffic is still split.

3

Revoke the old key

Once migration is complete, revoke. All old-key requests immediately return 401 KEY_REVOKED.

Handling 429 — Exponential Backoff

JavaScript — Retry Helper
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:

JavaScript — SSE Streaming
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.

MISSING_API_KEY401Authorization header missing or not Bearer format
WRONG_MODEL_KEY401Key prefix does not match this model family's endpoint
INVALID_API_KEY401Key not found in database or bcrypt comparison failed
KEY_REVOKED401Key has been manually revoked via dashboard or API
KEY_EXPIRED401Key's expiry date has passed — regenerate via dashboard
IP_NOT_WHITELISTED403Client IP address not in the key's allowed whitelist
RATE_LIMIT_EXCEEDED429RPM limit exceeded — check X-RateLimit-Reset header
INVALID_REQUEST400Required field missing or malformed request body
BATCH_TOO_LARGE400Batch request exceeds maximum item count (10)
INFERENCE_ERROR500AI model inference failed — retry with exponential backoff
SERVICE_UNAVAILABLE503Model engine not configured on this deployment

Rate Limits

Rate limits are enforced per API key. Response headers tell you exactly how many requests remain in the current window.

PlanRPM (standard)RPM (CareerVoice)RPM (CareerVision)Max Keys/Model
Starter6030202
Growth300150805
Pro1,00050030010
Enterprise5,000+2,000+1,000+Unlimited
Rate Limit Response Headers
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.

Signature Header Format
CareerStudio-Signature: t=1720000060,v1=5257a869559d4...
Node.js — Verify Webhook
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.

✨ New: Dedicated SDKs for all 12 languages
Full clients for every CSTM-2 endpoint — including streaming — in JavaScript/TypeScript, Python, Go, Ruby, PHP, Java, Rust, C#, Swift, Kotlin, Dart, and Elixir. JavaScript/TypeScript and Python are live: 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.
Base URL
https://api.careerstudiomax.com/api/cstm2
All model endpoints are under /v1/<modelid>/ — e.g. /v1/careerlm/chat, /v1/careerscore/score.

JavaScript / TypeScript

npm install
npm install openai        # OpenAI-compatible SDK (recommended)
# or: yarn add openai
# or: pnpm add openai
TypeScript — OpenAI SDK
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
pip install openai          # OpenAI-compatible SDK
# or: pip install requests  # raw HTTP
Python — OpenAI SDK
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
go get github.com/openai/openai-go      # OpenAI-compatible Go SDK
# or use net/http directly — no external dependency needed

Ruby

Gemfile
gem 'ruby-openai'          # OpenAI-compatible
# or: gem 'faraday'         # raw HTTP
Ruby — ruby-openai gem
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
composer require openai-php/client   # OpenAI-compatible
# or: composer require guzzlehttp/guzzle  # raw HTTP
PHP — openai-php/client
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 / Gradle
<!-- 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

Cargo.toml
[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
dotnet add package OpenAI        # OpenAI-compatible .NET SDK
# or use System.Net.Http.HttpClient directly — built-in

Swift

Package.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)

build.gradle.kts
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.json:json:20240303")

Dart / Flutter

pubspec.yaml
dependencies:
  http: ^1.2.0        # native HTTP client — no bloat

Elixir

mix.exs
defp deps do
  [{:req, "~> 0.5"}]   # modern HTTP client with JSON built-in
end

Shell / Bash

Dependencies
# Linux/macOS — usually pre-installed
brew install curl jq      # macOS (Homebrew)
apt-get install curl jq   # Debian/Ubuntu

PowerShell

Requirements
# PowerShell 7+ (pwsh) — Invoke-RestMethod is built-in, no install needed
# Install PowerShell 7: https://aka.ms/pscore6

Platform Status

Loading status...

Changelog

v2.1.0 — CareerVideo (CSVM-1)

July 2026

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

May 2026

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

April 2026

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

March 2026

Batch scoring added (up to 10 items). ATS score separated from overall score. Rewrite suggestions generated per scored item.

v1.0.0 — Initial Release

January 2026

CareerLM, CareerEmbed, CareerScore, CareerAgent, CareerVoice, CareerVision, CareerWebAPI. CAMP key integration. 15-module cover letter platform.