@kepler-insights/sdk
v1.1.0
Published
Official TypeScript SDK for the Kepler Insights API — curated company-scoring intelligence over a 67-signal engine.
Maintainers
Readme
Kepler Insights — TypeScript SDK
Official TypeScript / JavaScript SDK for the Kepler Insights API — curated company-scoring intelligence over a 67-signal engine.
Install
npm install @kepler-insights/sdk
# or
pnpm add @kepler-insights/sdk
# or
yarn add @kepler-insights/sdkRequires Node 18+. Native fetch is the only network dep — no axios, no node-fetch polyfill needed. Works in Node, Deno, Bun, and Cloudflare Workers.
Quickstart
import { Kepler } from "@kepler-insights/sdk";
const client = new Kepler({ apiKey: "ki_live_..." });
const score = await client.score("stripe.com");
console.log(`${score.domain}: ${score.ki_rating} (${score.composite_score.toFixed(1)})`);
console.log(` team: ${score.buckets.team_structure.toFixed(1)}`);
console.log(` market: ${score.buckets.market_position.toFixed(1)}`);Sandbox keys (ki_test_...) accept only the 4 canned domains — acme.test, unicorn.test, struggling.test, cohort.test. See the Sandbox guide.
API surface
| Method | Endpoint | Returns |
|---|---|---|
| client.score(domain) | POST /v1/score | Score |
| client.getScore(domain) | GET /v1/score/{domain} | Score |
| client.startScore(domain) | POST /v1/score?wait=false | Job (Growth+) |
| client.getJob(jobId) | GET /v1/jobs/{job_id} | JobResponse |
| client.history(domain, { limit, cursor }) | GET /v1/score/{domain}/history | HistoryPage |
| client.iterHistory(domain, { maxRecords }) | (auto-paginates) | AsyncIterable<HistoryRecord> |
| client.cohort(domain) | GET /v1/company/{domain}/cohort | Cohort |
| client.confidence(domain) | GET /v1/company/{domain}/confidence | Confidence |
| client.distribution() | GET /v1/distribution | Distribution |
| client.movers(window) | GET /v1/movers | Movers |
| client.signals() | GET /v1/signals | SignalsManifest |
| client.usage() | GET /v1/usage | Usage |
Every response shape is exported as a TypeScript type from the package root.
Async cold scoring
Cold scoring takes 30–60 seconds. On Growth and above, you can start a job and poll without holding an HTTP connection open:
const job = await client.startScore("stripe.com");
const score = await job.wait({ timeoutMs: 180_000 });
console.log(score.composite_score);If the API short-circuits to a cached-fresh response (no cold work needed), startScore returns a Job already in the complete state — wait() returns instantly. This mirrors Stripe's payment_intent "no action needed" pattern.
Error handling
Every error inherits from KeplerError. Branch with instanceof:
import {
Kepler,
AuthError,
ColdBudgetExhausted,
FreeTierSandboxOnly,
NotFound,
RateLimitError,
ScoringTimeout,
} from "@kepler-insights/sdk";
try {
const score = await client.score("stripe.com");
} catch (err) {
if (err instanceof FreeTierSandboxOnly) {
console.log("Upgrade to Starter for live scoring.");
} else if (err instanceof ColdBudgetExhausted) {
console.log(`Monthly cap hit. Resets in ${err.retryAfter}s.`);
} else if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry in ${err.retryAfter}s.`);
} else if (err instanceof ScoringTimeout) {
console.log("Cold scoring exceeded sync budget — use startScore() for async.");
} else if (err instanceof NotFound) {
console.log("Never scored. Trigger one with score(domain).");
} else if (err instanceof AuthError) {
console.log("Invalid or revoked API key.");
} else {
throw err;
}
}The SDK auto-retries 5xx and network errors with exponential backoff (3 attempts default). It never retries 4xx — those are caller errors.
Configuration
const client = new Kepler({
apiKey: "ki_live_...",
baseUrl: "https://api.keplerinsights.us", // override only for testing
timeoutMs: 70_000, // per-request timeout
retries: 3, // 5xx retry attempts
});For custom transports (proxies, mTLS, etc.) pass your own fetch:
import { Kepler } from "@kepler-insights/sdk";
import { ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://proxy.local:8080");
const customFetch: typeof fetch = (input, init) =>
fetch(input, { ...init, dispatcher } as RequestInit);
const client = new Kepler({ apiKey: "ki_live_...", fetchImpl: customFetch });Module compatibility
Dual ESM + CJS published. Use whichever your project prefers:
// ESM
import { Kepler } from "@kepler-insights/sdk";// CommonJS
const { Kepler } = require("@kepler-insights/sdk");TypeScript declarations ship in both flavors (.d.ts and .d.cts).
Development
git clone <repo>
cd Ki_dev/sdk-typescript
npm install
npm test # vitest
npm run typecheck # tsc --noEmit
npm run build # tsup → dist/License
MIT. The API itself is proprietary; the SDK wrapper is MIT-licensed so you can vendor it freely.
