PDF generation API for developers. Ship invoices, receipts, contracts, and reports with gorgeous defaults.
Install
# SDK — in your app
npm i @kamydev/sdk
# CLI — globally for scripts, CI, previews
npm i -g @kamydev/cli
import Kamy from "@kamydev/sdk";
const kamy = new Kamy({ apiKey: process.env.KAMY_API_KEY! });
const pdf = await kamy.render({
template: "invoice",
data: { invoiceNumber: "INV-001", total: 1500, currency: "USD" },
});
console.log(pdf.url); // signed URL, valid 1 hour
What's New
| Date | Change |
|---|---|
| Apr 2026 | GET /v1/renders now returns a per-render cost (in major currency units) plus a top-level currency: "usd". Denormalized at insert time via a Postgres trigger reading users.plan, so the cost reflects your plan when the render happened. Surfaced in SDK 0.2.3 as RenderSummary.cost / RendersListResult.currency. |
| Apr 2026 | SDK now ships OpenAPI-generated types — import type { paths, components } from "@kamydev/sdk/openapi" for fully-typed request/response shapes derived from the live spec. Raw openapi.json shipped too. |
| Apr 2026 | Per-template JSON Schema validation at render time via Ajv (formats enabled). Previously only required was checked — full type/format/enum/oneOf enforcement is now live. |
| Apr 2026 | options.encrypt — AES-256 password protection + permission flags (printing, copying, modifying, annotating, form-fill, accessibility, assembly). |
| Apr 2026 | OpenAPI 3.0.3 spec now covers all 19 /v1/* routes with full request/response schemas — https://kamy.dev/api/openapi.json |
| Apr 2026 | kamy push <file> CLI + client.pushTemplate() SDK + idempotent PUT /v1/templates upsert. Run it on every commit to sync templates from the repo. |
| Apr 2026 | options.validateOnly: true — dry-run any render to validate the payload without consuming quota. |
| Apr 2026 | options.pdfA: "1b" | "2b" | "3b" — best-effort PDF/A archival tagging via embedded sRGB ICC OutputIntent + XMP. |
| Apr 2026 | options.metadata (info dict) + options.watermark (pdf-lib stamp, distinct from theme.watermark). |
| Apr 2026 | options.inlineImages + options.compressImages — server-side image hardening, defends against expiring signed URLs. |
Full per-release detail in CHANGELOG.md.
Architecture
Kamy is a Turborepo monorepo containing:
| Package | Description |
|---|---|
apps/web |
Next.js 15 app — landing page, dashboard, REST API |
apps/mcp |
Cloudflare Worker — MCP server for AI coding agents |
apps/docs |
Nextra docs site |
packages/sdk |
@kamydev/sdk — publishable TypeScript SDK |
packages/templates |
@kamy/templates — PDF template HTML/CSS + Zod schemas |
packages/ui |
@kamy/ui — shared shadcn/Radix UI components |
packages/shared |
@kamy/shared — types, utils, observability, email |
packages/tsconfig |
@kamy/tsconfig — shared TypeScript configs |
Prerequisites
- Node.js 22+
- pnpm 10+
- Supabase CLI (
brew install supabase/tap/supabase) - Wrangler CLI (
pnpm add -g wrangler) — for MCP server
Local Development
# 1. Install dependencies
pnpm install
# 2. Copy env file and fill in values
cp .env.example apps/web/.env.local
# 3. Start local Supabase (requires Docker)
supabase start
# 4. Apply database migrations
supabase db reset
# 5. Generate TypeScript types from schema
supabase gen types typescript --local > packages/shared/src/types/database.ts
# 6. Start all apps in dev mode
pnpm dev
The web app runs at https://kamy.dev
Commands
pnpm dev # Start all apps with Turbopack (hot reload)
pnpm build # Production build all apps
pnpm typecheck # TypeScript check across all packages
pnpm lint # Biome lint + format check
pnpm lint:fix # Biome auto-fix
pnpm test # Run all tests (Vitest unit + Playwright E2E)
pnpm test:unit # Vitest unit tests only
pnpm test:e2e # Playwright E2E tests only
pnpm clean # Remove all build artifacts
Database
Migrations live in supabase/migrations/. They are applied in order by timestamp.
# Reset and reseed local DB
supabase db reset
# Create a new migration
supabase migration new <name>
# Push to remote Supabase project
supabase db push
Deployment
- Web app: Deployed to Vercel on merge to
main - MCP server: Deployed to Cloudflare Workers via
wrangler deploy - Database: Hosted on Supabase Cloud
Environment Variables
See .env.example for all required variables with descriptions.
Tech Stack
- Framework: Next.js 15 (App Router, React Server Components, Turbopack)
- Language: TypeScript 5.7+ strict
- Database: Supabase (Postgres 16 + Auth + Storage)
- Styling: Tailwind CSS v4 (Oxide engine)
- Payments: Stripe (Meters API)
- PDF Engine: Browserless.io v2
- Email: Resend + React Email
- Observability: Sentry + PostHog + Axiom
- Testing: Vitest + Playwright + MSW
Open Plugins
This repository ships an Open Pluginsdistribution so AI coding agents (Cursor, Claude Code, and any otherOpen-Plugins-compatible tool) can install Kamy as a single plugin andget a ready-to-use PDF pipeline.
The plugin bundles four components at the repo root:
| Path | Component | Purpose |
|---|---|---|
.plugin/plugin.json |
Manifest | Name, version, metadata, declared components |
skills/kamy/SKILL.md |
Skill | Teaches the agent when and how to render PDFs |
rules/kamy-sdk.mdc |
Rule | Coding conventions for @kamydev/sdk and the REST API |
agents/pdf-template-author.md |
Sub-agent | Specialised template-design agent (Handlebars + print CSS) |
.mcp.json |
MCP server | Hosted MCP at mcp.kamy.dev exposing render tools |
To install the plugin in a supported agent, point it at thisrepository (https://github.com/rakanalalami/kamy) and follow thehost's plugin-install flow. The agent will read the manifest andload the components automatically.
See the Open Plugins specification forthe full schema.