Skip to content

Triggers

Triggers automatically create and run sandboxes when specific files change in a commit. They enable event-driven data pipelines without polling or manual intervention.

How Triggers Work

  1. You define a trigger with conditions (which files to watch) and a sandbox configuration (what to run)
  2. When anyone commits to the repository, Tilde evaluates all enabled triggers
  3. If any condition matches the changed files, the trigger's sandbox is created and runs automatically
  4. Each trigger run is recorded for audit purposes

Note

Triggers have a depth limit to prevent infinite loops. A trigger can fire on any commit (including sandbox commits), but the resulting sandbox's commit will not fire further triggers.

Use Cases

  • Data validation — run schema checks whenever new CSV or Parquet files are added
  • Transformation pipelines — automatically convert raw data when it lands in a staging prefix
  • Model retraining — kick off training when the training dataset changes
  • Notifications — send alerts when specific configuration files are modified
  • Documentation — regenerate docs or summaries when source data is updated

Creating a Trigger

import tilde

repo = tilde.repository("my-team/my-data")
trigger = repo.sandbox_triggers.create(
    name="Validate CSV uploads",
    description="Run schema validation on new CSV files in the datasets/ prefix",
    conditions=[
        {"type": "prefix", "prefix": "datasets/"},
    ],
    sandbox_config={
        "image": "python:3.11",
        "command": ["python", "-m", "validate"],
        "mountpoint": "/data",
        "timeout_seconds": 300,
        "env_vars": {"STRICT_MODE": "1"},
    },
)
print(trigger.id)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  -X POST https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Validate CSV uploads",
    "description": "Run schema validation on new CSV files in the datasets/ prefix",
    "conditions": [
      {
        "type": "prefix",
        "prefix": "datasets/"
      }
    ],
    "sandbox_config": {
      "image": "python:3.11",
      "command": ["python", "-m", "validate"],
      "mountpoint": "/data",
      "timeout_seconds": 300,
      "env_vars": {
        "STRICT_MODE": "1"
      }
    }
  }'

Conditions

Each trigger has one or more conditions that determine when it fires. Conditions are evaluated with OR logic — the trigger fires if any condition matches.

Prefix Match

Fires when any changed file starts with the given prefix:

{ "type": "prefix", "prefix": "datasets/" }

This matches datasets/train.csv, datasets/test/labels.json, and any other path under datasets/.

Exact Path Match

Fires when a specific file is changed, optionally filtered by the type of change:

{ "type": "path_exact", "path": "config.yaml", "diff_type": "changed" }

The diff_type field controls which kinds of changes trigger a match:

diff_type Fires when the file is...
any (default) Added, removed, or modified
added Newly created
removed Deleted
changed Modified (existed before and after)

Combining Conditions

You can combine multiple conditions. The trigger fires if any of them match:

{
  "conditions": [
    { "type": "prefix", "prefix": "datasets/" },
    { "type": "path_exact", "path": "config.yaml", "diff_type": "changed" }
  ]
}

This trigger fires when files under datasets/ change or when config.yaml is modified.

Injected Environment Variables

When a trigger fires, the sandbox receives these additional environment variables:

Variable Description
TILDE_TRIGGER_COMMIT_ID The commit ID that fired the trigger
TILDE_TRIGGER_NAME Name of the trigger
TILDE_TRIGGER_MATCHED_PATHS JSON array of matched paths. For prefix conditions, contains the prefix itself (e.g. ["datasets/"]). For exact path conditions, contains the matched file path.

Your code can use these to determine what changed and respond accordingly.

Managing Triggers

List Triggers

for trigger in repo.sandbox_triggers.list():
    print(trigger.name, trigger.enabled)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers

Update a Trigger

trigger.update(
    name="Validate CSV uploads",
    conditions=[{"type": "prefix", "prefix": "datasets/v2/"}],
    sandbox_config={
        "image": "python:3.11",
        "command": ["python", "-m", "validate", "--strict"],
    },
)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  -X PUT https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers/TRIGGER_ID \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Validate CSV uploads",
    "conditions": [
      { "type": "prefix", "prefix": "datasets/v2/" }
    ],
    "sandbox_config": {
      "image": "python:3.11",
      "command": ["python", "-m", "validate", "--strict"]
    }
  }'

Enable or Disable a Trigger

trigger.toggle(enabled=False)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  -X PATCH https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers/TRIGGER_ID \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Delete a Trigger

trigger.delete()
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  -X DELETE https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers/TRIGGER_ID

Viewing Trigger Runs

Each time a trigger is evaluated on a commit, a trigger run is recorded:

for run in trigger.runs.list():
    print(run.status, run.sandbox_id, run.matched_paths)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sandbox-triggers/TRIGGER_ID/runs

Response:

{
  "results": [
    {
      "id": "run-uuid",
      "trigger_id": "trigger-uuid",
      "commit_id": "abc123def456",
      "status": "created",
      "sandbox_id": "sandbox-uuid",
      "matched_paths": ["datasets/"],
      "created_at": "2026-03-11T10:30:00Z"
    }
  ],
  "pagination": { "has_more": false, "next_offset": "", "max_per_page": 1000 }
}

Run statuses:

Status Meaning
created Sandbox was created and is running (or completed)
skipped Trigger matched but sandbox was not created (e.g. the trigger creator is no longer an org member)
failed Trigger matched but sandbox creation failed