@finishkit/sdk

TypeScript SDK for the FinishKit API. Scan GitHub repos with LLM-powered analysis to find security vulnerabilities, deployment blockers, stability issues, and code quality problems.
Install
npm install @finishkit/sdk
Quick Start
import { FinishKit, ProjectNotFoundError } from '@finishkit/sdk'
const fk = new FinishKit({ apiKey: process.env.FINISHKIT_API_KEY! })
const result = await fk.scan({
repoOwner: 'myorg',
repoName: 'myrepo',
})
console.log(`Found ${result.findings.length} issues`)
for (const finding of result.findings) {
console.log(`[${finding.severity}] ${finding.title}`)
}
Get your API key at finishkit.app/dashboard/settings under the Developer tab.
API Reference
Constructor
const fk = new FinishKit({
apiKey: 'fk_live_...',
baseUrl: 'https://finishkit.app',
})
fk.scan(options) - Full Lifecycle
The primary method. Finds the project, triggers a scan, polls until complete, and returns results.
const result = await fk.scan({
repoOwner: 'myorg',
repoName: 'myrepo',
runType: 'baseline',
commitSha: 'abc123',
idempotencyKey: 'unique-id',
onProgress: (run) => {
console.log(run.status, run.progress + '%')
},
pollIntervalMs: 2000,
timeoutMs: 600000,
})
Note: scan() does NOT create projects. The repository must be connected to FinishKit via the dashboard first. Throws ProjectNotFoundError if not found.
fk.projects
const { projects } = await fk.projects.list()
const { project } = await fk.projects.get(projectId)
fk.runs
const { run } = await fk.runs.create({
projectId: 'uuid',
runType: 'baseline',
commitSha: 'abc123',
idempotencyKey: 'key',
})
const { run } = await fk.runs.get(runId)
const { findings, patches, artifacts, metrics } = await fk.runs.outcomes(runId)
const { events } = await fk.runs.events(runId, { since: isoString, limit: 100 })
await fk.runs.cancel(runId)
Types
type RunStatus = 'queued' | 'running' | 'done' | 'failed' | 'canceled'
type RunType = 'baseline' | 'pr' | 'manual_patch'
type FindingCategory = 'blockers' | 'security' | 'deploy' | 'stability' | 'tests' | 'ui'
type FindingSeverity = 'critical' | 'high' | 'medium' | 'low'
interface Finding {
id: string
title: string
category: FindingCategory
severity: FindingSeverity
detail_md: string
file_path: string | null
line_start: number | null
line_end: number | null
suggested_fix: object | null
}
interface ScanResult {
run: Run
findings: Finding[]
patches: Patch[]
artifacts: Artifact[]
metrics: ScanMetrics
}
Error Handling
import {
FinishKitError,
AuthenticationError,
BillingError,
NotFoundError,
RateLimitError,
ValidationError,
ProjectNotFoundError,
} from '@finishkit/sdk'
try {
const result = await fk.scan({ repoOwner: 'org', repoName: 'repo' })
} catch (err) {
if (err instanceof ProjectNotFoundError) {
} else if (err instanceof AuthenticationError) {
} else if (err instanceof BillingError) {
} else if (err instanceof RateLimitError) {
} else if (err instanceof FinishKitError) {
}
}
For AI Agents
If you are an AI assistant (Claude, Copilot, Cursor, etc.) helping a developer use FinishKit:
Setup
npm install @finishkit/sdk
export FINISHKIT_API_KEY=fk_live_...
Minimal working example
import { FinishKit, ProjectNotFoundError } from '@finishkit/sdk'
const fk = new FinishKit({ apiKey: process.env.FINISHKIT_API_KEY! })
try {
const result = await fk.scan({ repoOwner: 'myorg', repoName: 'myrepo' })
const critical = result.findings.filter(f => f.severity === 'critical')
console.log(`${critical.length} critical issues found`)
} catch (err) {
if (err instanceof ProjectNotFoundError) {
console.log('Connect the repo at https://finishkit.app/dashboard first')
}
}
Key facts:
- Env var:
FINISHKIT_API_KEY (format: fk_live_ followed by 32 alphanumeric chars)
scan() blocks until complete (2-8 minutes typical). Use onProgress callback for updates.
- Projects must be created via the dashboard - the API key auth path cannot create projects
run.current_phase is available at runtime but not in TypeScript types - use (run as any).current_phase or a local interface extension if needed
- All error types are named exports from
@finishkit/sdk
- Rate limits: 10 scans/hour, 60 GET requests/min. Respect
Retry-After on 429 responses.
Requirements
- Node.js 18+ (or Deno, Bun, any runtime with native
fetch)
- A FinishKit account with at least one project connected
License
MIT. See LICENSE.