> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Triggers

> Every way to start a workflow: manual, schedule, webhook, inbound webhook, route event, and app events (instant provider webhooks and polling).

# Triggers

A workflow's single **trigger** node decides when it runs. Beyond manual and API invocation, KnoxCall supports scheduled, webhook, route-event, and app-based triggers — all backed by durable, exactly-once delivery.

## Trigger Types

| Type                | Fires when…                                          |
| ------------------- | ---------------------------------------------------- |
| **Manual**          | You run it from the UI or the API                    |
| **Schedule**        | A cron expression comes due                          |
| **Webhook**         | An HTTP request hits the workflow's signed URL       |
| **Inbound Webhook** | A shared inbound webhook fans out to this workflow   |
| **Route Event**     | A KnoxCall route processes a request (`proxy_event`) |
| **App Event**       | A connected app sends a provider webhook (instant)   |
| **App Polling**     | Polling a connected app surfaces a new item          |

Triggers are synced from the workflow definition to a trigger registry on **publish**, so changing a trigger only takes effect when you publish.

## Manual & API

A **Manual** trigger runs on demand. From the API, queue a run against the public resource:

```bash theme={"dark"}
curl -X POST https://api.knoxcall.com/v1/workflows/{id}/execute \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"input": {"any": "data"}}'
```

The `input` object is available in the workflow as `{{trigger.data.*}}` (and `{{input.*}}`). See [Using the API](/workflows/api).

## Schedule

Run on a cron schedule:

```yaml theme={"dark"}
Trigger Type: Schedule
Schedule: "0 * * * *"   # every hour, on the hour
```

Scheduling is **exactly-once across the worker fleet** — a due schedule fires a single run even with multiple workers, using row-locked claiming (no leader election, no duplicate runs).

## Webhook

A **Webhook** trigger gets a signed, per-workflow URL on publish:

```text theme={"dark"}
https://api.knoxcall.com/hooks/wf/{token}
```

`POST` your payload to it; the raw body is available in the workflow. The endpoint is rate-limited per token and supports bearer and HMAC signature verification. The payload is delivered as the trigger input.

<Warning>
  The old admin route `POST /admin/webhooks/workflows/{id}/trigger` has been
  removed. Use the workflow's `/hooks/wf/{token}` URL (or the `/v1` execute
  endpoint) instead.
</Warning>

## Inbound Webhook

If you already receive provider webhooks through a shared **inbound webhook**, target a workflow from it. Only verified deliveries fan out, and the match is pinned to the workflow's mode (Live/Test).

## Route Event

Fire when requests pass through your routes:

```yaml theme={"dark"}
Trigger Type: Route Event      # underlying triggerType: proxy_event
Event Types:
  - request.completed
Route Filter: (optional)
Environment Filter: (optional)
```

Valid event types: `request.received`, `request.success`, `request.error`, `request.client_error`, `request.server_error`, `request.timeout`, `request.completed`. You can narrow matches with a route filter, environment filter, and field conditions.

## App Triggers

Connected apps ([Connections](/workflows/connections)) can start workflows two ways.

### Instant (provider webhooks)

For apps that support it (e.g. **GitHub** issue-opened, **Stripe** events), publishing the workflow **subscribes** a provider webhook automatically; disabling or deleting the workflow **unsubscribes** it. Deliveries arrive at `POST /hooks/apps/:token`, are signature-verified over the raw bytes, and are **de-duplicated** so a provider redelivery runs the workflow only once.

```yaml theme={"dark"}
Trigger Type: App Event
Connection: my-github        # a saved GitHub connection
Event: issue_opened
```

### Polling

For apps without per-connection webhooks (e.g. **Slack** messages), KnoxCall polls on a schedule and fires on new items. The first poll **arms the cursor without firing** (so you don't get a backlog flood), and polling errors back off automatically.

```yaml theme={"dark"}
Trigger Type: App Polling
Connection: my-slack
Resource: new_channel_message
```

## Delivery Guarantees

* **Exactly-once** — schedules, polling, and instant webhook redeliveries all de-duplicate; a single logical event produces a single run.
* **Durable** — a queued run survives a worker restart and resumes.
* **Mode-scoped** — triggers only fire workflows in their own Live/Test mode.

## Notifications on Completion

To be notified when a run finishes (rather than starting one), subscribe an outbound webhook to `workflow.execution.completed` / `workflow.execution.failed`. See [Using the API](/workflows/api#webhook-events).

## Next Steps

<CardGroup cols={2}>
  <Card title="Connections" icon="plug" href="/workflows/connections">
    Connect the apps that power app triggers
  </Card>

  <Card title="Using the API" icon="code" href="/workflows/api">
    Execute and manage workflows via /v1
  </Card>
</CardGroup>
