Changelog

What's new in Kamy.

Every dev-visible change to the API, templates, and dashboard. Curated weekly. Have a question about a release? Email support.

Release

Kamy Ingest v0 — the inverse of render

POST a PDF, get back structured JSON plus a public verify URL that cryptographically proves the extraction matches the source byte-for-byte. The new MCP tool extract_document and the new /api/v1/extract endpoint give your agent a verifiable way to read documents from the outside world. Free tier: 50 extractions / month.

  • NEW
    POST /api/v1/extract. Five predefined templates ship in v0 — invoice, receipt, contract, id_document, generic_form. Source PDF via URL or base64. Claude Sonnet vision with tool_choice forced to the template schema, so the output is always strict typed JSON, never free text.
  • NEW
    Public verify URL — /extract/{id}. Side-by-side render of the source PDF and the structured extraction with the full hash chain. Recipients re-verify offline with Kamy's public Ed25519 key at /.well-known/kamy-extract-public-key.txt. The chain holds even if Kamy is offline at audit time.
  • NEW
    MCP tool extract_document live at mcp.kamy.dev/mcp. Drop into Claude, ChatGPT Apps, or Cursor and your agent immediately gains the ability to read inbound documents and act on a verifiable extraction.
  • NEW
    Downloadable proof bundle. /extract/{id}/report ships the full chain as a JSON artefact for archival. Pairs with a 16-line bash script in the docs so anyone can re-verify in three lines of openssl + jq.
  • NEW
    Pricing — Ingest extractions per tier. 50/mo on Free, 2,000/mo on Starter, 10,000/mo on Pro, 50,000/mo on Business, unlimited at $0.01 each on Scale. Public verify URL works on every tier including Free.
Release

Self-hosted Chromium — own your render infrastructure

Kamy no longer routes PDF generation through a third-party cloud service. Every render now runs on Kamy-owned Chromium containers deployed across three regions (IAD / CDG / SIN). Requests are routed to the nearest machine automatically. File sizes dropped 60–90% on image-heavy documents; warm render latency is under 1 s on the pre-warmed page pool.

  • NEW
    Self-hosted Chromium on Fly.io. PDF rendering runs on Kamy-owned infrastructure — your document contents no longer pass through a third-party service. Private documents stay private. The render pipeline is identical; no API changes required.
  • NEW
    Three-region deployment — machines in Ashburn (IAD), Paris (CDG), and Singapore (SIN). Fly.io anycast routes each request to the nearest healthy machine, cutting round-trip latency for customers in Europe and Asia-Pacific.
  • NEW
    Ghostscript compression. Every PDF is post-processed with Ghostscript after rendering. Image-heavy documents (property flyers, marketing collateral) are typically 60–90% smaller than raw Chromium output. Text-heavy documents (invoices, contracts) are unaffected. Pass compression: "printer" in the render options for 300 dpi output suitable for physical printing.
  • NEW
    10-slot pre-warmed page pool. Chromium pages are created at startup and reused across renders — no page-creation overhead on warm requests. Combined with the font cache below, p50 render latency is under 1 s for text-only documents.
  • NEW
    Google Fonts disk cache. Font requests to fonts.googleapis.com and fonts.gstatic.com are intercepted and served from local disk after the first fetch. Templates that load Google Fonts no longer pay a CDN roundtrip on every render.
Release

E-signatures — form filling, drag-to-place, webhooks, void

