Quickstart
This guide walks you through producing a .sdf file, reading it back, and validating it with the CLI. You will have a working end-to-end flow in under 5 minutes.
Prerequisites
- Node.js 20 LTS or later — for the TypeScript examples
- Python 3.11 or later — for the Python examples
- You only need one of the two. Pick whichever you prefer.
Install
TypeScript / Node.js:
npm install @etapsky/sdf-kitPython:
pip install etapsky-sdfProduce Your First SDF
TypeScript
import { buildSDF } from '@etapsky/sdf-kit/producer';import { writeFile } from 'fs/promises';
const schema = { $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', required: ['document_type', 'invoice_number'], properties: { document_type: { type: 'string' }, invoice_number: { type: 'string' }, total: { type: 'object', properties: { amount: { type: 'string' }, currency: { type: 'string' }, }, }, },};
const data = { document_type: 'invoice', invoice_number: 'INV-2026-001', total: { amount: '1250.00', currency: 'EUR' },};
const buffer = await buildSDF({ data, schema, issuer: 'Acme Supplies GmbH', issuerId: 'DE123456789', documentType: 'invoice', recipient: 'Global Logistics AG', schemaId: 'https://etapsky.github.io/sdf/schemas/invoice/v0.1.json',});
await writeFile('invoice.sdf', buffer);console.log('✓ invoice.sdf created');Run it:
npx tsx produce.tsPython
from sdf import SDFProducer, SDFMeta
schema = { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "required": ["document_type", "invoice_number"], "properties": { "document_type": {"type": "string"}, "invoice_number": {"type": "string"}, },}
data = { "document_type": "invoice", "invoice_number": "INV-2026-001", "total": {"amount": "1250.00", "currency": "EUR"},}
meta = SDFMeta( issuer="Acme Supplies GmbH", issuer_id="DE123456789", document_type="invoice", recipient="Global Logistics AG",)
producer = SDFProducer()with open("invoice.sdf", "wb") as f: f.write(producer.build(data=data, schema=schema, meta=meta))print("✓ invoice.sdf created")Run it:
python produce.pyRead It Back
TypeScript
import { parseSDF } from '@etapsky/sdf-kit/reader';import { readFile } from 'fs/promises';
const buffer = await readFile('invoice.sdf');const { meta, data, schema, pdfBytes } = await parseSDF(buffer);
console.log('document_id:', meta.document_id);console.log('invoice_number:', data.invoice_number);// pdfBytes → serve to PDF viewer for human reviewIf you only need the JSON layers and not the PDF bytes, use extractJSON instead. It skips loading the PDF data and is faster for pure data-processing workloads:
import { extractJSON } from '@etapsky/sdf-kit/reader';import { readFile } from 'fs/promises';
const buffer = await readFile('invoice.sdf');const { meta, data, schema } = await extractJSON(buffer);
console.log('document_id:', meta.document_id);console.log('invoice_number:', data.invoice_number);Python
from sdf import parse_sdf
with open("invoice.sdf", "rb") as f: result = parse_sdf(f.read())
print("document_id:", result.meta["document_id"])print("invoice_number:", result.data["invoice_number"])# result.pdf_bytes → serve to PDF viewer for human reviewValidate with the CLI
Install the CLI (one-time):
npm install -g @etapsky/sdf-cliOr use it without installing:
npx @etapsky/sdf-cli inspect invoice.sdfInspect the file — shows all four layers summarized:
sdf inspect invoice.sdfRun full validation — checks structure, schema conformance, and meta integrity:
sdf validate invoice.sdfA valid file exits with code 0. An invalid file exits with a non-zero code and prints the specific errors. This makes sdf validate safe to use in CI pipelines.
What’s Next?
- Installation — All install methods: npm, Homebrew, binary, PyPI
- Core Concepts — The four layers, producer/consumer roles, design decisions
- sdf-kit Reference — Full API documentation for
buildSDF,parseSDF, signing, and validation