Blueprints

A Blueprint is the declarative definition of an agreement workflow — what data goes in, who signs, which documents they sign, and in what order. Design it once, run it many times with different data as live Workflows.

A Blueprint specifies:

  • Inputs — what data is required (referencing Schemas)
  • Participants — who will sign (with names/emails from expressions)
  • Envelopes — groups of documents sent together (referencing Templates)
  • Orchestration — the order and conditions for signing (sequential, parallel, quorum)

You design a Blueprint once — in Studio, in your repo as YAML, or via the API — and run it many times, each time with different data.

YAML Format

apiVersion: signstack/v1beta2
kind: Blueprint

metadata:
  key: employee_onboarding    # Required, snake_case
  version: 1.0.0              # Required, semver
  name: Employee Onboarding   # Required
  description: New hire offer + NDA + benefits
  labels:
    department: hr

spec:
  inputs: # Data required at runtime
    - key: employee
      schema: employee@1.0.0

  participants: # People who sign
    - key: new_hire
      name:
        expr: '$full_name($.employee)'
      email:
        expr: '$.employee.email'

  envelopes: # Document groups
    - key: offer_envelope
      documents:
        - key: offer_letter
          template: offer_letter@1.0.0

  orchestration: # Signing order
    key: root
    type: group
    execution: sequential
    children:
      - key: new_hire_signs
        type: participant
        participant: new_hire
        action:
          type: sign
          envelope: offer_envelope
          assignments:
            - document: offer_letter
              role: employee

  functions: # Local alias → versioned function reference
    full_name: get_full_name@1.0.0

Spec Fields

Field Required Description
inputs No Data inputs required when running a workflow. Each references a Schema (key@version).
participants No People who perform actions. name and email can be literals or { expr: '...' }.
envelopes Yes Groups of documents. Each envelope has documents referencing Templates.
orchestration No Root step of the orchestration tree. If omitted, the workflow runs as a document generator — no signing or step routing.
functions No Custom function aliases. Keys used as #x3C;alias>() in expressions.

Inputs

inputs:
  - key: employee # Referenced as $.employee in expressions
    name: Employee Information # Optional display name
    schema: employee@1.0.0 # Schema for validation
    required: true # boolean or JSONata expression

Participants

participants:
  - key: new_hire
    name:
      expr: "$.employee.firstName & ' ' & $.employee.lastName"
    email:
      expr: '$.employee.email'
    phone: # Optional
      expr: '$.employee.phone'

Name, email, and phone can be literal strings or JSONata expressions pulling from inputs.

Envelopes & Documents

envelopes:
  - key: offer_envelope
    name: Offer Letter Package
    subject: 'Your Offer Letter' # Email subject line
    documents:
      - key: offer_letter
        name: Offer Letter
        template: offer_letter@1.0.0
        inputMap: # Optional: map template inputs to blueprint data
          contact: '$.employee' # Template expects 'contact', blueprint has 'employee'

      - key: enterprise_addendum
        name: Enterprise Addendum
        template: enterprise_addendum@1.0.0
        includeIf: "$.client.tier = 'Enterprise'" # Optional: include only when expression is true

Input mapping: When blueprint and template input keys differ, use inputMap to bridge them. Matching keys are auto-mapped.

Orchestration Steps

Two step types:

Group — contains child steps:

- key: signing_phase
  type: group
  name: Signing Phase
  execution: sequential # or parallel
  completion: all # all, any, or quorum (set `quorum: N` when using quorum)
  includeIf: '$.position.includesBenefits' # optional: skip phase entirely when false
  children:
    - ...child steps...

Participant — a signing task:

- key: new_hire_signs
  type: participant
  participant: new_hire
  includeIf: '$.position.level > 3' # optional: skip step entirely when false
  action:
    type: sign
    envelope: offer_envelope
    assignments:
      - document: offer_letter
        role: employee

Steps can also run validation and update entity data on completion. See The Workflow Engine.

Execution Modes

Mode Behavior
sequential Children execute one at a time, in order
parallel All children execute concurrently

Completion Rules (parallel groups)

Rule Behavior
all Wait for every child (default)
any Complete as soon as any one child finishes
quorum Complete when N children finish (set quorum: N)

Examples

Simple NDA (Single Participant)