A full pass on the e-signature signer UX and API surface. Signers can now fill AcroForm fields embedded in the PDF (Phase 3a), and senders can attach field definitions to flat PDFs so they gain fillable overlays too (Phase 3b). The signature placeholder is visible inline in the preview and draggable to a custom position. Two new webhooks fire on completion and void. The PATCH void endpoint and its SDK method are now documented.

  • NEW
    In-flow form filler (Phase 3a). If the source PDF contains AcroForm widgets (text, checkbox, radio, dropdown), the signing page now shows fillable overlays aligned to each field. Values are stamped server-side before the PKI signature is applied. Required fields block submission until filled.
  • NEW
    Sender-placed fields for flat PDFs (Phase 3b). Pass placedFields on POST /v1/signatures to attach field definitions to any rendered PDF — even ones without AcroForm widgets. The signer sees branded overlays; the server stamps values onto the page content stream before sealing.
  • NEW
    Inline pdf.js preview with drag-to-place. The signer page now shows a full pdf.js preview with the signature placeholder rendered inline. Signers can drag the placeholder to their preferred position — the chosen coordinates are forwarded to the completion endpoint and override the sender-supplied default.
  • NEW
    Signature webhooks. signature.signed fires when a signer completes; signature.voided fires when an API caller voids a pending request. Both deliver the full signature request row as the event payload. Configure webhook endpoints at /dashboard/webhooks.
  • NEW
    Void endpoint. PATCH /v1/signatures/{id} with { action: "void" } cancels a pending request. Returns 409 if already signed, voided, or expired — idempotent on repeated void calls. Available as kamy.signatures.void(id) in the SDK.
  • NEW
    kamy.signatures.get(id) — fetch a single signature request by ID. Useful for polling status without pulling the full list. Backed by the new GET /v1/signatures/{id} endpoint.
  • CHANGED
    Invite email now shows the Kamy logo, a "Verified by Kamy" pill, ESIGN / UETA / eIDAS Article 25 consent copy, and a phishing-report mailto in the footer. Completion emails sent to both parties are branded consistently.
Release

PAdES-B-T + B-LT — on-document timestamps and offline revocation

The cryptographic sealing flow shipped earlier today is now ETSI EN 319 142-1 PAdES-B-LT: every signed PDF carries an RFC 3161 timestamp embedded as an unsigned attribute on the SignerInfo (B-T) and a CRL revocation snapshot embedded in the PKCS#7 SignedData (B-LT) so verifiers can confirm authenticity offline. Leaf certs now publish a CRL Distribution Point that resolves to a public /api/verify/crl endpoint, and the verify page surfaces a per-document profile badge (B-B / B-T / B-LT).

  • NEW
    RFC 3161 timestamp embedded in-document. The TSA token now lives in the PKCS#7 SignerInfo's unsignedAttrs SET as id-aa-signatureTimeStampToken, not just on the audit row. Acrobat Reader reads it directly from the signature panel — no internet round-trip needed at verification time.
  • NEW
    CRL revocation embedded. Every signed PDF now carries the active Kamy CA CRL inside SignedData.crls. Verifiers (Acrobat, openssl, the Kamy verify page) confirm the leaf cert wasn't revoked at signing time without making a network call.
  • NEW
    Public CRL endpoint at https://kamy.dev/api/verify/crl. Returns the active Kamy CA CRL in DER form (application/pkix-crl). New leaf certs include this URL as a CRL Distribution Point so any X.509-aware verifier follows it automatically.
  • NEW
    Signature-profile badge on the verify page. /verify/[hash] now shows which PAdES tier a given document carries — B-B (basic seal), B-T (with TSA timestamp), B-LT (with revocation snapshot). A bumped SIGNATURE_LENGTH from 8 KB to 16 KB keeps the placeholder slot large enough for all three layers.
  • CHANGED
    kamy.signatures.signWithPki() now returns has_revocation_info: boolean alongside timestamped. Same field on the MCP tool response and the POST /v1/sign/{renderId} envelope.
  • CHANGED
    Revocation reasons are persisted on signing_certs.revocation_reason_code (RFC 5280 §5.3.1: 1=keyCompromise, 4=superseded, etc.) and surface in the embedded CRL entries.
Release

E-signatures and cryptographic seals

