Schemas
A Schema defines the structure and validation rules for your business data. Built on the open JSON Schema standard, schemas ensure every piece of data entering a workflow is valid and consistent.
Schemas are the starting point of every SignStack workflow. You define your data first — employee, company, deal_info — and everything else flows from it. Templates render your data into documents. Blueprints orchestrate workflows around it. But it all begins with the schema.
YAML Format
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: employee # Required, snake_case
version: 1.0.0 # Required, semver
name: Employee # Required
description: Employee data for HR documents
labels:
domain: hr
spec:
jsonSchemaDraft: 2020-12 # Required: 2020-12, 2019-09, draft-07, draft-06, draft-04
file: ./definitions/employee.json # Path to JSON Schema (or use `schemaDefinition:` for inline)
Metadata Fields
| Field | Required | Description |
|---|---|---|
key |
Yes | Unique identifier (snake_case). Referenced as key@version by other resources. |
version |
Yes | Semantic version (1.0.0) or draft. |
name |
Yes | Human-readable name (max 200 chars). |
description |
No | Description of the schema's purpose (max 1000 chars). |
labels |
No | Key-value pairs for categorization and filtering. Keys must be snake_case. |
Spec Fields
| Field | Required | Description |
|---|---|---|
jsonSchemaDraft |
Yes | JSON Schema draft version. Use 2020-12 for new schemas. |
file |
One of file / schemaDefinition |
Relative path to a .json file containing the JSON Schema definition. Convention: ./definitions/<name>.json. |
schemaDefinition |
One of file / schemaDefinition |
Inline JSON Schema definition as a YAML object. Useful for small schemas or when you don't want a separate .json file. |
Examples
Minimal Schema (Inline)
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: contact
version: 1.0.0
name: Contact
spec:
jsonSchemaDraft: 2020-12
schemaDefinition:
type: object
properties:
name: { type: string }
email: { type: string, format: email }
required: [name, email]
Full-Featured Schema
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: employee
version: 1.0.0
name: Employee
description: Employee data for HR documents
labels:
domain: hr
spec:
jsonSchemaDraft: 2020-12
file: ./definitions/employee.json
With ./definitions/employee.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" },
"department": { "type": "string" },
"tier": {
"type": "string",
"enum": ["Standard", "Premium", "Enterprise"],
"description": "Subscription tier affecting discount rates"
},
"startDate": { "type": "string", "format": "date" }
},
"required": ["firstName", "lastName", "email"]
}
Multiple Schemas in One File
Use YAML multi-document syntax (---) to define multiple schemas in a single file:
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: employee
version: 1.0.0
name: Employee
spec:
jsonSchemaDraft: 2020-12
file: ./definitions/employee.json
---
apiVersion: signstack/v1beta2
kind: Schema
metadata:
key: company
version: 1.0.0
name: Company
spec:
jsonSchemaDraft: 2020-12
file: ./definitions/company.json
How Schemas Are Used
Schemas are referenced by templates and blueprints as key@version:
# In a template
inputs:
- key: employee
schema: employee@1.0.0
# In a blueprint
inputs:
- key: employee
schema: employee@1.0.0
When a workflow runs, entity data provided for each input is validated against the referenced schema. Invalid data is rejected with a validation error.
In JSONata Expressions
Once entities are in the workflow, you reference them by their input key:
$.employee.firstName # Simple property access
$.employee.tier = "Enterprise" # Conditional check
$.deal.value * 0.05 # Calculations across entities
JSON Schema Drafts
| Draft | Use Case |
|---|---|
2020-12 |
Latest features, recommended for new schemas |
2019-09 |
Vocabulary system, good backwards compatibility |
draft-07 |
Widely supported, includes if/then/else |
draft-06 |
Added const and contains |
draft-04 |
Maximum compatibility with legacy systems |
Versioning
Schemas use semantic versioning. A schema moves from Draft to a concrete published version (1.0.0); to make further changes, you cut a new version (1.1.0, 2.0.0). Published versions are immutable — every workflow running against 1.0.0 keeps validating against the exact shape it was designed for, even after 2.0.0 ships.
Draft → 1.0.0 (published, immutable)
↓ edit + publish
1.1.0 (published, immutable)
↓ edit + publish
2.0.0 (published, immutable)
Pick the version bump based on the change:
- MAJOR (2.0.0) — Breaking changes (removed required fields, type changes)
- MINOR (1.1.0) — Backwards-compatible additions (new optional field)
- PATCH (1.0.1) — Bug fixes (description update, regex correction)
Best Practices
- Design for reuse — Create schemas for core business concepts (
employee,deal_info,property), not document-specific fields. The same schema should power multiple templates. - Use meaningful keys — Schema keys appear in expressions (
$.employee.firstName). Keep them readable:client_infonotci_v2. - Add descriptions — Descriptions help your team and AI tools generate better primitives from your data models.
- Plan for evolution — Use semantic versioning. Published versions are immutable, so existing workflows keep running against the schema they were designed for; cut a new version when you need to change shape.
Related Concepts
- The Data-First Principle — Why structured data drives SignStack
- Templates — How templates consume entity data via inputs
- Scenarios — Testing with sample entity data
