Skip to main content
Glama

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 (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 typesimport 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 Plugins distribution so AI coding agents (Cursor, Claude Code, and any other Open-Plugins-compatible tool) can install Kamy as a single plugin and get 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 this repository (https://github.com/rakanalalami/kamy) and follow the host's plugin-install flow. The agent will read the manifest and load the components automatically.

See the Open Plugins specification for the full schema.

A
license - permissive license
-
quality - not tested
-
maintenance - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rakanalalami/kamy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server