# run

The `run` tag executes another script **asynchronously**. Unlike `function`, `run` does not wait for the target script to finish and does not return a result. The calling script continues immediately after triggering the run.

This is useful for offloading work that doesn't need to happen inline — sending notifications, syncing data, processing queues, and other background tasks.

### Syntax

```liquid
{% run "script_handle", param1:value1, param2:value2 %}
```

* `"script_handle"` — the handle (or ID) of the script to run.
* `param1:value1, param2:value2` — named parameters. Each becomes a variable inside the target script.

### Parameters

Named parameters let you pass values into the target script. Each `key:value` pair becomes a variable accessible in the script's scope.

Values can be variables, string literals, or any Liquid expression:

```liquid
{% assign customer_email = "support@code57.pl" %}

{% run "send_welcome_email", email:customer_email, template:"onboarding" %}
```

Inside `send_welcome_email`, `email` and `template` are available as regular variables.

You can pass as many parameters as needed:

```liquid
{% run "sync_inventory", product_id:product.id, warehouse:"EU", quantity:new_qty %}
```

### No return value

Since `run` executes asynchronously, there is no `as result` clause. The calling script does not wait for the target script to finish and cannot access its result.

```liquid
{% run "process_order", order_id:order.id %}
{% log "Order processing triggered" %}
```

The log line executes immediately — it does not wait for `process_order` to complete.

If you need the result of another script, use `function` instead:

```liquid
{% function "process_order", order_id:order.id as result %}
```

### Delayed execution

Use the `delay` parameter to schedule a script to run after a specified number of seconds:

```liquid
{% run "send_followup_email", email:customer.email, delay:3600 %}
```

This triggers `send_followup_email` after 1 hour (3600 seconds).

The delay value can also be a variable:

```liquid
{% assign wait_time = 300 %}
{% run "retry_sync", product_id:product.id, delay:wait_time %}
```

### Dynamic handle

The script handle can be a variable instead of a string literal. This lets you decide which script to run at runtime:

```liquid
{% assign script_name = "process_returns" %}
{% run script_name, order_id:order.id %}
```

### Example: Trigger background sync for each order item

```liquid
{% for item in order.line_items %}
  {% run "sync_item_inventory", variant_id:item.variant_id, quantity:item.quantity %}
{% endfor %}
{% log "Inventory sync triggered for all items" %}
```

Each `run` call is dispatched asynchronously. The loop completes immediately without waiting for any of the sync scripts to finish.

### Example: Send notification with delay

```liquid
{% run "send_reminder", email:customer.email, order_name:order.name, delay:86400 %}
{% log "Reminder scheduled for 24h from now" %}
```

### Legacy format: JSON payload

The old format using a single JSON payload variable is still supported. All keys from the payload object are spread into the target script's scope.

```liquid
{% json run_input %}
{
  "email": "support@code57.pl",
  "template": "onboarding"
}
{% endjson %}

{% run "send_welcome_email", run_input %}
```

> **Note:** Named parameters and the JSON payload format cannot be mixed in a single call. Use one or the other.

### Limitations

* **No return value** — `run` is fire-and-forget. Use `function` if you need a result.
* **No recursive runs** — a script cannot run itself, directly or through a chain of other scripts.
* **Task variables are not available** inside the target script. Pass any values you need as parameters.
* **Global variables are accessible** inside the target script.