Two complementary signing flows shipped. Send any rendered PDF for canvas e-signature in a single API call — recipients get a unique URL, draw their signature, and the stamped copy lands back in your renders log. Or seal a document with a PAdES X.509 signature so any tampering breaks the signature, and recipients verify it on kamy.dev/verify by drag-dropping the file. Cert custody is fully owned: an in-house Kamy CA root, KMS-encrypted at rest, issuing per-account leaf certs.

  • NEW
    Visual e-signature flow. POST /v1/signatures takes a render_id and signer email, returns a sign_url the recipient opens to draw their signature. Available via kamy.signatures.create(), the create_signature_request MCP tool, and the dashboard at /dashboard/signatures. If RESEND_API_KEY is configured, the API emails the signer automatically; otherwise hand-deliver the URL.
  • NEW
    Cryptographic PAdES signing. POST /v1/sign/{render_id} seals an existing render with an X.509 certificate. Any tampering breaks the signature. Available via kamy.signatures.signWithPki(), the pki_sign_pdf MCP tool, and kamy sign <render-id> from the CLI. Signed under Kamy's in-house CA — recipients verify authenticity at kamy.dev/verify.
  • NEW
    Public verify page at kamy.dev/verify. Drag-drop a PDF — the SHA-256 is computed in your browser with SubtleCrypto (the file never uploads), and the matching audit row, signer identity, cert chain, and RFC 3161 timestamp are shown. Or visit kamy.dev/verify/<sha256> directly.
  • NEW
    RFC 3161 timestamps. Every PKI-signed document receives a cryptographic timestamp from a public TSA — the audit trail records the trusted signing time independent of the signer's local clock. Opt-out per call with withTimestamp: false.
  • CHANGED
    Verify CLI. kamy verify <pdf> hashes a PDF locally and prints the kamy.dev/verify/<sha256> URL. No API call, no upload — useful for pasting into emails or audit reports.
Release

Python SDK, AI assistant, form-fillable PDFs, .docx output

Big release. The Kamy surface area roughly doubled this week — a typed Python SDK on PyPI, an in-product AI assistant (Kamy Brain) that can diagnose render failures and open support tickets, fillable AcroForm widgets on rendered PDFs, a Word (.docx) output endpoint, and several dashboard insights pages. The marketing positioning also pivoted to lead with the AI-agent / MCP story.

  • NEW
    Python SDK on PyPI. pip install kamy-sdk → from kamy import Kamy. Sync (Kamy) and async (AsyncKamy) clients, both backed by httpx. Pydantic models mirror the wire shapes; typed exceptions (RateLimitError, ValidationError, QuotaExceededError, etc.) parse from the API's error envelope so callers can except RateLimitError and read e.retry_after_seconds. See pypi.org/project/kamy-sdk.
  • NEW
    Kamy Brain — an AI assistant inside the dashboard at /dashboard/brain. Answers Kamy questions, diagnoses failed renders by reading your account history, looks up template schemas, explains error codes, and opens support tickets on your behalf. Powered by Claude with six tools — every doc and template schema is in its context.
  • NEW
    options.formFields on /v1/render — adds fillable AcroForm widgets (text, textarea, checkbox, radio, dropdown, signature) to the rendered PDF. Position by page + bottom-left point coordinates (72 dpi); up to 100 fields per render. Per-field validation errors surface as FORM_FIELD_INVALID warnings.
  • NEW
    POST /v1/render-docx — Word (.docx) output for invoice / receipt / quote / contract / agreement templates. Same auth + quota + storage envelope as /v1/render. Re-renders from the same data payload, not HTML→DOCX conversion (which produces structurally fragile Word documents).
  • NEW
    Dashboard insights at /dashboard/metrics — top-10 templates table, p50 / p95 / p99 render latency over the last 30 days, and 6-month usage trend. Webhook deliveries page now has a per-row Redeliver button. Template version history adds a side-by-side diff view at /dashboard/templates/[slug]/diff.
  • NEW
    New marketing surfaces: /docs/mcp (full MCP integration guide for Claude Desktop / Code, Cursor, ChatGPT Apps), /trust (security commitments + subprocessor table), and /blog (AI-generated developer content, daily cron).
  • CHANGED
    Landing page repositioned around the AI-agent / MCP story. New hero copy ("The PDF API for AI Agents"), one-line claude mcp add install command, and a persona-targeted "Built for AI agents" section.
  • FIXED
    Stale subdomain references retired. Several internal docs and SDK defaults still pointed at api.kamy.dev and docs.kamy.dev — both nonexistent. The TS SDK had quietly migrated to kamy.dev in 0.5.x; the Python SDK 0.1.0 / 0.1.1 defaulted to the dead host and would fail on the first render. Fixed in kamy-sdk 0.1.2; static surfaces (llms.txt, agent.json, integration code generator) all updated.
  • FIXED
    PDF/A processor tightened. Trailer /ID entry, xmpMM:DocumentID/ InstanceID, and xmp:CreateDate / ModifyDate / MetadataDate are now emitted on every PDF/A render. Closes the three most common veraPDF rule failures for pdf-lib output.
