Finance template
Receipt
Thermal-printer (80mm) receipt in Roboto Mono with optional QR card, returns policy, tip / tendered / change lines, loyalty points, and dual-shape data input (canonical merchant+lineItems or legacy storeName+items).
Quick start
Reference the template by its slug and pass your data. The same call works from any language; pick whichever fits your stack. Replace $KAMY_API_KEY with a key from the dashboard.
curl https://kamy.dev/api/v1/render \
-H "Authorization: Bearer $KAMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateSlug": "receipt",
"data": {
"receiptNumber": "R-48291",
"issueDate": "2026-04-20T08:42:00-07:00",
"transactionTime": "08:42 AM",
"cashierName": "Maya R.",
"registerId": "POS-03",
"transactionId": "TXN-9F3A2C",
"merchant": {
"name": "Blue Bottle Coffee",
"address": [
"300 Webster St",
"Oakland, CA 94607"
],
"phone": "+1 (510) 555-0173",
"taxId": "EIN 27-1234567"
},
"currency": "USD",
"locale": "en-US",
"lineItems": [
{
"sku": "BEV-001",
"description": "Cappuccino",
"subDescription": "Oat milk · large",
"quantity": 2,
"unitPrice": 5.5,
"amount": 11
},
{
// …
}
}'import { Kamy } from "@kamydev/sdk";
const kamy = new Kamy({ apiKey: process.env.KAMY_API_KEY! });
const { url } = await kamy.render({
templateSlug: "receipt",
data: {
"receiptNumber": "R-48291",
"issueDate": "2026-04-20T08:42:00-07:00",
"transactionTime": "08:42 AM",
"cashierName": "Maya R.",
"registerId": "POS-03",
"transactionId": "TXN-9F3A2C",
"merchant": {
"name": "Blue Bottle Coffee",
"address": [
"300 Webster St",
"Oakland, CA 94607"
],
"phone": "+1 (510) 555-0173",
"taxId": "EIN 27-1234567"
},
"currency": "USD",
"locale": "en-US",
"lineItems": [
{
"sku": "BEV-001",
"description": "Cappuccino",
"subDescription": "Oat milk · large",
"quantity": 2,
"unitPrice": 5.5,
"amount": 11
},
{
// …
},
});
console.log(url); // signed URL, valid for 1 hourimport os, requests
resp = requests.post(
"https://kamy.dev/api/v1/render",
headers={"Authorization": f"Bearer {os.environ['KAMY_API_KEY']}"},
json={
"templateSlug": "receipt",
"data": {
"receiptNumber": "R-48291",
"issueDate": "2026-04-20T08:42:00-07:00",
"transactionTime": "08:42 AM",
"cashierName": "Maya R.",
"registerId": "POS-03",
"transactionId": "TXN-9F3A2C",
"merchant": {
"name": "Blue Bottle Coffee",
"address": [
"300 Webster St",
"Oakland, CA 94607"
],
"phone": "+1 (510) 555-0173",
"taxId": "EIN 27-1234567"
},
"currency": "USD",
"locale": "en-US",
"lineItems": [
{
"sku": "BEV-001",
"description": "Cappuccino",
"subDescription": "Oat milk · large",
"quantity": 2,
"unitPrice": 5.5,
"amount": 11
},
{
// …
},
},
)
resp.raise_for_status()
print(resp.json()["url"])Sample payload
The full sample data the live preview above renders from. Use it as a starting point for your own integration — every field is optional except those marked required in the schema below.
{
"receiptNumber": "R-48291",
"issueDate": "2026-04-20T08:42:00-07:00",
"transactionTime": "08:42 AM",
"cashierName": "Maya R.",
"registerId": "POS-03",
"transactionId": "TXN-9F3A2C",
"merchant": {
"name": "Blue Bottle Coffee",
"address": [
"300 Webster St",
"Oakland, CA 94607"
],
"phone": "+1 (510) 555-0173",
"taxId": "EIN 27-1234567"
},
"currency": "USD",
"locale": "en-US",
"lineItems": [
{
"sku": "BEV-001",
"description": "Cappuccino",
"subDescription": "Oat milk · large",
"quantity": 2,
"unitPrice": 5.5,
"amount": 11
},
{
"sku": "PSY-014",
"description": "Almond croissant",
"quantity": 1,
"unitPrice": 4.75,
"amount": 4.75
},
{
"sku": "BEV-002",
"description": "Drip coffee",
"subDescription": "Single origin · 12oz",
"quantity": 1,
"unitPrice": 4,
"amount": 4
}
],
"subtotal": 19.75,
"discount": 1,
"tax": 1.78,
"tip": 3,
"total": 23.53,
"paymentMethod": "Visa **** 4242",
"amountTendered": 23.53,
"changeGiven": 0,
"loyaltyPointsEarned": 24,
"qrCodeDataUrl": "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'><rect width='80' height='80' fill='%23fff'/><g fill='%23111'><rect x='4' y='4' width='16' height='16'/><rect x='8' y='8' width='8' height='8' fill='%23fff'/><rect x='10' y='10' width='4' height='4'/><rect x='60' y='4' width='16' height='16'/><rect x='64' y='8' width='8' height='8' fill='%23fff'/><rect x='66' y='10' width='4' height='4'/><rect x='4' y='60' width='16' height='16'/><rect x='8' y='64' width='8' height='8' fill='%23fff'/><rect x='10' y='66' width='4' height='4'/><rect x='26' y='6' width='4' height='4'/><rect x='34' y='6' width='4' height='4'/><rect x='42' y='6' width='4' height='4'/><rect x='50' y='6' width='4' height='4'/><rect x='26' y='14' width='4' height='4'/><rect x='38' y='14' width='4' height='4'/><rect x='46' y='14' width='4' height='4'/><rect x='30' y='22' width='4' height='4'/><rect x='42' y='22' width='4' height='4'/><rect x='50' y='22' width='4' height='4'/><rect x='58' y='22' width='4' height='4'/><rect x='66' y='22' width='4' height='4'/><rect x='6' y='26' width='4' height='4'/><rect x='14' y='26' width='4' height='4'/><rect x='22' y='26' width='4' height='4'/><rect x='34' y='26' width='4' height='4'/><rect x='46' y='26' width='4' height='4'/><rect x='54' y='26' width='4' height='4'/><rect x='70' y='26' width='4' height='4'/><rect x='10' y='30' width='4' height='4'/><rect x='18' y='30' width='4' height='4'/><rect x='26' y='30' width='4' height='4'/><rect x='38' y='30' width='4' height='4'/><rect x='50' y='30' width='4' height='4'/><rect x='62' y='30' width='4' height='4'/><rect x='74' y='30' width='4' height='4'/><rect x='6' y='34' width='4' height='4'/><rect x='22' y='34' width='4' height='4'/><rect x='30' y='34' width='4' height='4'/><rect x='42' y='34' width='4' height='4'/><rect x='54' y='34' width='4' height='4'/><rect x='66' y='34' width='4' height='4'/><rect x='14' y='38' width='4' height='4'/><rect x='26' y='38' width='4' height='4'/><rect x='34' y='38' width='4' height='4'/><rect x='46' y='38' width='4' height='4'/><rect x='58' y='38' width='4' height='4'/><rect x='70' y='38' width='4' height='4'/><rect x='6' y='42' width='4' height='4'/><rect x='18' y='42' width='4' height='4'/><rect x='30' y='42' width='4' height='4'/><rect x='42' y='42' width='4' height='4'/><rect x='50' y='42' width='4' height='4'/><rect x='62' y='42' width='4' height='4'/><rect x='10' y='46' width='4' height='4'/><rect x='22' y='46' width='4' height='4'/><rect x='38' y='46' width='4' height='4'/><rect x='54' y='46' width='4' height='4'/><rect x='66' y='46' width='4' height='4'/><rect x='74' y='46' width='4' height='4'/><rect x='14' y='50' width='4' height='4'/><rect x='26' y='50' width='4' height='4'/><rect x='34' y='50' width='4' height='4'/><rect x='42' y='50' width='4' height='4'/><rect x='58' y='50' width='4' height='4'/><rect x='70' y='50' width='4' height='4'/><rect x='30' y='58' width='4' height='4'/><rect x='38' y='58' width='4' height='4'/><rect x='46' y='58' width='4' height='4'/><rect x='54' y='58' width='4' height='4'/><rect x='62' y='58' width='4' height='4'/><rect x='70' y='58' width='4' height='4'/><rect x='26' y='66' width='4' height='4'/><rect x='34' y='66' width='4' height='4'/><rect x='50' y='66' width='4' height='4'/><rect x='58' y='66' width='4' height='4'/><rect x='66' y='66' width='4' height='4'/><rect x='74' y='66' width='4' height='4'/><rect x='30' y='70' width='4' height='4'/><rect x='42' y='70' width='4' height='4'/><rect x='54' y='70' width='4' height='4'/><rect x='62' y='70' width='4' height='4'/><rect x='70' y='70' width='4' height='4'/></g></svg>",
"returnPolicy": "Returns accepted within 14 days with this receipt. Perishables and opened bean bags are non-returnable.",
"websiteUrl": "bluebottlecoffee.com",
"footerText": "Open daily · 6am – 7pm"
}JSON Schema
The render endpoint validates your payload against this JSON Schema before queuing the render. Validation errors come back with HTTP 400 and a VALIDATION_FAILED code listing every offending path.
{
"type": "object",
"required": [
"receiptNumber",
"total",
"currency"
],
"properties": {
"receiptNumber": {
"type": "string",
"minLength": 1
},
"issueDate": {
"type": "string"
},
"merchant": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"email": {
"type": "string",
"format": "email"
},
"phone": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"type": "string"
}
},
"logoUrl": {
"type": "string",
"format": "uri"
},
"taxId": {
"type": "string"
}
}
},
"customer": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"email": {
"type": "string",
"format": "email"
},
"phone": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"type": "string"
}
},
"logoUrl": {
"type": "string",
"format": "uri"
},
"taxId": {
"type": "string"
}
}
},
"lineItems": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"description",
"quantity",
"unitPrice",
"amount"
],
"properties": {
"description": {
"type": "string",
"minLength": 1
},
"quantity": {
"type": "number",
"minimum": 0
},
"unitPrice": {
"type": "number"
},
"amount": {
"type": "number"
},
"sku": {
"type": "string"
},
"subDescription": {
"type": "string"
}
}
}
},
"subtotal": {
"type": "number"
},
"tax": {
"type": "number"
},
"total": {
"type": "number"
},
"currency": {
"type": "string",
"minLength": 1
},
"paymentMethod": {
"type": "string"
},
"notes": {
"type": "string"
},
"transactionTime": {
"type": "string"
},
"cashierName": {
"type": "string"
},
"registerId": {
"type": "string"
},
"transactionId": {
"type": "string"
},
"discount": {
"type": "number"
},
"tip": {
"type": "number"
},
"amountTendered": {
"type": "number"
},
"changeGiven": {
"type": "number"
},
"loyaltyPointsEarned": {
"type": "number"
},
"qrCodeDataUrl": {
"type": "string"
},
"returnPolicy": {
"type": "string"
},
"websiteUrl": {
"type": "string"
},
"footerText": {
"type": "string"
},
"locale": {
"type": "string"
},
"date": {
"type": "string"
},
"transactionDate": {
"type": "string"
},
"taxAmount": {
"type": "number"
},
"discountAmount": {
"type": "number"
},
"website": {
"type": "string"
},
"storeName": {
"type": "string"
},
"storeAddress": {
"type": "array",
"items": {
"type": "string"
}
},
"storePhone": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"quantity": {
"type": "number"
},
"price": {
"type": "number"
},
"amount": {
"type": "number"
}
}
}
}
}
}