SDKs
CommissionSight ships three official, open-source clients that wrap the full account-facing API — pick your stack: TypeScript / JavaScript (documented below), Python (jump to Python SDK), and C# / .NET (jump to .NET / C# SDK).
@commissionsight/sdk is the official, fully-typed client for the API. It wraps every endpoint, so you
get autocomplete and type-safety instead of hand-rolling fetch calls. It’s a small, zero-dependency,
open-source package:
- npm:
@commissionsight/sdk - Source (MIT): github.com/commissionsight/sdk
You need an active account and an API token issued to you. Without an active token the SDK can’t read or write anything — access is entirely controlled by your token.
Install
npm install @commissionsight/sdk # or: bun add / pnpm add / yarn addInitialize
import { CommissionSightClient } from '@commissionsight/sdk';
const cs = new CommissionSightClient({ baseUrl: 'https://api.commissionsight.com/v1', token: process.env.CS_TOKEN!, // your API token});Quickstart — upload, poll, read
// 1. Upload a statement (idempotent — safe to retry with the same key)const { jobId } = await cs.uploadFile({ file, // a File/Blob carrierId, periodYear: 2026, periodMonth: 4, idempotencyKey: 'humana-2026-04-v1',});
// 2. Poll the job until it's donelet job = await cs.getJob(jobId);while (job.status === 'queued' || job.status === 'processing') { await new Promise((r) => setTimeout(r, 1500)); job = await cs.getJob(jobId);}
// 3. Read the scored resultsconst results = await cs.getJobResults(jobId, { status: 'yellow' });Method map
The SDK wraps the full account-facing API surface — every /v1 endpoint your token can call has a method.
| Area | Methods |
|---|---|
| Auth / session | setToken, me, health |
| Workspaces | listWorkspaces, createWorkspace (2.3.0+; requires the multi-workspace feature) — and uploadFile({ workspaceId }) |
| Carriers | listCarriers, getCarrier, listCarrierGroups, resolveCarrier (2.5.0+), listConfigs, getConfigVersion, createConfig, testConfig, inferConfig |
| Files | uploadFile, listFiles, getFile, rescoreFile, retractFile, purgeFile |
| Jobs | listJobs, getJob, getJobResults, getJobDeltas, retryJob, downloadExceptions |
| Members | listMembers, getMember, getMemberJourney, getMemberTimeline, getMemberLastSeen |
| Policies | getPolicyJourney |
| Team | listTeam, inviteTeammate, removeTeammate |
| Audit | listAudit({ action?, limit?, offset? }) |
| Comparisons | compare({ from, to, carrierId?, granularity? }) |
| Reports | rollup, attrition, attritionSeries, dataQuality |
| Chargebacks | listChargebacks({ period?, carrierId? }) |
| Expected rates | listExpectedRates, upsertExpectedRate, deleteExpectedRate |
| Webhooks | listWebhooks, createWebhook, deleteWebhook |
| Billing | getBilling, updateBilling, billingPreview, createSetupIntent, savePaymentMethod |
resolveCarrier(groupId, file) powers “pick the brand, we detect the product”: it ranks a brand’s member carriers against a sample file and returns { best, ranked, ambiguous } — confirm when ambiguous, then uploadFile({ carrierId: best.carrierId, … }) to the detected carrier. listCarrierGroups() lists the brands; listCarriers() rows carry an optional groupId. See Carrier brands.
getJobResults rows include commissionOwed per member (the expected-vs-actual drilldown) and accept status=red,yellow for the combined at-risk view. Every row also carries memberRefId + policyRefId (and those columns are in every CSV export), so you can hand the id to getMemberJourney / getPolicyJourney for the full audit history. downloadExceptions(jobId) returns the rejected-rows CSV (retained 30 days).
Every method returns typed results matching the API reference. For example:
const stale = (await cs.listFiles()).data.filter((f) => f.rescoreSuggested);for (const f of stale) await cs.rescoreFile(f.id); // fix out-of-order periods
const dq = await cs.dataQuality('2026-04'); // statement-quality signalif (dq.overall !== 'ok') console.warn('Check your statements before trusting churn.');Errors
Failed calls throw an ApiError carrying the HTTP status and the parsed problem body — switch on the
stable code (see API conventions):
import { ApiError } from '@commissionsight/sdk';
try { await cs.uploadFile({ /* … */ });} catch (e) { if (e instanceof ApiError && e.status === 409) { // e.g. account_not_provisioned — finish setup first }}Correcting or removing a statement
Uploading over a carrier+period that already has a file fails with 409 (period_exists) — re-uploads
are never silently destructive. To apply a corrected file, catch it and re-send with replace: true
(the existing data is retracted and the corrected file re-ingested atomically; the following month is
re-scored). To remove a period entirely, retractFile(fileId).
import { ApiError } from '@commissionsight/sdk';
const args = { file, carrierId, periodYear: 2026, periodMonth: 4 };try { await cs.uploadFile(args);} catch (e) { if (e instanceof ApiError && (e.body as { code?: string })?.code === 'period_exists') { await cs.uploadFile({ ...args, replace: true }); // confirm + overwrite } else throw e;}
// Or unapply a period (no re-upload):await cs.retractFile(fileId);Python SDK
For Python apps, the native Python SDK mirrors this client — the same endpoints and shapes, kept in parity with the TypeScript SDK. Zero-dependency (standard library only), open-source (MIT), Python 3.8+.
- PyPI:
commissionsight - Source (MIT): github.com/commissionsight/python-sdk
pip install commissionsightimport osfrom commissionsight import CommissionSightClient
cs = CommissionSightClient( "https://api.commissionsight.com/v1", token=os.environ["CS_TOKEN"], # your API token)
# Same surface as the TypeScript client — upload, poll, then read scored results.res = cs.upload_file(file, carrier_id=carrier_id, period_year=2026, period_month=4)job = cs.get_job(res["jobId"])results = cs.get_job_results(res["jobId"], status="yellow")Methods use idiomatic snake_case (get_job_results, upsert_expected_rate, …) and admin endpoints
live under cs.admin. Responses are plain dicts with TypedDict shapes (the package ships
py.typed). The full method map, errors (ApiError), and correction flow above apply identically —
see the repo README for Python-idiomatic signatures.
.NET / C# SDK
For .NET apps, the native C# SDK mirrors this client — the same endpoints and shapes, kept in parity with the TypeScript SDK. Open-source (MIT), targeting net9.0 and net10.0.
- NuGet:
CommissionSight - Source (MIT): github.com/commissionsight/csharp-sdk
dotnet add package CommissionSightusing CommissionSight;
using var client = new CommissionSightClient(new CommissionSightClientOptions{ BaseUrl = "https://api.commissionsight.com/v1", Token = Environment.GetEnvironmentVariable("COMMISSIONSIGHT_TOKEN"),});
// Same surface as the TypeScript client — upload, poll, then read scored results.var me = await client.MeAsync();The full method map, errors, and correction flow above apply identically — see the repo README for the C#-idiomatic signatures.