Release

Per-render `name` field for dashboard tracking

Renders can now carry a caller-supplied label, persisted on the row and surfaced in the dashboard renders table and on every /v1/renders response. Solves the long-standing dead-end of inline-HTML and url-mode renders showing a bare em-dash in the dashboard, and lets customers tag template renders for their own internal tracking — useful for batches where the same template runs many times.

  • NEW
    POST /v1/render now accepts an optional top-level name string (1–120 chars, trimmed). Works in all three modes — template, html, and url. The value is echoed back on the response and persisted to the renders row, so the dashboard renders table shows the label as the primary identifier.
  • NEW
    POST /v1/render/async, POST /v1/batch (per item), and POST /v1/merge all accept the same name field. Lets you label individual queued jobs, each item in a batch, and the merged-output PDF independently.
  • CHANGED
    GET /v1/renders and GET /v1/renders/{id} now include name on every item — null when the original request didn't set the field, including for renders that pre-date this release.
  • CHANGED
    Dashboard renders table renames the first column to Name, prefers the caller-supplied label when present, falls back to the template name, then to a friendly Untitled render placeholder so empty rows no longer read as a dead em-dash. The render detail page gains a Name row when set.
  • FIXED
    Inline-HTML (html) and URL-mode (url) renders, plus merged outputs, no longer show — in the Template column with no other identifier — they pick up the newname field when set, or the friendly placeholder when not.
Release

Phase-3 template redesigns + opt-in page numbers

The four remaining system templates (agreement, certificate, shipping-label, report) all got the Phase-3 visual + data refresh, joining invoice / quote / contract that landed earlier the same day. Multi-page documents now declare a default page-number footer at the registry level instead of forcing every API caller to pass the option.

  • NEW
    agreement redesigned — Source Serif Pro body, parties cards, optional Roman-numeral recitals, numbered clauses with optional N.M sub-clauses, two-column signature blocks, optional witnesses block. New optional fields: agreementNumber, status, recitals[], closingClause, witnesses[], governingLaw, party.email, party.phone, party.description, section.clauses[], signature.imageUrl, signature.title.
  • NEW
    certificate redesigned — Cormorant Garamond Italic on cream parchment, double-border with corner fleurons, gold-underlined recipient, wax-seal emblem flanked by signatories. New optional fields: logoUrl, certificateId, sealText, presentedFor, secondaryLine, signatory.imageUrl.
  • NEW
    shipping-label redesigned — carrier-grade 4×6 in IBM Plex Mono, diagonal- stripe carrier bar, pill service-class badge, heavier Ship-To card, three-column spec strip, CSS-rendered code-128-style barcode. New optional fields: referenceNumber, orderNumber, packageCount, sortCode, originCountry, from.company, from.phone, from.street2, to.company, to.phone, to.street2.
  • NEW
    report redesigned — magazine-style cover with optional cover image and prepared-by/for meta, executive-summary callout, top-level metric grid with auto-direction deltas (▲ ▼ —), numbered sections with optional bulleted items, inline metric strips, pull-quotes, callouts, and per-section pageBreakBefore. New optional fields: coverImage, preparedBy, preparedFor, confidential, executiveSummary, accentColor, section.items[], section.quote, section.metrics[], section.callout, section.pageBreakBefore.
  • NEW
    New registry field SystemTemplate.defaultRenderOptions (currently honors { pageNumbers }). Caller-supplied options always win — the default is only consulted when the field is undefined, so passing { pageNumbers: false } is a real opt-out. Wired in both /v1/render and /v1/batch. Defaults set on: invoice, quote, contract, agreement, report, uae-tax-invoice, ksa-zatca-invoice.
  • NEW
    Two new Handlebars helpers for custom templates: startsWith(haystack, needle) and len(value) (array / string / object key-count, 0 on null).
  • FIXED
    emailSafe helper now also entity-encodes @ so rendered email addresses survive Cloudflare's email-obfuscation pass without being rewritten to __cf_email__ placeholders.
  • CHANGED
    Pricing copy genericised — the "Country-compliant tax templates" capability no longer inlines region names on the pricing card. The actual tax templates still ship under their region-specific names in /templates.
