Pentify
SDKs

TypeScript / JavaScript

@pentify/sdk — typed client generated from the Pentify OpenAPI 3.1 spec. ESM + CJS dual build. Works in Node 18+, Bun, Deno, and the Cloudflare Workers runtime.

Install

npm install @pentify/sdk
# or
pnpm add @pentify/sdk
# or
bun add @pentify/sdk

Client construction

import { Pentify } from "@pentify/sdk";

const pentify = new Pentify({
  apiKey: process.env.PENTIFY_API_KEY!,
  // optional:
  baseUrl: "https://api.pentify.io/v1",
  timeoutMs: 30_000,
  maxRetries: 5, // exponential backoff on 429 / 5xx
  fetch, // override for tests or alternative runtimes
});

Namespaced API

NamespaceSurface
pentify.scanslist, create, retrieve, cancel
pentify.targetslist, create, retrieve, verify, delete
pentify.reportsretrieve, pdfUrl, listFindings
pentify.usageretrieve
pentify.webhookslist, create, retrieve, delete, verify

Async idioms

Every method is async and returns a typed promise.

const scan = await pentify.scans.create({
  target: "example.com",
  scanType: "quick",
});

for await (const page of pentify.scans.list({ limit: 100 }).pages()) {
  for (const s of page.data) console.log(s.id, s.status);
}

Errors

import {
  PentifyError,
  InsufficientTokensError,
  RateLimitedError,
} from "@pentify/sdk";

try {
  await pentify.scans.create({ target: "example.com", scanType: "quick" });
} catch (e) {
  if (e instanceof InsufficientTokensError) {
    console.log("need", e.required, "have", e.balance, "→", e.topUpUrl);
  } else if (e instanceof PentifyError) {
    console.log(e.code, e.requestId);
  }
}

See Errors for the full code list.

Retry behavior

The client retries 429, 502, 503, and 504 automatically with exponential backoff (1s base, ±25% jitter, doubling, cap 30s). Honors Retry-After when present. Other 5xx and any 4xx are not retried.

Webhook verification

import { Pentify } from "@pentify/sdk";

const event = pentify.webhooks.verify({
  header: req.headers.get("pentify-signature")!,
  rawBody: await req.text(),
  secret: process.env.PENTIFY_WEBHOOK_SECRET!,
});

if (event.type === "scan.completed") {
  // event.data is fully typed.
}
Note
See Webhooks for the full signing scheme, replay window, and verification rules.