CSTM-1 API Reference
The world's first REST API built exclusively on career intelligence. Extract entities, build knowledge graphs, match candidates to jobs, and access 5 precision intelligence heads — all in structured JSON.
http://localhost:3000/api (development) · https://your-domain.com/api (production)
What CSTM-1 can do
- Named Entity Recognition — extract EMPLOYEE, EMPLOYER, RECRUITER, JOB, SKILL, LOCATION, DATE, SALARY entities from any text
- Career Knowledge Graphs — build structured graphs with nodes, edges, clusters, and career scores
- Job Matching — score candidate-to-job compatibility with ATS keyword analysis
- Salary Intelligence — P10–P90 percentiles, negotiation scripts, market trends
- Career Path Prediction — probability-scored next roles, AI disruption risk
- Resume Scoring — ATS score, bullet rewrites, priority fixes
- Skill Gap Analysis — month-by-month learning plan with real resources
Authentication
Every request must include your API key in the X-API-Key header. Generate keys from the Transformer API tab in the app.
# Every request
curl -X POST /api/transformer/v1/extract \
-H "X-API-Key: csk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"text": "Alice Chen is a Senior Engineer at Google in London."}'
Key types
| Prefix | Purpose |
|---|---|
| csk_live_… | Production keys — counts against your quota |
| csk_test_… | Sandbox/development — counts against your quota |
| csk_secret_… | Shown ONCE on creation — use for credential rotation only |
csk_secret_…) is shown exactly once when generated. Store it in a secrets manager. Never commit it to source code.Managing API Keys
Generate a new API key. Requires a logged-in session. Maximum 5 active keys per account.
| Field | Type | Notes |
|---|---|---|
| name | string | optional — label for the key |
| tier | free | pro | enterprise | optional — defaults to free |
| keyType | live | test | optional — defaults to live |
List all API keys for the authenticated user. Secret keys are never returned.
Revoke an API key permanently. This cannot be undone.
Rate Limits & Tiers
🆓 Free
Developer exploration
- 100 requests / day
- 10 requests / minute
- All 4 transformer endpoints
- All 6 intelligence heads
- 90-day usage logs
⚡ Pro — $29/mo
Production applications
- 10,000 requests / day
- 100 requests / minute
- Priority routing
- SLA 99.9%
- Batch processing
🏢 Enterprise
Unlimited capacity
- Unlimited requests
- 1,000 requests / minute
- Private deployment
- Fine-tuning support
- Dedicated SLA
When you hit a limit, the API returns HTTP 429 with a retryAfter field in seconds.
Error Handling
| Status | Meaning | Fix |
|---|---|---|
| 400 | Bad request — missing required field | Check the error field for which field is missing |
| 401 | Authentication required | Pass X-API-Key: csk_live_… header |
| 429 | Rate limit reached | Check retryAfter (seconds) and wait |
| 500 | AI inference failed | Usually transient — retry after 2–3 seconds |
# Error response format
{
"error": "Daily limit reached (100 requests). Resets in ~18h.",
"tier": "free",
"used": 100,
"limit": 100,
"retryAfter": 64800,
"upgrade": "https://careerstudiomax.com/pricing"
}
POST /v1/extract Core NER
Extract career entities from any text. Returns structured entities with confidence scores and relationship graph.
| Field | Type | Notes |
|---|---|---|
| text required | string | Career text to extract from. Max 10,000 characters. |
| options.entityTypes | string[] | Filter: ["EMPLOYEE","SKILL","JOB"…] — omit for all types |
| options.minConfidence | number 0–1 | Filter by minimum confidence score |
curl -X POST http://localhost:3000/api/transformer/v1/extract \
-H "X-API-Key: csk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"text": "Alice Chen is a Senior Engineer at Google in London, earning £120,000.",
"options": { "minConfidence": 0.7 }
}'
import requests
api_key = "csk_live_your_key"
base_url = "http://localhost:3000/api/transformer"
response = requests.post(
f"{base_url}/v1/extract",
headers={"X-API-Key": api_key, "Content-Type": "application/json"},
json={
"text": "Alice Chen is a Senior Engineer at Google in London, earning £120,000.",
"options": {"minConfidence": 0.7}
}
)
data = response.json()
if response.status_code == 200:
entities = data["data"]["entities"]
for entity in entities:
print(f"{entity['type']:12} | {entity['text']:25} | conf: {entity['confidence']:.2f}")
else:
print("Error:", data.get("error"))
const API_KEY = 'csk_live_your_key';
const BASE_URL = 'http://localhost:3000/api/transformer';
async function extractEntities(text, options = {}) {
const res = await fetch(`${BASE_URL}/v1/extract`, {
method: 'POST',
headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ text, options })
});
if (!res.ok) throw new Error((await res.json()).error);
return (await res.json()).data;
}
// Usage
extractEntities('Alice Chen is a Senior Engineer at Google in London.', { minConfidence: 0.7 })
.then(data => {
data.entities.forEach(e => console.log(`[${e.type}] ${e.text} (${(e.confidence*100).toFixed(0)}%)`));
})
.catch(console.error);
// Requires: libcurl + nlohmann/json (https://github.com/nlohmann/json)
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <string>
using json = nlohmann::json;
static size_t writeCallback(char* ptr, size_t size, size_t nmemb, std::string* data) {
data->append(ptr, size * nmemb);
return size * nmemb;
}
std::string cstmExtract(const std::string& text, const std::string& apiKey) {
CURL* curl = curl_easy_init();
std::string response;
json body = {
{"text", text},
{"options", {{"minConfidence", 0.7}}}
};
std::string jsonBody = body.dump();
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, ("X-API-Key: " + apiKey).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:3000/api/transformer/v1/extract");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonBody.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
return response;
}
int main() {
std::string apiKey = "csk_live_your_key";
std::string text = "Alice Chen is a Senior Engineer at Google in London, earning £120,000.";
std::string raw = cstmExtract(text, apiKey);
json result = json::parse(raw);
if (result.contains("data")) {
for (auto& entity : result["data"]["entities"]) {
std::cout << entity["type"].get<std::string>() << "\t"
<< entity["text"].get<std::string>() << "\n";
}
}
return 0;
}
POST /v1/job-match
Match a candidate profile to a job description. Returns match score, verdict, ATS keywords, and hiring probability.
| Field | Type | Notes |
|---|---|---|
| candidateText required* | string | Resume or profile text |
| jobDescription required | string | Full job description |
| candidateEntities | object | Pre-extracted entities — use instead of candidateText |
# Python — job match
import requests
response = requests.post(
"http://localhost:3000/api/transformer/v1/job-match",
headers={"X-API-Key": "csk_live_your_key"},
json={
"candidateText": "10 years Python, led team of 8, AWS certified, ex-Google...",
"jobDescription": "We need a Senior Python engineer with AWS and team leadership..."
}
)
match = response.json()["data"]
print(f"Match: {match['matchScore']}/100 — {match['verdict']}")
print(f"Hiring probability: {match['hiringProbability']*100:.0f}%")
print("Missing ATS keywords:", match["atsKeywords"]["missing"])
POST /cstm/match Intelligence Head 1
Full recruiter-grade job match: match score, strengths, gaps, cover letter hook, ATS analysis, shortlist probability, and red flags.
# Python — full intelligence match
response = requests.post(
"http://localhost:3000/api/cstm/match",
headers={"Content-Type": "application/json"}, # no key needed for CSTM heads
json={
"jobDescription": "...",
"candidateProfile": "...",
"context": {"country": "UK"}
}
)
result = response.json()
print(result["data"]["matchScore"]) # 0–100
print(result["meta"]["confidence"]) # 0.0–1.0
print(result["meta"]["inferenceMs"]) # response time
POST /cstm/salary Intelligence Head 2
P10–P90 salary percentiles, total compensation breakdown, negotiation script, and comparable roles.
// JavaScript — salary intelligence
const res = await fetch('/api/cstm/salary', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
role: 'Senior Data Scientist',
country: 'UK',
level: 'Senior (5–10 yrs)',
experienceYears: '7'
})
});
const { data, meta } = await res.json();
console.log(`Median: ${data.currency}${data.percentiles.p50}`);
console.log(`Script: ${data.negotiationAdvice.script}`);
console.log(`Confidence: ${meta.confidence}`);
POST /cstm/career-path Intelligence Head 3
# Python — career path prediction
response = requests.post("http://localhost:3000/api/cstm/career-path", json={
"currentRole": "Product Manager at Series B startup",
"yearsExperience": "5",
"skills": ["Product strategy", "SQL", "Agile", "Stakeholder management"],
"goals": "Become a CPO within 5 years",
"country": "UK"
})
data = response.json()["data"]
pri = data["primaryNextRole"]
print(f"Most likely next: {pri['title']} ({pri['probability']*100:.0f}%)")
print(f"Timeline: {pri['timelineMonths']['min']}–{pri['timelineMonths']['max']} months")
print(f"AI disruption: {data['aiDisruptionRisk']['level']}")
POST /cstm/resume-score Intelligence Head 4
// Node.js — resume scoring
const { data } = await (await fetch('/api/cstm/resume-score', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
resumeText: fs.readFileSync('resume.txt', 'utf8'),
targetRole: 'Head of Engineering',
country: 'UK'
})
})).json();
console.log(`Overall: ${data.overallScore}/100 ATS: ${data.atsScore}/100`);
data.weakBullets.forEach(b => {
console.log('\nBEFORE:', b.original);
console.log('AFTER: ', b.rewritten);
});
POST /cstm/skill-gap Intelligence Head 5
# Python — skill gap analysis
response = requests.post("http://localhost:3000/api/cstm/skill-gap", json={
"currentRole": "Junior Data Analyst",
"targetRole": "Machine Learning Engineer at Google",
"currentSkills": "Python, pandas, SQL, basic statistics",
"country": "UK",
"hoursPerWeek": "15"
})
data = response.json()["data"]
print(f"Readiness: {data['readinessScore']}/100 Difficulty: {data['difficultyRating']}")
print(f"Estimated time: {data['estimatedMonths']} months at 15h/week")
for skill in data["missingSkills"]:
print(f" [{skill['importance']}] {skill['skill']} — {skill['learningPath']['resource']}")
GET /v1/usage
Returns quota usage, daily breakdown by endpoint, and 30-day history.
curl http://localhost:3000/api/transformer/v1/usage \
-H "X-API-Key: csk_live_your_key"
Complete Python SDK
"""
CareerStudioMax CSTM-1 Python Client
pip install requests
"""
import requests
from dataclasses import dataclass
from typing import Optional, List, Dict, Any
@dataclass
class CSTMClient:
api_key: str
base_url: str = "http://localhost:3000/api"
def _headers(self) -> Dict:
return {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
def _post(self, path: str, body: Dict) -> Dict:
r = requests.post(f"{self.base_url}{path}", headers=self._headers(), json=body)
r.raise_for_status()
return r.json()
def extract(self, text: str, min_confidence: float = 0.0,
entity_types: Optional[List[str]] = None) -> Dict:
"""Extract career entities from text."""
opts = {}
if min_confidence: opts["minConfidence"] = min_confidence
if entity_types: opts["entityTypes"] = entity_types
return self._post("/transformer/v1/extract", {"text": text, "options": opts})["data"]
def career_graph(self, text: str) -> Dict:
"""Build a career knowledge graph from text."""
return self._post("/transformer/v1/career-graph", {"text": text})["data"]
def job_match(self, candidate_text: str, job_description: str) -> Dict:
"""Match a candidate to a job description."""
return self._post("/transformer/v1/job-match", {
"candidateText": candidate_text,
"jobDescription": job_description
})["data"]
def salary(self, role: str, country: str, level: str = "Mid-level") -> Dict:
"""Get salary intelligence for a role."""
return self._post("/cstm/salary", {
"role": role, "country": country, "level": level
})["data"]
def career_path(self, current_role: str, skills: List[str],
country: str = "Global") -> Dict:
"""Predict next career moves."""
return self._post("/cstm/career-path", {
"currentRole": current_role, "skills": skills, "country": country
})["data"]
def resume_score(self, resume_text: str, target_role: str,
job_description: str = "") -> Dict:
"""Score a resume for a target role."""
return self._post("/cstm/resume-score", {
"resumeText": resume_text, "targetRole": target_role,
"jobDescription": job_description
})["data"]
def skill_gap(self, current_role: str, target_role: str,
current_skills: str, country: str = "Global") -> Dict:
"""Analyse the skill gap between current and target role."""
return self._post("/cstm/skill-gap", {
"currentRole": current_role, "targetRole": target_role,
"currentSkills": current_skills, "country": country
})["data"]
def usage(self) -> Dict:
"""Get current API key usage stats."""
r = requests.get(
f"{self.base_url}/transformer/v1/usage",
headers=self._headers()
)
return r.json()["data"]
# ── Example usage ──────────────────────────────────────────
if __name__ == "__main__":
client = CSTMClient(api_key="csk_live_your_key")
# Extract entities
result = client.extract(
"Alice Chen is a Senior ML Engineer at DeepMind in London, earning £135,000.",
min_confidence=0.8
)
print("Entities:", [(e["type"], e["text"]) for e in result["entities"]])
# Salary intel
sal = client.salary("ML Engineer", "UK", "Senior (5–10 yrs)")
print(f"Median: {sal['currency']}{sal['percentiles']['p50']:,}")
# Check quota
usage = client.usage()
print(f"Used today: {usage['plan']['used']} / {usage['plan']['limit']}")
Complete JavaScript / Node.js SDK
/**
* CareerStudioMax CSTM-1 JavaScript Client
* Works in browser and Node.js (Node 18+ with native fetch)
*/
class CSTMClient {
constructor(apiKey, baseUrl = 'http://localhost:3000/api') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async #post(path, body) {
const res = await fetch(`${this.baseUrl}${path}`, {
method: 'POST',
headers: { 'X-API-Key': this.apiKey, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const json = await res.json();
if (!res.ok) throw new Error(json.error || `HTTP ${res.status}`);
return json;
}
/** Extract career entities from text */
async extract(text, options = {}) {
const r = await this.#post('/transformer/v1/extract', { text, options });
return r.data;
}
/** Build a career knowledge graph */
async careerGraph(text) {
const r = await this.#post('/transformer/v1/career-graph', { text });
return r.data;
}
/** Match a candidate to a job */
async jobMatch(candidateText, jobDescription) {
const r = await this.#post('/transformer/v1/job-match', { candidateText, jobDescription });
return r.data;
}
/** Get salary intelligence */
async salary(role, country, level = 'Mid-level') {
const r = await this.#post('/cstm/salary', { role, country, level });
return r.data;
}
/** Predict next career moves */
async careerPath(currentRole, skills, country = 'Global') {
const r = await this.#post('/cstm/career-path', { currentRole, skills, country });
return r.data;
}
/** Score a resume */
async resumeScore(resumeText, targetRole, jobDescription = '') {
const r = await this.#post('/cstm/resume-score', { resumeText, targetRole, jobDescription });
return r.data;
}
/** Analyse skill gap */
async skillGap(currentRole, targetRole, currentSkills, country = 'Global') {
const r = await this.#post('/cstm/skill-gap', { currentRole, targetRole, currentSkills, country });
return r.data;
}
/** Get usage stats */
async usage() {
const res = await fetch(`${this.baseUrl}/transformer/v1/usage`, {
headers: { 'X-API-Key': this.apiKey }
});
return (await res.json()).data;
}
}
// ── Example usage ──────────────────────────────────────────
const client = new CSTMClient('csk_live_your_key');
(async () => {
// Batch: extract + graph in parallel
const text = 'Alice Chen, ex-Google ML Engineer, now CTO at Anthropic.';
const [entities, graph] = await Promise.all([
client.extract(text, { minConfidence: 0.75 }),
client.careerGraph(text)
]);
console.log('Entities:', entities.entities.map(e => `[${e.type}] ${e.text}`));
console.log('Graph nodes:', graph.nodes.length);
console.log('Career score:', graph.careerScore?.overall);
// Salary
const sal = await client.salary('CTO', 'UK', 'Director / VP');
console.log(`CTO salary (UK) median: ${sal.currency}${sal.percentiles.p50?.toLocaleString()}`);
})();
Complete C++ Client
sudo apt install libcurl4-openssl-dev · wget https://github.com/nlohmann/json/releases/latest/download/json.hpp
/**
* CareerStudioMax CSTM-1 C++ Client
* Compile: g++ -std=c++17 cstm_client.cpp -lcurl -o cstm_example
*/
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <string>
#include <stdexcept>
using json = nlohmann::json;
class CSTMClient {
public:
CSTMClient(const std::string& apiKey,
const std::string& baseUrl = "http://localhost:3000/api")
: apiKey_(apiKey), baseUrl_(baseUrl) {
curl_global_init(CURL_GLOBAL_ALL);
}
~CSTMClient() { curl_global_cleanup(); }
// ── Core NER ──────────────────────────────────────────
json extract(const std::string& text, double minConf = 0.0) {
json body = {
{"text", text},
{"options", {{"minConfidence", minConf}}}
};
return post("/transformer/v1/extract", body)["data"];
}
// ── Career Graph ──────────────────────────────────────
json careerGraph(const std::string& text) {
return post("/transformer/v1/career-graph", {{"text", text}})["data"];
}
// ── Job Match ─────────────────────────────────────────
json jobMatch(const std::string& candidate, const std::string& jd) {
json body = {{"candidateText", candidate}, {"jobDescription", jd}};
return post("/transformer/v1/job-match", body)["data"];
}
// ── Salary Intelligence ───────────────────────────────
json salary(const std::string& role, const std::string& country,
const std::string& level = "Mid-level") {
json body = {{"role", role}, {"country", country}, {"level", level}};
return post("/cstm/salary", body)["data"];
}
// ── Career Path ───────────────────────────────────────
json careerPath(const std::string& role,
const std::vector<std::string>& skills,
const std::string& country = "Global") {
json body = {{"currentRole", role}, {"skills", skills}, {"country", country}};
return post("/cstm/career-path", body)["data"];
}
// ── Resume Score ──────────────────────────────────────
json resumeScore(const std::string& resume, const std::string& target) {
json body = {{"resumeText", resume}, {"targetRole", target}};
return post("/cstm/resume-score", body)["data"];
}
// ── Usage Stats ───────────────────────────────────────
json usage() {
CURL* curl = curl_easy_init();
std::string response;
std::string url = baseUrl_ + "/transformer/v1/usage";
struct curl_slist* hdrs = nullptr;
hdrs = curl_slist_append(hdrs, ("X-API-Key: " + apiKey_).c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrs);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(hdrs);
return json::parse(response)["data"];
}
private:
std::string apiKey_, baseUrl_;
static size_t writeCallback(char* p, size_t sz, size_t n, std::string* d) {
d->append(p, sz * n); return sz * n;
}
json post(const std::string& path, const json& body) {
CURL* curl = curl_easy_init();
std::string response;
std::string url = baseUrl_ + path;
std::string payload = body.dump();
struct curl_slist* hdrs = nullptr;
hdrs = curl_slist_append(hdrs, ("X-API-Key: " + apiKey_).c_str());
hdrs = curl_slist_append(hdrs, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrs);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
CURLcode code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(hdrs);
if (code != CURLE_OK)
throw std::runtime_error(curl_easy_strerror(code));
json result = json::parse(response);
if (result.contains("error"))
throw std::runtime_error(result["error"].get<std::string>());
return result;
}
};
// ── Example usage ──────────────────────────────────────────
int main() {
CSTMClient client("csk_live_your_key");
// 1. Extract entities
json entities = client.extract(
"Alice Chen is ML Engineer at DeepMind, London. Salary £135k.", 0.75
);
std::cout << "Entities found: " << entities["entities"].size() << "\n";
for (auto& e : entities["entities"]) {
std::cout << " [" << e["type"].get<std::string>() << "] "
<< e["text"].get<std::string>() << "\n";
}
// 2. Salary intelligence
json sal = client.salary("ML Engineer", "UK", "Senior (5-10 yrs)");
std::cout << "Median salary: "
<< sal["currency"].get<std::string>()
<< sal["percentiles"]["p50"].get<int>() << "\n";
// 3. Career path prediction
json path = client.careerPath(
"Senior ML Engineer",
{"PyTorch", "Python", "LLMs", "Team leadership"},
"UK"
);
std::string nextRole = path["primaryNextRole"]["title"];
double prob = path["primaryNextRole"]["probability"];
std::cout << "Next role: " << nextRole
<< " (" << (prob * 100) << "%)\n";
// 4. Usage
json usageData = client.usage();
std::cout << "Requests today: "
<< usageData["plan"]["used"].get<int>() << " / "
<< usageData["plan"]["limit"].get<int>() << "\n";
return 0;
}
Entity Type Reference
| Type | Description | Examples |
|---|---|---|
| EMPLOYEE | Job seekers, candidates, named individuals in career contexts | Alice Chen, John Smith |
| EMPLOYER | Companies, organizations that hire | Google, NHS, KPMG |
| RECRUITER | HR professionals, headhunters, talent acquisition | Sarah at Hays, Michael Page |
| JOB | Job titles, roles, positions, occupations | Senior Engineer, Product Manager |
| SKILL | Technical skills, certifications, tools, technologies | Python, AWS, Agile, PMP |
| LOCATION | Cities, countries, regions, remote | London, remote, APAC region |
| DATE | Time periods, years of experience, dates | 5 years, 2019–2023, Q3 2024 |
| SALARY | Compensation figures, ranges, equity | £120,000, $85k–$110k, 0.1% equity |
Standard Response Format
{
"success": true,
"data": { /* endpoint-specific payload */ },
"requestId": "req_cstm_a1b2c3d4e5f6g7h8", // unique per request for debugging
"usageToday": 12, // requests used today (transformer endpoints)
"dailyLimit": 100, // your daily limit
"meta": { // intelligence endpoints only
"model": "CSTM-1",
"apiVersion": "v1",
"taskType": "SALARY_INTELLIGENCE",
"requestId": "req_cstm_...",
"inferenceMs": 1243, // time taken
"confidence": 0.91, // 0.0–1.0
"knowledgeCutoff": "Live-bridged — no fixed cutoff"
}
}
☕ Java SDK
com.squareup.okhttp3:okhttp:4.12.0 and com.fasterxml.jackson.core:jackson-databind:2.17.0 to your pom.xml or build.gradle.// CareerStudioMax CSTM-1 Java Client
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class CSTMClient {
private final String apiKey;
private final String baseUrl;
private final OkHttpClient http = new OkHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
private static final MediaType JSON = MediaType.get("application/json");
public CSTMClient(String apiKey) {
this.apiKey = apiKey;
this.baseUrl = "http://localhost:3000/api";
}
private Map post(String path, Map body) throws Exception {
String json = mapper.writeValueAsString(body);
Request req = new Request.Builder()
.url(baseUrl + path)
.addHeader("X-API-Key", apiKey)
.post(RequestBody.create(json, JSON))
.build();
try (Response res = http.newCall(req).execute()) {
return mapper.readValue(res.body().string(), Map.class);
}
}
public Map extract(String text) throws Exception {
Map body = Map.of("text", text);
Map result = post("/transformer/v1/extract", body);
return (Map) result.get("data");
}
public Map salary(String role, String country) throws Exception {
Map body = Map.of("role", role, "country", country);
Map result = post("/cstm/salary", body);
return (Map) result.get("data");
}
public Map jobMatch(String candidateText, String jobDescription) throws Exception {
Map body = Map.of("candidateText", candidateText, "jobDescription", jobDescription);
Map result = post("/transformer/v1/job-match", body);
return (Map) result.get("data");
}
public static void main(String[] args) throws Exception {
CSTMClient client = new CSTMClient("csk_live_your_key");
Map entities = client.extract("Alice Chen is a Senior ML Engineer at DeepMind, London.");
System.out.println("Entities: " + entities);
Map sal = client.salary("ML Engineer", "UK");
System.out.println("Median: " + sal.get("percentiles"));
}
}
🔵 Go SDK
// CareerStudioMax CSTM-1 Go Client
// go get -u github.com/tidwall/gjson
package main
import (
"bytes"; "encoding/json"; "fmt"; "io"; "net/http"
)
type CSTMClient struct { APIKey, BaseURL string }
func NewClient(apiKey string) *CSTMClient {
return &CSTMClient{APIKey: apiKey, BaseURL: "http://localhost:3000/api"}
}
func (c *CSTMClient) post(path string, body map[string]interface{}) (map[string]interface{}, error) {
data, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", c.BaseURL+path, bytes.NewBuffer(data))
req.Header.Set("X-API-Key", c.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { return nil, err }
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(raw, &result)
return result, nil
}
func (c *CSTMClient) Extract(text string) (map[string]interface{}, error) {
r, err := c.post("/transformer/v1/extract", map[string]interface{}{ "text": text })
if err != nil { return nil, err }
return r["data"].(map[string]interface{}), nil
}
func (c *CSTMClient) Salary(role, country string) (map[string]interface{}, error) {
r, err := c.post("/cstm/salary", map[string]interface{}{ "role": role, "country": country })
if err != nil { return nil, err }
return r["data"].(map[string]interface{}), nil
}
func (c *CSTMClient) CareerPath(role string, skills []string, country string) (map[string]interface{}, error) {
r, err := c.post("/cstm/career-path", map[string]interface{}{ "currentRole": role, "skills": skills, "country": country })
if err != nil { return nil, err }
return r["data"].(map[string]interface{}), nil
}
func main() {
client := NewClient("csk_live_your_key")
entities, _ := client.Extract("Alice Chen is a Senior ML Engineer at DeepMind, London.")
fmt.Printf("Entities: %v\n", entities["entities"])
sal, _ := client.Salary("ML Engineer", "UK")
fmt.Printf("Salary: %v\n", sal["percentiles"])
path, _ := client.CareerPath("Senior Engineer", []string{"Go", "Kubernetes", "gRPC"}, "UK")
fmt.Printf("Next role: %v\n", path["primaryNextRole"])
}
© C# / .NET SDK
System.Net.Http.Json (built-in .NET 5+). No extra packages needed.// CareerStudioMax CSTM-1 C# Client (.NET 6+)
using System.Net.Http.Json;
using System.Text.Json;
public class CSTMClient
{
private readonly HttpClient _http = new();
private readonly string _apiKey;
private const string BaseUrl = "http://localhost:3000/api";
public CSTMClient(string apiKey) {
_apiKey = apiKey;
_http.DefaultRequestHeaders.Add("X-API-Key", apiKey);
}
private async Task<JsonElement> Post(string path, object body) {
var res = await _http.PostAsJsonAsync($"{BaseUrl}{path}", body);
res.EnsureSuccessStatusCode();
var root = await res.Content.ReadFromJsonAsync<JsonElement>();
return root.GetProperty("data");
}
public Task<JsonElement> Extract(string text) =>
Post("/transformer/v1/extract", new { text });
public Task<JsonElement> Salary(string role, string country, string level = "Mid-level") =>
Post("/cstm/salary", new { role, country, level });
public Task<JsonElement> JobMatch(string candidateText, string jobDescription) =>
Post("/transformer/v1/job-match", new { candidateText, jobDescription });
public Task<JsonElement> CareerPath(string currentRole, string[] skills, string country = "Global") =>
Post("/cstm/career-path", new { currentRole, skills, country });
public Task<JsonElement> ResumeScore(string resumeText, string targetRole) =>
Post("/cstm/resume-score", new { resumeText, targetRole });
}
// Usage
var client = new CSTMClient("csk_live_your_key");
var entities = await client.Extract("Alice Chen is a Senior ML Engineer at DeepMind, London.");
Console.WriteLine($"Entity count: {entities.GetProperty("metadata").GetProperty("entityCount")}");
var sal = await client.Salary("ML Engineer", "UK", "Senior (5-10 yrs)");
Console.WriteLine($"Median: {sal.GetProperty("currency")}{sal.GetProperty("percentiles").GetProperty("p50")}");
💎 Ruby SDK
# CareerStudioMax CSTM-1 Ruby Client
# gem install faraday
require 'faraday'
require 'json'
class CSTMClient
BASE_URL = 'http://localhost:3000/api'
def initialize(api_key)
@conn = Faraday.new(url: BASE_URL) do |f|
f.request :json
f.response :json
f.headers['X-API-Key'] = api_key
end
end
def post(path, body)
res = @conn.post(path, body)
raise res.body['error'] unless res.success?
res.body['data']
end
def extract(text, min_confidence: 0.0)
post('/transformer/v1/extract', { text:, options: { minConfidence: min_confidence } })
end
def salary(role, country, level: 'Mid-level')
post('/cstm/salary', { role:, country:, level: })
end
def job_match(candidate_text, job_description)
post('/transformer/v1/job-match', { candidateText: candidate_text, jobDescription: job_description })
end
def career_path(current_role, skills, country: 'Global')
post('/cstm/career-path', { currentRole: current_role, skills:, country: })
end
def resume_score(resume_text, target_role)
post('/cstm/resume-score', { resumeText: resume_text, targetRole: target_role })
end
def usage
res = @conn.get('/transformer/v1/usage')
res.body['data']
end
end
# Usage
client = CSTMClient.new('csk_live_your_key')
entities = client.extract('Alice Chen is a Senior ML Engineer at DeepMind, London.', min_confidence: 0.8)
puts "Entities: #{entities['entities'].map { |e| "[#{e['type']}] #{e['text']}" }.join(', ')}"
sal = client.salary('ML Engineer', 'UK', level: 'Senior (5-10 yrs)')
puts "Median: #{sal['currency']}#{sal['percentiles']['p50']}"
usage = client.usage
puts "Used today: #{usage['plan']['used']} / #{usage['plan']['limit']}"
🐘 PHP SDK
/**
* CareerStudioMax CSTM-1 PHP Client
* Requires: PHP 8.0+ · composer require guzzlehttp/guzzle
*/
use GuzzleHttp\Client;
class CSTMClient {
private Client $http;
private const BASE_URL = 'http://localhost:3000/api';
public function __construct(string $apiKey) {
$this->http = new Client([
'base_uri' => self::BASE_URL,
'headers' => ['X-API-Key' => $apiKey, 'Content-Type' => 'application/json']
]);
}
private function post(string $path, array $body): array {
$res = $this->http->post($path, ['json' => $body]);
$data = json_decode($res->getBody(), true);
return $data['data'];
}
public function extract(string $text, float $minConfidence = 0.0): array {
return $this->post('/transformer/v1/extract', [
'text' => $text, 'options' => ['minConfidence' => $minConfidence]
]);
}
public function salary(string $role, string $country, string $level = 'Mid-level'): array {
return $this->post('/cstm/salary', ['role' => $role, 'country' => $country, 'level' => $level]);
}
public function jobMatch(string $candidate, string $jd): array {
return $this->post('/transformer/v1/job-match', ['candidateText' => $candidate, 'jobDescription' => $jd]);
}
public function careerPath(string $role, array $skills, string $country = 'Global'): array {
return $this->post('/cstm/career-path', ['currentRole' => $role, 'skills' => $skills, 'country' => $country]);
}
}
// Usage
$client = new CSTMClient('csk_live_your_key');
$entities = $client->extract('Alice Chen is a Senior ML Engineer at DeepMind, London.', 0.8);
foreach ($entities['entities'] as $e) echo "[{$e['type']}] {$e['text']}\n";
$sal = $client->salary('ML Engineer', 'UK');
echo "Median: {$sal['currency']}{$sal['percentiles']['p50']}\n";
🦀 Rust SDK
reqwest = { version = "0.11", features = ["json"] } · tokio = { version = "1", features = ["full"] } · serde_json = "1"// CareerStudioMax CSTM-1 Rust Client
use reqwest::Client;
use serde_json::{json, Value};
pub struct CSTMClient { client: Client, api_key: String, base_url: String }
impl CSTMClient {
pub fn new(api_key: &str) -> Self {
Self {
client: Client::new(),
api_key: api_key.to_string(),
base_url: "http://localhost:3000/api".to_string(),
}
}
async fn post(&self, path: &str, body: Value) -> Result<Value, reqwest::Error> {
let res = self.client
.post(format!("{}{}", self.base_url, path))
.header("X-API-Key", &self.api_key)
.json(&body)
.send().await?;
let json: Value = res.json().await?;
Ok(json["data"].clone())
}
pub async fn extract(&self, text: &str) -> Result<Value, reqwest::Error> {
self.post("/transformer/v1/extract", json!({ "text": text })).await
}
pub async fn salary(&self, role: &str, country: &str) -> Result<Value, reqwest::Error> {
self.post("/cstm/salary", json!({ "role": role, "country": country })).await
}
pub async fn job_match(&self, candidate: &str, jd: &str) -> Result<Value, reqwest::Error> {
self.post("/transformer/v1/job-match", json!({ "candidateText": candidate, "jobDescription": jd })).await
}
pub async fn career_path(&self, role: &str, skills: Vec<&str>, country: &str) -> Result<Value, reqwest::Error> {
self.post("/cstm/career-path", json!({ "currentRole": role, "skills": skills, "country": country })).await
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = CSTMClient::new("csk_live_your_key");
let entities = client.extract("Alice Chen is a Senior ML Engineer at DeepMind, London.").await?;
println!("Entity count: {}", entities["metadata"]["entityCount"]);
let sal = client.salary("ML Engineer", "UK").await?;
println!("Median: {}{},", sal["currency"], sal["percentiles"]["p50"]);
Ok(())
}
🍎 Swift / iOS SDK
// CareerStudioMax CSTM-1 Swift Client (iOS 15+ / macOS 12+)
// Pure Swift — no dependencies needed
import Foundation
actor CSTMClient {
private let apiKey: String
private let baseURL = "http://localhost:3000/api"
init(apiKey: String) { self.apiKey = apiKey }
private func post(path: String, body: [String: Any]) async throws -> [String: Any] {
var req = URLRequest(url: URL(string: baseURL + path)!)
req.httpMethod = "POST"
req.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.httpBody = try JSONSerialization.data(withJSONObject: body)
let (data, _) = try await URLSession.shared.data(for: req)
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
return json["data"] as! [String: Any]
}
func extract(text: String, minConfidence: Double = 0.0) async throws -> [String: Any] {
try await post(path: "/transformer/v1/extract", body: [
"text": text, "options": ["minConfidence": minConfidence]
])
}
func salary(role: String, country: String, level: String = "Mid-level") async throws -> [String: Any] {
try await post(path: "/cstm/salary", body: ["role": role, "country": country, "level": level])
}
func jobMatch(candidateText: String, jobDescription: String) async throws -> [String: Any] {
try await post(path: "/transformer/v1/job-match", body: [
"candidateText": candidateText, "jobDescription": jobDescription
])
}
}
// Usage (in async context)
let client = CSTMClient(apiKey: "csk_live_your_key")
let entities = try await client.extract(text: "Alice Chen is a Senior ML Engineer at DeepMind, London.", minConfidence: 0.8)
print("Entities: \(entities["entities"] ?? [])")
let sal = try await client.salary(role: "ML Engineer", country: "UK")
print("Median: \(sal["currency"] ?? "")\(sal["percentiles"]?["p50"] ?? "")")
🎯 Kotlin / Android SDK
implementation 'com.squareup.okhttp3:okhttp:4.12.0' · implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3'// CareerStudioMax CSTM-1 Kotlin Client
import kotlinx.serialization.json.*
import okhttp3.*; import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
class CSTMClient(private val apiKey: String) {
private val http = OkHttpClient()
private val JSON = "application/json".toMediaType()
private val BASE = "http://localhost:3000/api"
private val json = Json { ignoreUnknownKeys = true }
private fun post(path: String, body: JsonObject): JsonObject {
val req = Request.Builder()
.url("$BASE$path")
.addHeader("X-API-Key", apiKey)
.post(body.toString().toRequestBody(JSON))
.build()
val resp = http.newCall(req).execute()
val parsed = json.parseToJsonElement(resp.body!!.string()).jsonObject
return parsed["data"]!!.jsonObject
}
fun extract(text: String) = post("/transformer/v1/extract", buildJsonObject { put("text", text) })
fun salary(role: String, country: String, level: String = "Mid-level") =
post("/cstm/salary", buildJsonObject { put("role", role); put("country", country); put("level", level) })
fun jobMatch(candidate: String, jd: String) =
post("/transformer/v1/job-match", buildJsonObject { put("candidateText", candidate); put("jobDescription", jd) })
fun careerPath(role: String, skills: List<String>, country: String = "Global") =
post("/cstm/career-path", buildJsonObject {
put("currentRole", role); put("country", country)
putJsonArray("skills") { skills.forEach { add(it) } }
})
}
fun main() {
val client = CSTMClient("csk_live_your_key")
val entities = client.extract("Alice Chen is a Senior ML Engineer at DeepMind, London.")
println("Entities: ${entities["entities"]}")
val sal = client.salary("ML Engineer", "UK")
println("Median: ${sal["currency"]}${sal["percentiles"]?.jsonObject?.get("p50")}")
}
📊 R SDK
install.packages(c("httr2","jsonlite"))# CareerStudioMax CSTM-1 R Client
# install.packages(c("httr2","jsonlite"))
library(httr2)
library(jsonlite)
cstm_client <- function(api_key, base_url = "http://localhost:3000/api") {
list(api_key = api_key, base_url = base_url)
}
cstm_post <- function(client, path, body) {
resp <- request(paste0(client$base_url, path)) |>
req_headers("X-API-Key" = client$api_key,
"Content-Type" = "application/json") |>
req_body_json(body) |>
req_perform()
fromJSON(resp_body_string(resp))$data
}
# Extract entities
cstm_extract <- function(client, text, min_confidence = 0.0) {
cstm_post(client, "/transformer/v1/extract",
list(text = text, options = list(minConfidence = min_confidence)))
}
# Salary intelligence
cstm_salary <- function(client, role, country, level = "Mid-level") {
cstm_post(client, "/cstm/salary", list(role = role, country = country, level = level))
}
# Job match
cstm_job_match <- function(client, candidate_text, job_description) {
cstm_post(client, "/transformer/v1/job-match",
list(candidateText = candidate_text, jobDescription = job_description))
}
# Skill gap analysis
cstm_skill_gap <- function(client, current_role, target_role, current_skills, country = "Global") {
cstm_post(client, "/cstm/skill-gap",
list(currentRole = current_role, targetRole = target_role,
currentSkills = current_skills, country = country))
}
# --- Example usage ---
client <- cstm_client("csk_live_your_key")
# Extract entities
result <- cstm_extract(client, "Alice Chen is a Senior ML Engineer at DeepMind, London.", 0.8)
cat("Entity count:", result$metadata$entityCount, "\n")
print(result$entities[, c("type", "text", "confidence")])
# Salary data
sal <- cstm_salary(client, "ML Engineer", "UK", "Senior (5-10 yrs)")
cat("Median:", sal$currency, sal$percentiles$p50, "\n")
# Skill gap for data scientists
gap <- cstm_skill_gap(client,
current_role = "Data Analyst",
target_role = "ML Engineer",
current_skills = "R, ggplot2, SQL, statistics",
country = "UK"
)
cat("Readiness:", gap$readinessScore, "/100 | Estimated:", gap$estimatedMonths, "months\n")
🔮 LifePath AI — All 21 Modes
LifePath AI is the simulation engine built on CSTM-1. It operates across 21 intelligence modes, each targeting a specific dimension of career decision-making. All modes are accessible via the existing endpoints — the system prompt and context determine which mode activates.
/api/future-self, /api/life-intel, and /api/life-sim routes each handle specific mode groups.| Mode | Name | Endpoint | Key Inputs |
|---|---|---|---|
| 1 | Future Self Simulation | POST /api/future-self/simulate | career, years, age, values, country |
| 2 | Regret Forecasting | POST /api/future-self/regret | career, alternativeCareer, values |
| 3 | AI Future Self Chat | POST /api/future-self/chat | message, persona, career, chatHistory |
| 4 | Identity Alignment Scan | POST /api/life-intel/identity/scan | career, personality, values, workStyle |
| 5 | Career Timeline Map | POST /api/future-self/timeline | career, currentRole, yearsExperience |
| 6 | Personality Deep Profile | POST /api/life-intel/personality/profile | answers, career |
| 7 | Adaptive Career Recs | POST /api/life-intel/career/adaptive | personality, values, skills, avoidances |
| 8 | Parallel Life Simulator | POST /api/life-sim/parallel | career1, career2, decision, currentAge |
| 9 | Decision Stress Test | POST /api/life-sim/stress-test | career, decision, financialSituation |
| 10 | Skill Gap Heatmap | POST /api/life-sim/skill-heatmap | targetRole, currentSkills |
| 11 | Opportunity Timing | POST /api/life-sim/timing | career, currentRole, yearsExperience |
| 12 | Realistic Salary Simulator | POST /api/life-sim/salary-sim | career, personality, negotiationStyle |
| 13 | Burnout Risk Predictor | POST /api/life-intel/burnout/predict | career, workHours, satisfaction |
| 14 | Meaning vs Money | POST /api/life-intel/meaning-money | career, alternativeCareer, values |
| 15 | Career Regret Stories | POST /api/life-intel/regret-stories | career, decision, age |
| 16 | Reality Feed | POST /api/life-sim/reality-feed | career, aspect |
| 17 | Micro-Internship | POST /api/life-sim/micro-internship | career, task, level |
| 18 | Shadow Day AI | POST /api/life-sim/shadow-day | career, company_type, level |
| 19 | Life Trade-Off Slider | POST /api/life-sim/tradeoff | career, preferences (money/time/stability/freedom/meaning/status/growth) |
| 20 | Identity Evolution | POST /api/life-intel/identity/evolution | currentProfile, previousProfile |
| 21 | Wrong Path Alert | POST /api/life-intel/wrong-path-alert | career, yearsIn, satisfaction |
LifePath AI — Python Example (all 21 modes)
"""LifePath AI Python Client — all 21 modes"""
import requests
class LifePathAI:
def __init__(self, base_url="http://localhost:3000/api"):
self.base = base_url
self.s = requests.Session()
self.s.headers["Content-Type"] = "application/json"
def _p(self, path, body): return self.s.post(self.base+path, json=body).json()
# Mode 1
def future_self(self, career, years=7, age=None, values=None, country="Global"):
return self._p("/future-self/simulate", {"career":career,"years":years,"age":age,"values":values,"country":country})
# Mode 2
def regret_forecast(self, career, alt=None, values=None, country="Global"):
return self._p("/future-self/regret", {"career":career,"alternativeCareer":alt,"values":values,"country":country})
# Mode 3
def future_self_chat(self, message, persona="successful", career=None, history=None):
return self._p("/future-self/chat", {"message":message,"persona":persona,"career":career,"chatHistory":history or []})
# Mode 4
def identity_scan(self, career, personality=None, values=None, work_style=None):
return self._p("/life-intel/identity/scan", {"career":career,"personality":personality,"values":values,"workStyle":work_style})
# Mode 5
def timeline(self, career, current_role=None, years_exp=0):
return self._p("/future-self/timeline", {"career":career,"currentRole":current_role,"yearsExperience":years_exp})
# Mode 6
def personality_profile(self, answers, career=None):
return self._p("/life-intel/personality/profile", {"answers":answers,"career":career})
# Mode 7
def adaptive_careers(self, personality, values=None, skills=None, avoidances=None):
return self._p("/life-intel/career/adaptive", {"personality":personality,"values":values,"skills":skills,"avoidances":avoidances})
# Mode 8
def parallel_life(self, career1, career2, decision=None, age=28):
return self._p("/life-sim/parallel", {"career1":career1,"career2":career2,"decision":decision,"currentAge":age})
# Mode 9
def stress_test(self, career, decision=None, risk="moderate"):
return self._p("/life-sim/stress-test", {"career":career,"decision":decision,"riskTolerance":risk})
# Mode 10
def skill_heatmap(self, target_role, current_skills):
return self._p("/life-sim/skill-heatmap", {"targetRole":target_role,"currentSkills":current_skills})
# Mode 11
def timing(self, career, current_role=None, years=None):
return self._p("/life-sim/timing", {"career":career,"currentRole":current_role,"yearsExperience":years})
# Mode 12
def salary_sim(self, career, personality=None, neg_style="passive", country="Global"):
return self._p("/life-sim/salary-sim", {"career":career,"personality":personality,"negotiationStyle":neg_style,"country":country})
# Mode 13
def burnout_risk(self, career, hours=50, satisfaction=5, stress=None):
return self._p("/life-intel/burnout/predict", {"career":career,"workHours":hours,"satisfaction":satisfaction,"stressFactors":stress})
# Mode 14
def meaning_money(self, career, alt, values=None, goals=None):
return self._p("/life-intel/meaning-money", {"career":career,"alternativeCareer":alt,"values":values,"lifeGoals":goals})
# Mode 15
def regret_stories(self, career, decision=None, age="mid-career"):
return self._p("/life-intel/regret-stories", {"career":career,"decision":decision,"age":age})
# Mode 16
def reality_feed(self, career, aspect=None):
return self._p("/life-sim/reality-feed", {"career":career,"aspect":aspect})
# Mode 17
def micro_internship(self, career, task=None, level="mid-level"):
return self._p("/life-sim/micro-internship", {"career":career,"task":task,"level":level})
# Mode 18
def shadow_day(self, career, company_type=None, level="senior"):
return self._p("/life-sim/shadow-day", {"career":career,"company_type":company_type,"level":level})
# Mode 19
def tradeoff_slider(self, career, prefs:dict):
return self._p("/life-sim/tradeoff", {"career":career,"preferences":prefs})
# Mode 20
def identity_evolution(self, current, previous=None, career=None):
return self._p("/life-intel/identity/evolution", {"currentProfile":current,"previousProfile":previous,"career":career})
# Mode 21
def wrong_path_alert(self, career, years_in=None, satisfaction=5, recent=None):
return self._p("/life-intel/wrong-path-alert", {"career":career,"yearsIn":years_in,"satisfaction":satisfaction,"recentChanges":recent})
# ── Example: all 21 modes in sequence ──
ai = LifePathAI()
# Mode 1 — simulate life as ML Engineer in 7 years
print(ai.future_self("ML Engineer", years=7, age=28, country="UK"))
# Mode 9 — stress test leaving corporate for startup
print(ai.stress_test("Startup founder", decision="Leaving corporate job", risk="moderate"))
# Mode 19 — trade-off slider: meaning-first profile
print(ai.tradeoff_slider("Product Manager", {"money":50,"meaning":90,"freedom":75,"stability":40,"time":65,"status":30,"growth":80}))
Changelog
| Version | Date | Changes |
|---|---|---|
| v1.5 | 2025-05 | Data Intelligence Agent · emerging skills tracker · AI disruption index |
| v1.4 | 2025-05 | Daily rate limits · per-minute throttling · csk_live_/csk_test_ key format · secret keys |
| v1.3 | 2025-04 | 5 Intelligence Heads (match, salary, career-path, resume-score, skill-gap) · CSTM-1 identity |
| v1.2 | 2025-04 | 196-country salary intelligence · PPP-adjusted benchmarks |
| v1.1 | 2025-03 | Career graph endpoint · knowledge graph clustering · career score |
| v1.0 | 2025-03 | Initial release: NER extraction · job match · API key system |
CareerStudioMax AI · CSTM-1 API v1 · Built on career intelligence