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": '$' & $formatNumber($.consultant.rate, '#,##0.00') & '/hr'
}
roles:
- { key: consultant_signer }
- { key: company_rep }
apiVersion: signstack/v1beta2
kind: Asset
metadata:
key: consulting_agreement_html
version: 1.0.0
spec:
type: html
styles:
- agreement_styles@1.0.0
data:
schema: agreement_context@1.0.0
content: |
<h1>Consulting Services Agreement</h1>
<p>Between <strong>{{company_name}}</strong> and
<strong>{{consultant_name}}</strong>.</p>
<p>Rate: {{rate}}</p>
<div data-field="company_signature" data-type="signature" data-role="company_rep"></div>
<div data-field="consultant_signature" data-type="signature" data-role="consultant_signer"></div>
apiVersion: signstack/v1beta2
kind: JsonataFunction
metadata:
key: format_currency
version: 1.0.0
spec:
params:
- { name: amount, type: number }
returnType:
type: string
body: "'$' & $formatNumber(amount, '#,##0.00')"
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: consultant
version: 1.0.0
spec:
jsonSchemaDraft: 2020-12
schemaDefinition:
type: object
properties:
firstName: { type: string }
lastName: { type: string }
email: { type: string, format: email }
rate: { type: number }
required: [firstName, lastName, email]
Expressive. Compose these five primitives to model essentially any agreement workflow: single-signer NDAs, multi-party contracts with parallel signing, approval chains with conditional routing, quorum-based board resolutions, workflows that update entity data mid-flight, and documents that appear only when business rules are satisfied. Render from HTML (dynamic, data-driven) or existing PDFs (fixed-layout forms).
Dependable. Every entity is schema-validated before a document is rendered. Every published primitive is immutable — a workflow running against blueprint@1.0.0 today will behave identically a year from now. Every step, signature, and entity change is captured in an audit trail.
Reusable. The same employee schema powers your offer letter, NDA, and benefits enrollment. That NDA template in turn shows up in your hiring, vendor, and contractor blueprints. Your legal footer asset lives in every document. A format_currency function works identically in every expression. Design each primitive once, reuse it everywhere.
Easy to compose. AI is built into the Studio and CLI (and available as a SignStack Skill for your own AI coding tools) — describe the agreement and it composes the right primitives for you. Iterate with prompts; directly edit YAML only when you want to.
Three Interfaces, Same Primitives
Every interface produces the same underlying primitives. A blueprint built in Studio, written in the CLI, or created via the API is the same resource — stored the same way, runs the same way.
| Interface | What It Does |
|---|---|
| Studio | Visual workspace for describing, previewing, publishing, and running workflows. AI built in. |
| CLI | Version-controlled primitives in git. Generate, preview, push, and run from your terminal. AI built in. |
| REST API | Create and manage primitives, trigger workflows, and respond to events — programmatically from your application. |
White-Label & Embeddable
SignStack is built to disappear inside your product. You keep the brand; SignStack provides the infrastructure.
- Your brand, end-to-end. Every email, signing page, and completed document carries your sender identity, logo, company info, and contact details. Embedded components inherit your app's styling automatically, so in-product surfaces match your design system without extra work.
- Built for multi-tenancy. A namespace is an isolated environment inside your SignStack organization — primitives, workflows, branding, and API keys are scoped inside and never cross over. Give every tenant their own namespace and their own identity with zero risk of data leaking between them. Read more →
- Embed anything from Studio. Resource editing, workflow editing, workflow monitoring, and e-signing — all available as framework-agnostic web components you drop into your own app. Most render inline; e-signing uses a sandboxed iframe for security.
Your Agreements, In Git
SignStack's own versioning — immutable published versions like blueprint@1.0.0 — gives you stable, auditable runtime behavior. On top of that, the primitives are plain YAML files that live in your repo alongside your application code, so you get your entire developer toolchain for free:
- Git history for every change to every contract definition
- Pull request reviews before deploying agreement changes
- CI/CD pipelines that validate and push primitives automatically
- Branching to test contract changes in isolation before merging
my-project/
├── blueprint.yaml # Blueprint
├── templates.yaml # Templates
├── assets.yaml # Assets
├── functions.yaml # Functions
├── schemas.yaml # Schemas
├── definitions/ # JSON Schemas
├── html/ # HTML / Handlebars
└── css/
Who Uses SignStack
- SaaS teams embedding white-label agreement infrastructure into their product
- Developers who want infrastructure-as-code for agreements — YAML definitions, Git version control, CLI-driven deployments
- Teams needing data-driven automation — conditional logic, parallel approvals, dynamic documents that react to business data
- AI agents and workflow platforms that need a structured, auditable way to incorporate signatures and approvals into automated processes
Ready to Start?
Head to the Quick Start to build your first agreement workflow — in Studio, in your terminal, or straight from the API.
