@kynth/api
Official TypeScript SDK for Kynth Core — the AI back-end for your product. Parse documents, extract fields, redact PII, analyze contracts, fight chargebacks, and enrich companies through one typed client.
npm i @kynth/api
Quickstart
import { KynthCore } from "@kynth/api";
const kynth = new KynthCore({ apiKey: process.env.KYNTH_API_KEY! });
const doc = await kynth.parse({ fileUrl: "https://…/invoice.pdf" });
console.log(doc.totalAmount);
console.log(doc.usage.balanceRemaining);
Get a key (and 500 free credits) at api.kynth.studio. Zero runtime dependencies — works on Node 18+, browsers, and edge/worker runtimes with a global fetch.
Methods
Every method returns the endpoint result plus a usage: { credits, balanceRemaining } envelope. A non-2xx response throws a typed KynthError (and never burns credits).
await kynth.parse({ fileUrl });
await kynth.extract({ text, fields: ["order", "total"] });
await kynth.classify({ text, labels: ["billing", "tech"] });
await kynth.summarize({ text, length: "standard" });
await kynth.redact({ text });
await kynth.sentiment({ text, aspects: ["product"] });
await kynth.contract({ fileUrl });
await kynth.chargeback({ reason, transaction, evidence });
await kynth.enrich({ email: "sam@stripe.com" });
await kynth.account();
Async & webhooks
A hundred-page contract doesn't fit in a request/response cycle. The document endpoints — parse, invoice, receipt, statement, resume, tables, split, compare, contract — take async: true and hand you a job instead of a result.
const job = await kynth.parse({ fileUrl, async: true });
const done = await kynth.waitForJob<ParseResult>(job.jobId);
if (done.status === "succeeded") console.log(done.result!.totalAmount);
else console.error(done.error);
async: true narrows the return type to a JobHandle, so the compiler tells you which one you got. Poll a single time with getJob(jobId) if you'd rather drive the loop yourself.
Every job reaches a terminal state. If the instance running yours dies mid-flight, it is marked failed with an explanation rather than left running forever — and you aren't billed for it. Nothing is silently retried; resubmit and you stay in control of the spend.
Webhooks
Pass a callbackUrl (public https) and the finished job is POSTed to it, signed with your account's webhook secret from the API keys page:
await kynth.parse({ fileUrl, async: true, callbackUrl: "https://you.example/hooks/kynth" });
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody: string, header: string, secret: string) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const got = header.replace(/^sha256=/, "");
return got.length === expected.length &&
timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}
Delivery is best-effort and never retried — polling is the source of truth.
Error handling
import { KynthCore, KynthError } from "@kynth/api";
try {
await kynth.parse({ fileUrl });
} catch (err) {
if (err instanceof KynthError) {
console.error(err.code, err.message);
}
}
Options
new KynthCore({
apiKey: "ksk_live_…",
baseUrl: "https://api.kynth.studio",
timeoutMs: 60_000,
fetch: customFetch,
});
Pricing
Pay-per-call credits, no subscription. Each endpoint burns at its own rate (1 credit = $0.01), and you're only charged on a successful call. See api.kynth.studio/docs.
MIT © Kynth Studios