Skip to content

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:

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

Terminal window
npm install @commissionsight/sdk # or: bun add / pnpm add / yarn add

Initialize

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 done
let 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 results
const 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.

AreaMethods
Auth / sessionsetToken, me, health
WorkspaceslistWorkspaces, createWorkspace (2.3.0+; requires the multi-workspace feature) — and uploadFile({ workspaceId })
CarrierslistCarriers, getCarrier, listCarrierGroups, resolveCarrier (2.5.0+), listConfigs, getConfigVersion, createConfig, testConfig, inferConfig
FilesuploadFile, listFiles, getFile, rescoreFile, retractFile, purgeFile
JobslistJobs, getJob, getJobResults, getJobDeltas, retryJob, downloadExceptions
MemberslistMembers, getMember, getMemberJourney, getMemberTimeline, getMemberLastSeen
PoliciesgetPolicyJourney
TeamlistTeam, inviteTeammate, removeTeammate
AuditlistAudit({ action?, limit?, offset? })
Comparisonscompare({ from, to, carrierId?, granularity? })
Reportsrollup, attrition, attritionSeries, dataQuality
ChargebackslistChargebacks({ period?, carrierId? })
Expected rateslistExpectedRates, upsertExpectedRate, deleteExpectedRate
WebhookslistWebhooks, createWebhook, deleteWebhook
BillinggetBilling, 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 signal
if (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+.

Terminal window
pip install commissionsight
import os
from 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.

Terminal window
dotnet add package CommissionSight
using 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.