Skip to content

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

Implemented

The simplest reference pulls from the pipeline's input:

yaml
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:

NamespaceWhere it comes fromExample
inputPipeline input fieldsinput.url
secretsEnvironment variables declared as secretssecrets.API_KEY
envAny environment variableenv.HOME
configPipeline configuration valuesconfig.model
(step name)A previous step's outputsummarize.text

Step references

The most common reference type: one step uses another step's output.

yaml
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:

yaml
prompt: "The vendor is {{ parse_invoice.data.vendor }}"
prompt: "First item: {{ extract.data.line_items.0.description }}"

Secrets

Implemented

Secrets are sensitive values injected from environment variables at runtime. Declare them in the pipeline:

yaml
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

Implemented

Any environment variable can be referenced without declaring it as a secret:

yaml
prompt: "The current user's home directory is {{ env.HOME }}"

Use env for non-sensitive configuration. Use secrets for credentials.

Config references

Implemented

Pipeline config values are accessible under the config namespace:

yaml
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

Implemented

Keys that contain dots or special characters need bracket notation:

yaml
# 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.

Released under the Apache 2.0 License.