End-to-end walkthrough
This walks through onboarding a carrier and processing your first two months with the TypeScript SDK.
0. Install the SDK
The official client is published on npm with zero runtime dependencies:
npm i @commissionsight/sdk# or: bun add @commissionsight/sdk · pnpm add @commissionsight/sdk · yarn add @commissionsight/sdkIt’s fully typed and runs anywhere fetch is available — Node 18+, Bun, Deno, Cloudflare Workers,
and the browser.
1. Get a token
The CommissionSight team issues your account API token (shown once). Export it:
export CS_TOKEN="cs_…"export CS_BASE="https://api.commissionsight.com/v1"2. Pick a carrier + config
List carriers and confirm a config exists (global default or your account override):
import { CommissionSightClient } from '@commissionsight/sdk';const client = new CommissionSightClient({ baseUrl: process.env.CS_BASE!, token: process.env.CS_TOKEN! });
const carriers = await client.listCarriers();const carrierId = carriers.data[0].id;await client.listConfigs(carrierId); // ensure at least one active config3. Upload month 1, then month 2
import { readFileSync } from 'node:fs';
async function upload(path: string, year: number, month: number) { const file = new File([readFileSync(path)], path); const { jobId } = await client.uploadFile({ file, carrierId, periodYear: year, periodMonth: month }); // poll until done for (;;) { const job = await client.getJob(jobId); if (job.status === 'completed') return job; if (job.status === 'failed') throw new Error(job.error ?? 'ingest failed'); await new Promise((r) => setTimeout(r, 1000)); }}
await upload('jan.csv', 2025, 1); // all members NEW (green)const feb = await upload('feb.csv', 2025, 2); // deltas computed vs Januaryconsole.log(feb.stats); // { green, yellow, red, new, reappeared, … }Fixing a bad file (replace)
Re-uploading a period that already has a file is refused with 409 period_exists — it won’t silently
overwrite. Send replace: true to confirm: the old data is retracted and the corrected file
re-ingested atomically (dropped members leave no orphans), and the following month is re-scored.
import { ApiError } from '@commissionsight/sdk';
const file = new File([readFileSync('jan-corrected.csv')], 'jan-corrected.csv');const args = { file, carrierId, periodYear: 2025, periodMonth: 1 };try { await client.uploadFile(args);} catch (e) { if (e instanceof ApiError && (e.body as { code?: string })?.code === 'period_exists') { await client.uploadFile({ ...args, replace: true }); // confirmed overwrite } else throw e;}4. Read the grid
const results = await client.getJobResults(feb.jobId, { status: 'yellow' });for (const row of results.data) { console.log(row.memberExternalId, row.status, row.flags, row.commissionAmount);}5. Compare periods & export
const cmp = await client.compare({ from: '2025-01', to: '2025-02' });console.log(cmp.summary); // { green, yellow, red, new, reappeared, total }// cmp.data[] rows include memberName, memberExternalId, policyNumber + commission then-vs-nowEach comparison row carries the member’s name, external id, and policy number, so you can build a readable, searchable report or CSV directly from the response.
What “green/yellow/red” means
| Situation | Status | Flags |
|---|---|---|
| Present both months, nothing tracked changed | 🟢 green | — |
| Commission changed | 🟡 yellow | COMMISSION_CHANGED |
| Other tracked field changed | 🟡 yellow | DATA_CHANGED |
| Present last month, gone this month | 🔴 red | DROPPED |
| First time seen | 🟢 green | NEW |
| Returned after a drop | 🟡 yellow | REAPPEARED (+ REAPPEARED_WITH_DELTA if commission differs) |