JANUS
Analytics Core · API Reference
JANUS ANALYTICS · v1

API Reference

Programmatic access to Janus AI analyst capabilities — portfolio narrative, strategy Q&A and risk analysis — all computed on live portfolio data. Every response is grounded in the same MySQL datasets that power the Analytics console.

API v1  ·  On-premise · Data-safe
Authentication

All analyst endpoints require a Janus API key. Keys are issued by your system administrator via the key management panel and begin with janus_.

Passing your API key
Header (recommended) X-API-Key: janus_your_key_here
Bearer token Authorization: Bearer janus_your_key_here
Query string ?api_key=janus_your_key_here
Keep your key secret. Each key is shown only once at generation. If a key is compromised, revoke it from the admin panel and issue a new one. Keys track last_used_at — unused keys older than 90 days are auto-expired.
Base URL

All endpoints are relative to the Janus deployment root.

https://ai.momentocapital.com/api/v1
POST /analyst/analyze

Generate a full AI narrative for a single portfolio over a date range. The engine fetches equity, computes performance metrics and holdings, then passes a structured prompt to the on-prem LLM.

POST
/api/v1/analyst/analyze
Portfolio AI narrative — performance, holdings, behaviour summary
Request body application/json
FieldTypeRequiredDescription
portfolio_id string required Portfolio identifier as stored in the Equity table (e.g. mc_val_1).
start_date string required Start of the analysis window. Format: YYYY-MM-DD.
end_date string required End of the analysis window. Format: YYYY-MM-DD.
Example request
# Portfolio analysis
curl -X POST https://ai.momentocapital.com/api/v1/analyst/analyze \
  -H "X-API-Key: janus_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "portfolio_id": "mc_val_1",
    "start_date":   "2024-01-01",
    "end_date":     "2024-12-31"
  }'
import requests

response = requests.post(
    "https://ai.momentocapital.com/api/v1/analyst/analyze",
    headers={"X-API-Key": "janus_your_key_here"},
    json={
        "portfolio_id": "mc_val_1",
        "start_date":   "2024-01-01",
        "end_date":     "2024-12-31",
    },
)
data = response.json()
print(data["analysis_markdown"])
{
  "portfolio_id": "mc_val_1",
  "start_date":   "2024-01-01",
  "end_date":     "2024-12-31"
}
Response 200 OK
{
  "portfolio_id": string,
  "start_date": string YYYY-MM-DD,
  "end_date": string YYYY-MM-DD,
  "analysis_markdown": string — full markdown narrative,
  "source": "deepseek" | "python_fallback"
}
POST /analyst/chat

Ask a natural language question about a portfolio's strategy and receive a structured, analyst-grade answer. Choose between a quantitative profile (statistical rigour, factor exposures) or a finance profile (executive narrative, investor language).

POST
/api/v1/analyst/chat
Strategy Q&A — ask anything about a portfolio's investment approach
Request body application/json
FieldTypeRequiredDescription
portfolio_id string required Portfolio identifier. Used to pull strategy and risk module context.
question string required Natural language question about the portfolio or its strategy.
analyst_profile string optional Answer tone. "quantitative" (default) — statistical precision; "finance" — narrative, investor-ready language.
Example request
curl -X POST https://ai.momentocapital.com/api/v1/analyst/chat \
  -H "X-API-Key: janus_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "portfolio_id":    "mc_val_1",
    "question":        "What are the main risk factors in this strategy?",
    "analyst_profile": "quantitative"
  }'
import requests

response = requests.post(
    "https://ai.momentocapital.com/api/v1/analyst/chat",
    headers={"X-API-Key": "janus_your_key_here"},
    json={
        "portfolio_id":    "mc_val_1",
        "question":        "What are the main risk factors?",
        "analyst_profile": "finance",
    },
)
data = response.json()
print(data["answer_markdown"])
{
  "portfolio_id":    "mc_val_1",
  "question":        "What are the main risk factors?",
  "analyst_profile": "quantitative"
}
Response 200 OK
{
  "portfolio_id": string,
  "question": string — echoed back,
  "analyst_profile": "quantitative" | "finance",
  "answer_markdown": string — full markdown answer,
  "source": "deepseek" | "python_fallback"
}
POST /analyst/risk

Returns a quantitative risk profile — max drawdown, VaR, CVaR, volatility, CAGR, Calmar ratio — plus an AI-generated narrative that contextualises each metric and highlights regime-level risk factors.

POST
/api/v1/analyst/risk
Risk metrics + AI narrative — drawdown, VaR, CVaR, volatility, Calmar
Request body application/json
FieldTypeRequiredDescription
portfolio_id string required Portfolio identifier.
start_date string required Start of evaluation window. Format: YYYY-MM-DD.
end_date string required End of evaluation window. Format: YYYY-MM-DD.
Example request
curl -X POST https://ai.momentocapital.com/api/v1/analyst/risk \
  -H "X-API-Key: janus_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "portfolio_id": "mc_val_1",
    "start_date":   "2024-01-01",
    "end_date":     "2024-12-31"
  }'
import requests

response = requests.post(
    "https://ai.momentocapital.com/api/v1/analyst/risk",
    headers={"X-API-Key": "janus_your_key_here"},
    json={
        "portfolio_id": "mc_val_1",
        "start_date":   "2024-01-01",
        "end_date":     "2024-12-31",
    },
)
data = response.json()
print(data["risk_metrics"])
print(data["risk_narrative"])
{
  "portfolio_id": "mc_val_1",
  "start_date":   "2024-01-01",
  "end_date":     "2024-12-31"
}
Response 200 OK
{
  "portfolio_id": string,
  "start_date": string,
  "end_date": string,
  "risk_metrics": {
    "max_drawdown_pct": number — worst peak-to-trough %,
    "volatility_ann_pct": number — annualised daily vol %,
    "var_95_pct": number — parametric VaR 95 %,
    "cvar_95_pct": number — conditional VaR (ES) 95 %,
    "cagr_pct": number — compound annual growth %,
    "calmar_ratio": number | null,
    "skewness": number,
    "kurtosis": number,
    "n_observations": integer
  },
  "risk_narrative": string — markdown narrative,
  "source": "deepseek" | "python_fallback"
}
Error Codes

All errors return a JSON body with error and code fields.

HTTPCodeMeaning
401 MISSING_API_KEY No API key was provided in the request.
401 INVALID_API_KEY The key does not exist or has been revoked.
400 Missing required field or invalid date format.
404 No equity data for the portfolio/date range combination.
500 Internal error — database or LLM engine failure.
// Example 401 response
{
  "error": "Invalid or revoked API key.",
  "code":  "INVALID_API_KEY"
}
Key Management

Admins manage keys via session-authenticated endpoints (no API key required — uses Janus login session).

MethodEndpointDescription
POST /api/v1/keys Generate a new API key. Body: {"label": "client name"}. Returns the plain key — shown once.
GET /api/v1/keys List all keys (prefix + metadata, no plain text).
DELETE /api/v1/keys/<id> Revoke a key by its numeric ID.
Generate a key
curl -X POST https://ai.momentocapital.com/api/v1/keys \
  -H "Content-Type: application/json" \
  -b "session=<your_session_cookie>" \
  -d '{"label": "Acme Capital - prod"}'

// Response (200)
{
  "id":         7,
  "key":        "janus_Xf3...  ← SAVE THIS, shown once",
  "key_prefix": "janus_Xf3k",
  "label":      "Acme Capital - prod",
  "created_at": "2026-03-24 10:00:00",
  "is_active":  true
}