Skip to content

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:

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

It’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:

Terminal window
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 config

3. 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 January
console.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-now

Each 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

SituationStatusFlags
Present both months, nothing tracked changed🟢 green
Commission changed🟡 yellowCOMMISSION_CHANGED
Other tracked field changed🟡 yellowDATA_CHANGED
Present last month, gone this month🔴 redDROPPED
First time seen🟢 greenNEW
Returned after a drop🟡 yellowREAPPEARED (+ REAPPEARED_WITH_DELTA if commission differs)