Data References
Data in JigSpec flows through template references — the double-brace syntax. Wherever you need to use a value from the pipeline's input, a previous step's output, or an environment variable, you write a template reference.
Think of it as "fill in the blank" syntax: you write a template with placeholders, and JigSpec fills them in at runtime.
The basics
ImplementedThe simplest reference pulls from the pipeline's input:
pipeline:
input:
name: string
steps:
- name: greet
action: ai
prompt: "Say hello to {{ input.name }}"input.name is a template reference. At runtime, it's replaced with whatever value was passed in for name.
Namespaces
All template references have a namespace — the first part before the dot:
| Namespace | Where it comes from | Example |
|---|---|---|
input | Pipeline input fields | input.url |
secrets | Environment variables declared as secrets | secrets.API_KEY |
env | Any environment variable | env.HOME |
config | Pipeline configuration values | config.model |
| (step name) | A previous step's output | summarize.text |
Step references
The most common reference type: one step uses another step's output.
steps:
- name: summarize
action: ai
prompt: "Summarize: {{ input.article }}"
- name: translate
action: ai
prompt: "Translate this to Spanish: {{ summarize.text }}"summarize.text refers to the text output of the summarize step. The exact output fields depend on the action — see each action's documentation for what fields it produces.
Nested access
You can drill into nested objects with dots:
prompt: "The vendor is {{ parse_invoice.data.vendor }}"
prompt: "First item: {{ extract.data.line_items.0.description }}"Secrets
ImplementedSecrets are sensitive values injected from environment variables at runtime. Declare them in the pipeline:
pipeline:
name: fetch-data
secrets:
- API_KEY
- DATABASE_URL
steps:
- name: fetch
action: code
run: |
const resp = await fetch(url, {
headers: { Authorization: `Bearer ${secrets.API_KEY}` }
})When the pipeline runs, secrets.API_KEY is read from the API_KEY environment variable. The value is never stored in the pipeline file itself.
Keep secrets out of prompts
Use secrets in code steps and input maps, not directly in ai prompts. Language models log prompts, which could expose secret values.
Environment variables
ImplementedAny environment variable can be referenced without declaring it as a secret:
prompt: "The current user's home directory is {{ env.HOME }}"Use env for non-sensitive configuration. Use secrets for credentials.
Config references
ImplementedPipeline config values are accessible under the config namespace:
pipeline:
config:
model: anthropic/claude-sonnet-4-5
output_dir: ./output
steps:
- name: write
action: ai
prompt: "The configured model is {{ config.model }}"Bracket notation
ImplementedKeys that contain dots or special characters need bracket notation:
# Access a key named "file.txt"
prompt: "Contents: {{ step['file.txt'] }}"
# Access a key with a hyphen
prompt: "Value: {{ step['some-key'] }}"Use bracket notation whenever your key contains ., -, or other characters that would be ambiguous in dot notation.
Validation
JigSpec validates template references before running the pipeline. If you reference a step that doesn't exist, or use a namespace that isn't declared, the validator catches it:
ValidationError: Unknown reference 'typo.text' — did you mean 'summarize.text'?Missing secrets produce warnings (not errors) — the pipeline will still run, but the secret will be an empty string if the environment variable isn't set.