SignStack
Agreement infrastructure for developers. Define your data, compose your contracts, run via API.
The Problem
Traditional e-signature platforms are document-centric. You upload a PDF, manually place fields at pixel coordinates, and write custom backend code to bridge the gap between your application data and the document. Your app already has structured business objects — employees, deals, clients, invoices — but the signing tool doesn't understand them.
Every time the document changes, your field mappings break. Every new contract type means another round of manual setup. Scaling means more glue code, more maintenance, more drift between your data and your documents.
A Different Approach: Data First
SignStack starts with your data, not your documents.
You define your business entities as JSON Schemas — the same data structures you already use in your application. Documents are a rendering concern. SignStack maps your structured data onto documents using JSONata expressions, so fields are always in sync with reality.
Your Data (employee, deal_info, company)
↓ typed by Schemas
Blueprint (orchestrates who signs what) ──→ Template (transforms and renders the document)
↓ runs as
Workflow (live, stateful signing instance — triggered via API)
The same employee schema can power an offer letter, an NDA, and a benefits enrollment form. Change the schema once, all documents adapt. No custom backend code.
Deep dive: The Data-First Principle →
Five Composable Primitives
SignStack gives you five building blocks. They compose together like LEGO to form any agreement workflow.
| Primitive | What It Does |
|---|---|
| Schema | Defines the shape of a business entity (employee, deal_info). Your data contract. |
| Blueprint | Orchestrates the full workflow — who signs what, when, with what data. |
| Template | Connects data to a document. Maps entity fields onto the asset using expressions. The view layer. |
| Asset | Wraps a file — HTML template, PDF, CSS, image. The raw content layer. |
| Function | Reusable business logic (format_currency, calculate_tax). Shared across primitives. |
A Workflow is a live instance of a Blueprint, created when you provide real entity data.
Here's what they actually look like:
apiVersion: signstack/v1beta2
kind: Blueprint
metadata:
key: consulting_agreement
version: 1.0.0
spec:
inputs:
- { key: consultant, schema: consultant@1.0.0 }
- { key: company, schema: company@1.0.0 }
participants:
- key: company_rep
email: { expr: '$.company.representative.email' }
- key: consultant_signer
email: { expr: '$.consultant.email' }
envelopes:
- key: agreement
documents:
- { key: contract, template: consulting_agreement@1.0.0 }
orchestration:
key: root
type: group
execution: sequential
children:
- { key: company_signs, type: participant, participant: company_rep }
- { key: consultant_signs, type: participant, participant: consultant_signer }
apiVersion: signstack/v1beta2
kind: Template
metadata:
key: consulting_agreement
version: 1.0.0
spec:
type: html
content: consulting_agreement_html@1.0.0
inputs:
- { key: consultant, schema: consultant@1.0.0 }
- { key: company, schema: company@1.0.0 }
data:
transform: |
{
"consultant_name": $.consultant.firstName & ' ' & $.consultant.lastName,
"company_name": $.company.name,
"rate": '