Release

Earlier the same day — Phase-3 (first batch) + thumbnails

  • NEW
    invoice redesigned — fintech-style with status pill, partial-payment math, payment instructions, QR slot, signature block, multi-page-safe line items.
  • NEW
    quote redesigned — serif-headline sales proposal with live validity countdown banner, project cover-letter block, structured numbered terms, deposit / payment terms card, Accept / Decline CTA. Field aliases added so SDK and legacy callers both validate.
  • NEW
    receipt redesigned — 80mm thermal printer aesthetic in Roboto Mono with optional QR card, returns policy, tip / tendered / change lines, and loyalty points. Accepts both canonical (merchant + lineItems) and legacy (storeName + items) shapes.
  • NEW
    contract redesigned — classic legal layout with three-way data alignment so SDK / dashboard / API renders all match. Adds roman and isArray Handlebars helpers.
  • FIXED
    Landing-page template thumbnails now scale to width and top-anchor for multi-page documents (no more squashed previews). Inline styles + Google Fonts allowed in the /api/templates/preview CSP so previews actually render.
  • FIXED
    /v1/templates responses now overlay the system-template registry metadata (tier, industry, country, language, compliance) so the dashboard and SDKs see the same shape as the marketing gallery.
Release

Country-compliant tax invoices + security audit

First two country-specific tax templates land for Pro / Team. Separately, a focused security audit closed five critical findings and hardened the SSRF guard against three new bypasses.

  • NEW
    uae-tax-invoice — Federal Tax Authority (FTA) compliant bilingual (ar+en) tax invoice, VAT 5%, Cabinet Decision 52/2017. Pro / Team only.
  • NEW
    ksa-zatca-invoice — ZATCA Phase 1 compliant bilingual (ar+en) tax invoice, VAT 15%, with a QR-code slot for the TLV-encoded payload. Pro / Team only.
  • NEW
    Free tier now includes 1 watermark-free render per month for evaluation. See /pricing.
  • NEW
    /cjk-pdf-api and /indic-pdf-api landing pages — verified font coverage across 12 scripts (Chinese / Japanese / Korean / Devanagari / Bengali / Tamil / Telugu / Kannada / Malayalam / Gurmukhi / Gujarati / Oriya).
  • NEW
    Shared SiteHeader / SiteFooter across every marketing page for consistent navigation.
  • FIXED
    SSRF guard now blocks three additional bypass classes: trailing-dot hostname normalisation, hex-encoded IPv4-mapped IPv6, and CGNAT / benchmark / reserved IPv4 ranges.
  • FIXED
    DELETE /v1/templates/{id} now returns 409 TEMPLATE_IN_USE instead of 500 when the template is referenced by a render or a webhook.
  • FIXED
    /v1/batch and /v1/merge now await their renders inserts so insert failures actually surface to the caller (rather than logging silently and returning 200).
  • FIXED
    API-key revocation from the dashboard now takes effect on the next request (cache invalidation was lagging by up to a minute).
  • FIXED
    OpenAPI spec — production server URL corrected; RenderOptions fields fully documented. /api/openapi.json.

Stay up to date

Want a heads-up on big changes?

Breaking changes are announced 30 days before they ship and are always opt-in via a new endpoint or new field — never silently in place. New templates, new optional fields, and new helpers are additive and safe to ignore. Email us to be added to release announcements if you want them in your inbox.

Changelog — Kamy — Kamy