Documentation
Everything you need to integrate ETCH into your applications.
Quick Start
ETCH processes document templates by merging them with JSON data. You design your template in Word, Excel, or PowerPoint using a simple tag syntax, send it to the ETCH API with your data, and receive a finished document back.
How It Works
Create a DOCX, XLSX, or PPTX file with ETCH tags like {{name}}.
Structure your data as JSON with keys matching your template tags.
Send your template and data to the ETCH processing endpoint.
Receive the processed document with all tags replaced by your data.
API Example
curl -X POST https://api.get-etch.app/api/v1/process \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "template=@invoice.docx" \
-F 'data={"name":"Jane","total":99.99}' \
-o "invoice-output.docx"
Client Libraries
Official client libraries are available for the following languages. Click the tabs above for language-specific documentation.
Variables
Insert dynamic values using double curly braces. Supports nested objects and array access.
{{name}} → Simple variable
{{user.email}} → Nested object access
{{items[0].name}} → Array index access
{{company.address.city}} → Deep nesting
Conditionals
Show or hide sections based on data values.
{{#if isPaid}}
Payment received. Thank you!
{{else if isPending}}
Payment is being processed.
{{else}}
Payment required.
{{/if}}
{{#unless isArchived}}
This record is active.
{{/unless}}
Loops
Iterate over arrays to generate repeated content. Access loop metadata with @index, @first, and @last.
{{#each items}}
{{@index}}. {{name}} - {{price | currency}}
{{#if @first}}(First item){{/if}}
{{#if @last}}(Last item){{/if}}
{{/each}}
GroupBy
Group array items by a property to create categorised sections.
{{#groupBy items "category"}}
Category: {{key}}
{{#each items}}
- {{name}}
{{/each}}
{{/groupBy}}
Switch / Case
{{#switch status}}
{{#case "active"}}Account is active{{/case}}
{{#case "suspended"}}Account is suspended{{/case}}
{{#default}}Unknown status{{/default}}
{{/switch}}
Math Expressions
Perform calculations directly in your templates.
Subtotal: {{price * quantity}}
Tax: {{price * quantity * 0.2}}
Total: {{price * quantity * 1.2 | currency}}
Formatters
Transform values using the pipe | operator. ETCH includes 21 built-in formatters.
| Formatter | Example | Output |
|---|---|---|
| currency | {{price | currency}} | $1,234.56 |
| number | {{count | number}} | 1,234 |
| date | {{created | date}} | Jan 15, 2026 |
| uppercase | {{name | uppercase}} | JANE DOE |
| lowercase | {{status | lowercase}} | active |
| titlecase | {{city | titlecase}} | New York |
| percentage | {{rate | percentage}} | 85.5% |
| truncate:N | {{desc | truncate:50}} | First 50 chars... |
Helpers
Built-in helper functions for common operations.
Total items: {{length items}}
Tags: {{join tags ", "}}
Sorted: {{#each (sort items "name")}} ... {{/each}}
Sum: {{sum items "amount"}}
Average: {{avg items "score"}}
Comments
{{!-- This comment will not appear in output --}}
Special Tags
{{newSlide}} → Insert a new slide (PPTX only)
Format Support
| Feature | DOCX | XLSX | PPTX | MD |
|---|---|---|---|---|
| Variables | ✓ | ✓ | ✓ | ✓ |
| Conditionals | ✓ | ✓ | ✓ | ✓ |
| Loops | ✓ | ✓ | ✓ | ✓ |
| Images | ✓ | ✓ | ✓ | ✓ |
| Tables | ✓ | ✓ | ✓ | ✓ |
| Math | ✓ | ✓ | ✓ | ✓ |
| QR / Barcodes | ✓ | ✓ | ✓ | ✓ |
| New Slide | — | — | ✓ | — |
Python Client
The official Python client supports both synchronous and asynchronous usage.
Installation
pip install etch-client
Quick Start
from etch import EtchClient
client = EtchClient(
api_key="your-api-key",
base_url="https://api.get-etch.app"
)
# Process a template file
result = client.process(
template_path="invoice.docx",
data={"name": "Jane", "total": 99.99}
)
# Save the output
with open("output.docx", "wb") as f:
f.write(result)
Async Usage
from etch import AsyncEtchClient
async def main():
client = AsyncEtchClient(api_key="your-api-key")
result = await client.process(
template_path="report.docx",
data={"title": "Monthly Report", "items": [...]}
)
with open("report-output.docx", "wb") as f:
f.write(result)
Template Management
# List templates
templates = client.templates.list()
# Upload a template
client.templates.upload("invoices/standard.docx", open("invoice.docx", "rb"))
# Process using a stored template
result = client.process(
template_id="invoices/standard.docx",
data={"name": "Jane"}
)
# Delete a template
client.templates.delete("invoices/standard.docx")
JavaScript / TypeScript Client
Works in Node.js and browser environments with full TypeScript support.
Installation
npm install etch-client
Quick Start
import { EtchClient } from 'etch-client';
import fs from 'fs';
const client = new EtchClient({
apiKey: 'your-api-key',
baseUrl: 'https://api.get-etch.app'
});
// Process a template
const result = await client.process({
template: fs.readFileSync('invoice.docx'),
data: { name: 'Jane', total: 99.99 }
});
fs.writeFileSync('output.docx', result);
TypeScript
import { EtchClient, ProcessOptions } from 'etch-client';
interface InvoiceData {
name: string;
total: number;
items: Array<{ name: string; qty: number; price: number }>;
}
const client = new EtchClient({ apiKey: process.env.ETCH_API_KEY! });
const data: InvoiceData = {
name: 'Jane',
total: 99.99,
items: [
{ name: 'Widget', qty: 5, price: 19.99 }
]
};
const result: Buffer = await client.process({ template, data });
Go Client
Idiomatic Go client with context support and typed errors.
Installation
go get github.com/ae-dev/etch-go-client
Quick Start
package main
import (
"context"
"os"
etch "github.com/ae-dev/etch-go-client"
)
func main() {
client := etch.NewClient(
etch.WithAPIKey("your-api-key"),
etch.WithBaseURL("https://api.get-etch.app"),
)
// Process a template file
result, err := client.ProcessFile(context.Background(), etch.ProcessRequest{
TemplatePath: "invoice.docx",
Data: map[string]interface{}{
"name": "Jane",
"total": 99.99,
},
})
if err != nil {
panic(err)
}
os.WriteFile("output.docx", result, 0644)
}
Error Handling
result, err := client.ProcessFile(ctx, req)
if err != nil {
var apiErr *etch.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API error %d: %s\n", apiErr.StatusCode, apiErr.Message)
}
return err
}
Concurrent Processing
g, ctx := errgroup.WithContext(context.Background())
for _, invoice := range invoices {
inv := invoice
g.Go(func() error {
result, err := client.ProcessFile(ctx, etch.ProcessRequest{
TemplatePath: "invoice.docx",
Data: inv,
})
if err != nil {
return err
}
return os.WriteFile(inv.Filename, result, 0644)
})
}
if err := g.Wait(); err != nil {
log.Fatal(err)
}
Java / Kotlin Client
Compatible with Java 11+ and Kotlin. Available via Maven Central.
Maven
<dependency>
<groupId>app.get-etch</groupId>
<artifactId>etch-client</artifactId>
<version>1.0.0</version>
</dependency>
Gradle (Kotlin DSL)
implementation("app.get-etch:etch-client:1.0.0")
Java Example
import app.getetch.EtchClient;
import java.nio.file.*;
import java.util.Map;
public class Example {
public static void main(String[] args) throws Exception {
var client = EtchClient.builder()
.apiKey("your-api-key")
.baseUrl("https://api.get-etch.app")
.build();
byte[] result = client.process(
Path.of("invoice.docx"),
Map.of("name", "Jane", "total", 99.99)
);
Files.write(Path.of("output.docx"), result);
}
}
Kotlin Example
import app.getetch.EtchClient
import java.nio.file.Path
fun main() {
val client = EtchClient.builder()
.apiKey("your-api-key")
.build()
val result = client.process(
template = Path.of("invoice.docx"),
data = mapOf("name" to "Jane", "total" to 99.99)
)
Path.of("output.docx").toFile().writeBytes(result)
}
Examples & Recipes
Common patterns and use cases for ETCH templates.
Invoice Generation
A complete invoice template with line items, totals, and conditional payment status.
INVOICE #{{invoice_number}}
Date: {{date | date}}
Bill To: {{customer.name}}
{{#each items}}
| {{name}} | {{quantity}} | {{price | currency}} | {{quantity * price | currency}} |
{{/each}}
Subtotal: {{subtotal | currency}}
Tax ({{tax_rate | percentage}}): {{subtotal * tax_rate | currency}}
Total: {{total | currency}}
{{#if paid}}
PAID - Thank you!
{{else}}
Payment due by {{due_date | date}}
{{/if}}
Report with Grouped Data
Use groupBy to organise data by department, category, or any property.
{{title}} - Generated {{generated_at | date}}
{{#groupBy employees "department"}}
Department: {{key}}
{{#each items}}
{{name}} - {{role}} ({{salary | currency}})
{{/each}}
Department Total: {{sum items "salary" | currency}}
{{/groupBy}}
Grand Total: {{sum employees "salary" | currency}}
Batch Processing
Process multiple documents from a single template using any client library.
import asyncio
from etch import AsyncEtchClient
async def generate_certificates(students):
client = AsyncEtchClient(api_key="your-api-key")
tasks = [
client.process(
template_path="certificate.docx",
data={"name": s["name"], "course": s["course"], "date": s["date"]}
)
for s in students
]
results = await asyncio.gather(*tasks)
for student, result in zip(students, results):
with open(f"cert-{student['name']}.docx", "wb") as f:
f.write(result)
QR Code Generation
Generate QR codes and barcodes directly in your documents.
{
"ticket_id": "TKT-2026-0042",
"qr_code": {
"type": "qr",
"data": "https://get-etch.app/verify/TKT-2026-0042",
"width": 150,
"height": 150
},
"barcode": {
"type": "code128",
"data": "TKT-2026-0042",
"width": 200,
"height": 60
}
}
PDF Output
Generate PDF output from any supported template format.
curl -X POST https://api.get-etch.app/api/v1/process \
-H "Authorization: Bearer $API_KEY" \
-F "template=@report.docx" \
-F "data=@data.json" \
-F "output_format=pdf" \
-o "report.pdf"