Schemas
Schemas are the foundation of SignStack's data-first architecture. They define the structure, validation rules, and types for your business data—ensuring consistency and integrity throughout your workflows.
What is a Schema?
A Schema is a formal definition of an Entity type. Built on the open JSON Schema standard, it describes:
- Fields and types: What properties an entity has (strings, numbers, dates, nested objects)
- Validation rules: Required fields, formats (email, date, currency), min/max values
- Documentation: Descriptions that help both humans and AI understand your data
Think of Schemas as contracts. When you define a ClientInfo schema, you're declaring: "Every client entity must have an email field that's a valid email address."
Creating a Schema
Via the API
curl -X POST https://api.signstack.ai/v1/orgs/{orgId}/schemas \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "client-info",
"displayName": "Client Information",
"description": "Core client data for agreements",
"jsonSchemaDraft": "2020-12",
"schemaDefinition": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Full legal name"
},
"email": {
"type": "string",
"format": "email"
},
"tier": {
"type": "string",
"enum": ["Standard", "Premium", "Enterprise"]
},
"companyName": {
"type": "string"
}
},
"required": ["name", "email"]
},
"status": "active"
}'
Response:
{
"id": "sch_abc123",
"key": "client-info",
"version": "1.0.0",
"alreadyExists": false
}
Key Fields
| Field | Description |
|---|---|
key |
Unique identifier for your schema (kebab-case recommended) |
displayName |
Human-readable name shown in the UI |
jsonSchemaDraft |
JSON Schema version: 2020-12, 2019-09, draft-07, draft-06, or draft-04 |
schemaDefinition |
The JSON Schema definition object |
status |
draft (editing) or active (published and validated) |
JSON Schema Drafts
SignStack supports multiple JSON Schema draft versions:
| 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 validation |
draft-06 |
Added const and contains keywords |
draft-04 |
Maximum compatibility with legacy systems |
Tip: Use
2020-12for new projects unless you need compatibility with external systems using older drafts.
Schema Lifecycle
Schemas follow a versioned lifecycle:
Draft → Active → Deprecated
↓
New Version (Draft)
Status Transitions
- Draft: Schema is being designed. You can freely edit the definition.
- Active: Schema is published and in use. Editing is locked to maintain integrity.
- Deprecated: Schema is no longer recommended but remains available for existing workflows.
Creating a New Version
When you need to modify an active schema:
# Create a new draft version
POST /v1/orgs/{orgId}/schemas/client-info/versions
# Update the draft
PUT /v1/orgs/{orgId}/schemas/client-info/versions/2.0.0
# Publish the new version
PATCH /v1/orgs/{orgId}/schemas/client-info/versions/2.0.0
{
"status": "active",
"versionType": "minor"
}
Entities: Schema Instances
An Entity is an instance of a Schema—the actual data for a specific client, deal, or property.
# Add entities to a workflow
POST /v1/orgs/{orgId}/workflows/wf_xyz/entities
{
"entities": [
{
"schemaKey": "client-info",
"displayName": "Primary Client",
"data": {
"name": "Jane Smith",
"email": "jane@example.com",
"tier": "Premium",
"companyName": "Acme Corp"
}
}
]
}
The entity data is validated against the schema. If email is missing or invalid, the request fails with a validation error.
Entity Slots: Template & Blueprint Requirements
Entity Slots declare what data a Template or Blueprint needs. They reference schemas by key:
{
"entitySlots": [
{
"key": "client_info",
"displayName": "Client Information",
"schemaKey": "client-info",
"isRequired": true
},
{
"key": "deal_info",
"displayName": "Deal Details",
"schemaKey": "deal-info",
"isRequired": true
}
]
}
When a workflow runs, the engine verifies that all required entity slots are filled with valid data.
Using Schema Data in Expressions
Once entities are in the workflow's Entity Context, you can reference them in JSONata expressions:
// In a Template field's valueExpression
entities.client_info.name
// Conditional display based on tier
entities.client_info.tier = "Enterprise"
// Combining data from multiple entities
entities.deal_info.value * (entities.client_info.tier = "Premium" ? 0.9 : 1)
AI-Assisted Schema Generation
SignStack can generate schema definitions from sample JSON data:
POST /v1/orgs/{orgId}/schemas/generate-from-sample
{
"sampleJson": {
"name": "John Doe",
"email": "john@example.com",
"signedDate": "2024-01-15",
"dealValue": 50000
},
"jsonSchemaDraft": "2020-12"
}
This returns a schema definition inferring types, formats, and structure from your sample.
Best Practices
1. Design Schemas for Reuse
Create schemas that represent core business concepts, not document-specific fields:
✓ client-info, deal-info, property-info
✗ contract-page-1-fields, signature-block-data
2. Use Meaningful Keys
Schema keys appear in expressions and code. Keep them readable:
✓ "schemaKey": "client-info"
✗ "schemaKey": "ci_v2_prod"
3. Add Descriptions
Descriptions help your team and enable better AI assistance:
{
"properties": {
"tier": {
"type": "string",
"description": "Client subscription tier affecting discount rates and SLA",
"enum": ["Standard", "Premium", "Enterprise"]
}
}
}
4. Plan for Evolution
Schemas will change. Use semantic versioning and deprecate old versions gracefully rather than deleting them.
Related Concepts
- The Data-First Principle – Why structured data drives SignStack
- Templates – How templates consume entity data via slots
- Scenarios – Testing with sample entity data