September 6, 2025
cNode SDK (Preview): Forecasts & Szenarien direkt im Code – mit Mock-Demo zum Ausprobieren
von
Leonardo Bornhäußer



Warum ein SDK – und warum jetzt?
APIs sind mächtig, doch im Alltag zählt Developer-Speed. Das cNode SDK reduziert Boilerplate auf einen Funktionsaufruf: Cluster, Goal, Horizon, Inputs – fertig.
In der Preview-Phase können Sie bereits realistisch testen: Entweder komplett offline mit synthetischen Daten oder gegen einen Mock-Endpoint, bis die produktive SDK-Version als @cnode/sdk
veröffentlicht wird.
Denkmodell: Cluster × Goals
Wie die API ist auch das SDK domänen- und zielbasiert:
Cluster (Preview):
finance, product, hr, marketing, compliance, supply_chain
Typische Goals:
Finance:
revenue_forecast, cashflow_forecast, break_even, profitability, roi_forecast, valuation_dcf, price_elasticity, anomaly_detection
Product:
demand_forecast, inventory_coverage, return_rate_forecast
HR:
headcount_forecast, attrition_forecast
Marketing:
mql_forecast, cac_ltv_projection
Compliance:
esg_risk_score, anomaly_detection
So binden Sie gezielt KPIs und Kontexte ein – ohne Blackbox.
Ergebnisformat: Forecasts, Intervalle, Explainability, Diagnostics
Der SDK-Call liefert strukturierte Ergebnisse:
Forecast: Zeitreihe (Datum/Wert)
Intervals: Konfidenzbänder (Lower/Upper + Confidence)
Explanations: wichtigste Treiber (global & optional lokal)
Diagnostics: Metriken (z. B. WAPE/MAE/RMSE), Warnungen, Retrain-Hinweise
Damit bleiben Prognosen prüfbar und erklärbar – ideal für Finance, ESG, Planning & Compliance.
Vollständiges SDK-Preview-Snippet (copy-paste)
Hinweis: Dieses Snippet enthält einen Mock-SDK-Shim, damit Sie heute bereits auf der Doku/Website eine Demo zeigen können. Ersetzen Sie ihn später durch
@cnode/sdk
.
/** * CNode SDK — Preview / Coming Soon (copy–paste) * ----------------------------------------------------------------------------- * STATUS: The official SDK package is under active development. * This snippet shows the intended params & responses and includes a * small mock SDK so you can demo today on your docs/homepage. * * WHEN LIVE, REPLACE with: * import { CNode } from "@cnode/sdk"; * const cnode = new CNode({ apiKey: process.env.CNODE_API_KEY }); * * CLUSTERS (preview): * "finance", "product", "hr", "marketing", "compliance", "supply_chain" * * COMMON GOALS by cluster (preview examples): * finance: "revenue_forecast", "cashflow_forecast", "break_even", * "profitability", "roi_forecast", "valuation_dcf", * "price_elasticity", "anomaly_detection" * product: "demand_forecast", "inventory_coverage", "return_rate_forecast" * hr: "headcount_forecast", "attrition_forecast" * marketing: "mql_forecast", "cac_ltv_projection" * compliance: "esg_risk_score", "anomaly_detection" * * RUN PARAMS (preview): * { * projectId: string, // required * cluster: string, // required (see CLUSTERS) * goal: string, // required (see GOALS) * horizon: "3M"|"6M"|"12M"|string, // required * inputs: object, // required, domain-specific * explainability?: boolean, // default: true * options?: { * confidence?: number, // 0.5..0.99; default: 0.8 * includeIntervals?: boolean, // return prediction bands * sensitivity?: { topK?: number }, // top drivers count * backtest?: { from: string, to: string, metric?: "WAPE"|"MAE"|"RMSE" }, * retrain?: "auto"|"never", * tags?: string[], * metadata?: Record<string, unknown> * } * } * * RUN RESULT (preview): * { * run_id: string, * forecast: Array<{ date: "YYYY-MM-DD", value: number }>, * intervals?: Array<{ date: string, lower: number, upper: number, confidence: number }>, * explanations?: { * global_top_features: Array<{ feature: string, weight: number }>, * local?: Array<{ date: string, contributions: Array<{ feature: string, weight: number }> }> * }, * diagnostics?: { * metrics?: { WAPE?: number, MAE?: number, RMSE?: number }, * retrain?: boolean, * warnings?: string[] * } * } * * SECURITY NOTE: * Keep real API keys server-side. For homepage demos, use mocked data or a * short-lived preAuth token from a server route. */ // ---------- Types (preview) ---------- type Cluster = | "finance" | "product" | "hr" | "marketing" | "compliance" | "supply_chain" | (string & {}); // allow custom type Goal = | "revenue_forecast" | "cashflow_forecast" | "break_even" | "profitability" | "roi_forecast" | "valuation_dcf" | "price_elasticity" | "anomaly_detection" | "demand_forecast" | "inventory_coverage" | "return_rate_forecast" | "headcount_forecast" | "attrition_forecast" | "mql_forecast" | "cac_ltv_projection" | "esg_risk_score" | (string & {}); // allow custom type BacktestMetric = "WAPE" | "MAE" | "RMSE"; interface RunOptions { confidence?: number; // default: 0.8 includeIntervals?: boolean; sensitivity?: { topK?: number }; // default: 5 backtest?: { from: string; to: string; metric?: BacktestMetric }; retrain?: "auto" | "never"; tags?: string[]; metadata?: Record<string, unknown>; } interface RunParams { projectId: string; cluster: Cluster; goal: Goal; horizon: "3M" | "6M" | "12M" | (string & {}); inputs: Record<string, unknown>; explainability?: boolean; options?: RunOptions; } interface RunResult { run_id: string; forecast: Array<{ date: string; value: number }>; intervals?: Array<{ date: string; lower: number; upper: number; confidence: number }>; explanations?: { global_top_features: Array<{ feature: string; weight: number }>; local?: Array<{ date: string; contributions: Array<{ feature: string; weight: number }> }>; }; diagnostics?: { metrics?: Partial<Record<BacktestMetric, number>>; retrain?: boolean; warnings?: string[]; }; } // ---------- Temporary SDK shim for demos (remove once SDK is live) ---------- class MockCNode { constructor( private cfg: { /** * If you supply a baseUrl (e.g. "/api/mock/cnode"), we'll POST to: * `${baseUrl}/scenarios:run` * Otherwise we synthesize a deterministic forecast locally. */ baseUrl?: string; /** * Do NOT put real API keys in client-side code. This is a placeholder to * illustrate the SDK signature only. */ apiKey?: string; apiVersion?: string; // e.g. "2025-09-01" } = {} ) { this.cfg.apiVersion ??= "2025-09-01"; } scenarios = { run: async (p: RunParams): Promise<RunResult> => { if (this.cfg.baseUrl) { // Proxy to your mock endpoint while backend is under development const res = await fetch(`${this.cfg.baseUrl}/scenarios:run`, { method: "POST", headers: { "Content-Type": "application/json", "X-API-Version": this.cfg.apiVersion!, "X-Demo-Mode": "true", // Example only; never ship real keys in browser Authorization: this.cfg.apiKey ? `Bearer ${this.cfg.apiKey}` : undefined } as Record<string, string>, body: JSON.stringify({ project_id: p.projectId, cluster: p.cluster, goal: p.goal, horizon: p.horizon, inputs: p.inputs, explainability: p.explainability ?? true, options: p.options, _note: "SDK-preview: replace mock route with production once live" }) }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(`Mock SDK ${res.status}: ${err.message ?? res.statusText}`); } return res.json(); } // Fallback: synthesize a deterministic, upward-trending demo series const months = parseHorizonToMonths(p.horizon); const start = new Date(Date.UTC(2025, 0, 1)); const base = 42000; const step = 3500; const forecast = Array.from({ length: months }, (_, i) => { const d = new Date(start); d.setUTCMonth(d.getUTCMonth() + i); const trend = base + step * i; const season = 1 + 0.1 * Math.sin((2 * Math.PI * i) / 12); // ±10% seasonality return { date: d.toISOString().slice(0, 10), value: Math.round(trend * season) }; }); const intervals = forecast.map((pnt) => ({ date: pnt.date, lower: Math.round(pnt.value * 0.9), upper: Math.round(pnt.value * 1.1), confidence: (p.options?.confidence ?? 0.8) })); const explanations: RunResult["explanations"] = { global_top_features: [ { feature: "trend", weight: 0.45 }, { feature: "seasonality", weight: 0.32 }, { feature: "promo_index", weight: 0.11 } ] }; const diagnostics: RunResult["diagnostics"] = { metrics: p.options?.backtest ? { WAPE: 0.14, MAE: 5200, RMSE: 7300 } : undefined, retrain: p.options?.retrain === "auto", warnings: [] }; return { run_id: "mock-sdk-run-001", forecast, intervals: p.options?.includeIntervals !== false ? intervals : undefined, explanations: p.explainability === false ? undefined : explanations, diagnostics }; } }; } // ---------- Helper ---------- function parseHorizonToMonths(h: RunParams["horizon"]): number { if (typeof h !== "string") return 12; const m = h.match(/^(\d+)\s*(M|m|months?)$/); if (m) return Math.max(1, parseInt(m[1], 10)); const y = h.match(/^(\d+)\s*(Y|y|years?)$/); if (y) return Math.max(1, parseInt(y[1], 10) * 12); // common presets if (h === "3M") return 3; if (h === "6M") return 6; if (h === "12M") return 12; return 12; } // ---------- Example usage for docs/homepage ---------- (async () => { // OPTION A (no network): synth data only const cnode = new MockCNode(); // OPTION B (with mock API): POST to your server route until prod is live // const cnode = new MockCNode({ baseUrl: "/api/mock/cnode" }); const run = await cnode.scenarios.run({ projectId: "demo-finance", cluster: "finance", goal: "revenue_forecast", // try: "cashflow_forecast", "valuation_dcf" horizon: "12M", inputs: { currency: "EUR", revenue_history: [ { date: "2024-09-01", value: 42000 }, { date: "2025-08-01", value: 86500 } ], cost_history: [ { date: "2024-09-01", value: -28000 }, { date: "2025-08-01", value: -52500 } ], promo_index: [{ date: "2025-06-01", value: 0.6 }] }, explainability: true, options: { confidence: 0.8, includeIntervals: true, sensitivity: { topK: 5 }, backtest: { from: "2025-01-01", to: "2025-08-01", metric: "WAPE" }, retrain: "auto", tags: ["homepage-demo"], metadata: { source: "marketing-site" } } }); console.log("Run:", run.run_id); console.table(run.forecast.slice(0, 6)); // preview first 6 points if (run.intervals) console.table(run.intervals.slice(0, 3)); console.log("Top drivers:", run.explanations?.global_top_features?.slice(0, 5)); console.log("Metrics:", run.diagnostics?.metrics); })();
Sicherheit & Governance
API-Keys nie im Browser – serverseitig oder per kurzlebigem preAuth-Token.
EU-Hosting, DSGVO-Konformität, Mandanten-Isolation.
Versionierung & Audit-Trails via Governance-Layer.
Roadmap & GA-Hinweis
Die SDK-Signaturen stehen – Details können sich bis GA noch ändern. Ziel: ein stabil versioniertes npm-Package (@cnode/sdk
) mit klarer SemVer-Strategie und Developer-Guides.
Weitere Beiträge entdecken
Bleib auf dem Laufenden mit unseren neuesten Artikeln zu datenbasierter Planung, KI-gestützter Szenariosteuerung und Best Practices aus der Anwendung von cNode.