Generating Contracts with AI
SignStack primitives are structured YAML — an ideal format for AI generation. Describe a contract in plain English, and AI produces the primitives (schemas, assets, templates, functions if needed, blueprint) as working resources.
Across all three paths below, the AI doesn't just emit YAML and hand you a problem — it validates, previews, and iterates on the output before giving you a final result. You get a working contract, not a draft you have to debug.
Three ways to generate. Pick whichever fits how you work.
In Studio
Open the New Contract flow in Studio and describe what you want:
"A consulting services agreement where the company signs first, then the consultant countersigns. Capture name, email, rate, and start date for the consultant."
Studio generates the primitives as drafts and opens them in the preview, ready to iterate on.
In the CLI
From your terminal, pass the prompt inline:
signstack generate "a consulting agreement where the company signs first,
then the consultant countersigns"
The CLI streams an AI-generated blueprint and writes the YAML files into a new <blueprint-key>@draft/ folder.
Run signstack generate without a prompt to enter the interactive mode: browse the public Library to fork a starter blueprint, or pick the + New option to print setup instructions for letting your own AI assistant drive the generation.
With Your Own AI (SignStack Skill)
If you'd rather let your AI assistant do the generation — whether it lives in your IDE, a desktop app, or the browser — run signstack generate, choose + New, and follow the printed instructions for your tool. The CLI drops a SignStack Skill file (or equivalent) where your assistant will pick it up:
| Tool | How it picks up the skill |
|---|---|
| Claude Code | /signstack-generate <description> |
| Cursor | Reads .cursor/rules/signstack-generate.mdc automatically |
| ChatGPT / OpenAI Codex | Reads AGENTS.md |
| Google Gemini | Reads GEMINI.md |
Then prompt your AI to generate a SignStack contract. It reads the skill for the primitives/format knowledge it needs and produces working YAML in your project folder.
Use this path when you want your existing AI assistant to drive the generation — it already has your codebase context, and the skill gives it SignStack knowledge.
Example Prompts
All three paths accept the same kind of prompt. A few shapes that work well:
Simple contracts:
- "Generate an NDA between two companies with mutual confidentiality obligations"
- "Create a freelance services agreement where the company signs first, then the contractor countersigns"
Multi-document workflows:
- "Generate an employee onboarding package with an offer letter, NDA, and benefits enrollment form. HR signs the offer letter first, then the new hire signs all three documents"
- "Create a SaaS subscription agreement with a master services agreement and an order form. Both the vendor and customer sign the MSA, then the customer signs the order form"
Complex orchestration:
- "Generate a board resolution where 3 board members vote in parallel, and the resolution passes when any 2 approve (quorum)"
- "Create a rental lease where the landlord signs, then tenant and guarantor sign in parallel"
What Gets Generated
For CLI generation, you get a complete project folder with the primitive YAML files and any supporting assets:
agreements/<contract_name>/
├── definitions/ # JSON Schema files for each data entity
│ ├── employee.json
│ └── company.json
├── html/ # HTML/Handlebars templates for each document
│ └── offer_letter.hbs
├── css/ # Stylesheets
│ └── styles.css
├── scenarios/ # Sample entity data for preview and run
│ └── standard.json
├── schema.yaml # Schema primitives
├── asset.yaml # Asset primitives
├── template.yaml # Template primitives
├── function.yaml # Custom Function primitives (if the contract logic needs them)
└── blueprint.yaml # Blueprint primitives
This is the convention used in apps/signstack-cli/agreements/. The CLI discovers every .yaml / .yml file under the project root, so you can also split resources across separate files (one per resource) or group them however suits your repo.
In Studio, the primitives land directly in your namespace as draft resources you can preview and publish.
After Generation
The CLI operates per resource — point it at the blueprint and it walks the whole dependency graph:
# Validate the blueprint and every primitive it depends on
signstack validate <blueprint_key>@1.0.0
# Preview the rendered PDF
signstack preview <blueprint_key>@1.0.0
# Push the blueprint and its dependencies in order
signstack push <blueprint_key>@1.0.0
# Run with test data
signstack run <blueprint_key>@1.0.0 --scenario standard
Updating Existing Contracts
AI isn't just for starting fresh. Point it at an existing contract and ask for a change — "add a manager approval step for deals over $100k", "swap the signer order", "add an NDA envelope" — and AI reads the current primitives, applies the change, and returns the updated YAML.
- In Studio — open the contract and describe the change in the AI chat.
- With your own AI (Skill) — with the skill installed, tell your AI to update the SignStack primitives in your project. It reads the current YAML, applies the change, and writes back the updated files.
Across all three paths, AI validates and previews the updated contract before returning it. You get working output.
Customizing Generated Output (By Hand)
The generated YAML is standard SignStack primitives. Customize it the same way you would hand-written YAML:
- Edit schemas to add or remove entity fields
- Modify HTML templates for layout and content changes
- Adjust how data maps to the document —
data.transformfor HTML templates, per-fieldvalueexpressions for PDF templates - Restructure blueprint orchestration for different signing flows (parallel, conditional, quorum)
- Add custom functions for complex business logic
After making changes, run signstack preview <blueprint_key>@1.0.0 to render the document or signstack run <blueprint_key>@1.0.0 --scenario standard for a full end-to-end check.
Don't Need to Start from Scratch?
For common contract types, fork a starter from the Library instead of describing one from scratch. Try to run a listing as-is, Customize to fork it into your namespace as an editable draft.