apiVersion: signstack/v1beta2
kind: Blueprint

metadata:
  key: simple_nda_workflow
  version: 1.0.0
  name: Simple NDA Workflow

spec:
  inputs:
    - key: signer_info
      schema: contact@1.0.0

  participants:
    - key: signer
      name:
        expr: '$.signer_info.name'
      email:
        expr: '$.signer_info.email'

  envelopes:
    - key: nda_envelope
      documents:
        - key: nda
          template: simple_nda@1.0.0
          inputMap:
            contact: '$.signer_info'

  orchestration:
    key: signer_signs_nda
    type: participant
    participant: signer
    action:
      type: sign
      envelope: nda_envelope
      assignments:
        - document: nda
          role: signer

Multi-Party Contract (Parallel Signing)

apiVersion: signstack/v1beta2
kind: Blueprint

metadata:
  key: multi_party_contract
  version: 1.0.0
  name: Multi-Party Contract

spec:
  inputs:
    - key: party_a
      schema: company@1.0.0
    - key: party_b
      schema: company@1.0.0
    - key: contract_details
      schema: contract_data@1.0.0

  participants:
    - key: party_a_signer
      name:
        expr: '$.party_a.representative.name'
      email:
        expr: '$.party_a.representative.email'
    - key: party_b_signer
      name:
        expr: '$.party_b.representative.name'
      email:
        expr: '$.party_b.representative.email'
    - key: witness
      name:
        expr: '$.contract_details.witness.name'
      email:
        expr: '$.contract_details.witness.email'

  envelopes:
    - key: contract_envelope
      documents:
        - key: main_contract
          template: business_contract@1.0.0
          inputMap:
            details: '$.contract_details'

  orchestration:
    key: root
    type: group
    execution: sequential
    children:
      # Both parties sign in parallel
      - key: signing_phase
        type: group
        execution: parallel
        children:
          - key: party_a_signs
            type: participant
            participant: party_a_signer
            action:
              type: sign
              envelope: contract_envelope
              assignments:
                - document: main_contract
                  role: party_a
          - key: party_b_signs
            type: participant
            participant: party_b_signer
            action:
              type: sign
              envelope: contract_envelope
              assignments:
                - document: main_contract
                  role: party_b

      # Witness signs after both parties
      - key: witness_signs
        type: participant
        participant: witness
        action:
          type: sign
          envelope: contract_envelope
          assignments:
            - document: main_contract
              role: witness

Board Resolution (Quorum)

apiVersion: signstack/v1beta2
kind: Blueprint

metadata:
  key: board_resolution
  version: 1.0.0
  name: Board Resolution Approval

spec:
  inputs:
    - key: resolution
      schema: resolution@1.0.0
    - key: board_members
      schema: board_members@1.0.0

  participants:
    - key: board_member_1
      name:
        expr: '$.board_members[0].name'
      email:
        expr: '$.board_members[0].email'
    - key: board_member_2
      name:
        expr: '$.board_members[1].name'
      email:
        expr: '$.board_members[1].email'
    - key: board_member_3
      name:
        expr: '$.board_members[2].name'
      email:
        expr: '$.board_members[2].email'

  envelopes:
    - key: resolution_envelope
      documents:
        - key: resolution_doc
          template: board_resolution@1.0.0

  orchestration:
    key: root
    type: group
    execution: sequential
    children:
      - key: board_approval
        type: group
        execution: parallel
        completion: quorum
        quorum: 2
        children:
          - key: member_1_signs
            type: participant
            participant: board_member_1
            action:
              type: sign
              envelope: resolution_envelope
              assignments:
                - document: resolution_doc
                  role: board_member
          - key: member_2_signs
            type: participant
            participant: board_member_2
            action:
              type: sign
              envelope: resolution_envelope
              assignments:
                - document: resolution_doc
                  role: board_member
          - key: member_3_signs
            type: participant
            participant: board_member_3
            action:
              type: sign
              envelope: resolution_envelope
              assignments:
                - document: resolution_doc
                  role: board_member

Versioning

Blueprints use semantic versioning. A blueprint 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 behaving exactly as designed, 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 inputs, changed orchestration)
  • MINOR (1.1.0) — Backwards-compatible additions (new optional input, new step)
  • PATCH (1.0.1) — Bug fixes (expression correction, name change)