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

# Webhook Triggers

> Trigger workflows from external HTTP events

## Overview

Webhook triggers are part of the workflow system. A webhook trigger creates a public URL that starts a workflow run when an external system sends a request.

<Note>
  Current public webhook triggers are generic workflow webhooks. Native GitHub, Stripe, Slack, and Linear trigger setup can be modeled in your workflow, but the public trigger API itself is `cron` or `webhook`.
</Note>

## Create A Webhook Trigger

```typescript theme={null}
const trigger = await rt.workflows.createTrigger('incoming-leads', {
  type: 'webhook',
  name: 'Lead capture',
  enabled: true,
  secret: 'replace-with-a-long-random-secret',
});

console.log(trigger.webhookUrl);
console.log(trigger.secret);
```

```bash cURL theme={null}
curl -X POST https://api.runtools.ai/v1/workflows/incoming-leads/triggers \
  -H "X-API-Key: $RUNTOOLS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "webhook",
    "name": "Lead capture",
    "enabled": true,
    "secret": "replace-with-a-long-random-secret"
  }'
```

The response includes `webhookUrl`. Store the returned secret if you asked RunTools to generate one.

## Invoke A Webhook

```bash theme={null}
curl -X POST https://api.runtools.ai/v1/workflows/webhooks/<webhook-slug> \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: replace-with-a-long-random-secret" \
  -d '{
    "event": "lead.created",
    "email": "person@example.com",
    "company": "Acme"
  }'
```

The payload becomes the workflow run input.

## Manage Webhook Triggers

```typescript theme={null}
const triggers = await rt.workflows.triggers('incoming-leads');

await rt.workflows.updateTrigger('incoming-leads', triggers[0].id, {
  enabled: false,
});

await rt.workflows.deleteTrigger('incoming-leads', triggers[0].id);
```

## View Triggered Runs

```typescript theme={null}
const runs = await rt.workflows.runs('incoming-leads', 25);

for (const run of runs) {
  console.log(run.triggerType, run.status, run.createdAt);
}
```

## Security

Use a long random secret for webhook triggers and rotate it when a provider configuration changes. If a trigger has a secret, requests must include that secret in the expected header.

<Warning>
  Do not put privileged API keys directly in webhook payloads. Store provider credentials in RunTools secrets or OAuth connected apps and let your workflow use those server-side.
</Warning>
