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

# Incoming Webhooks

> Trigger tool execution from external services

<Info>
  **Enterprise Feature** — Incoming webhooks are available on superglue Enterprise plans. [Contact us](https://cal.com/superglue/superglue-demo) to learn more.
</Info>

Trigger tools from external services like Stripe, GitHub, Shopify, or any system that can send HTTP webhooks. When an external service sends a webhook, superglue executes your tool with the webhook payload as input.

<video autoPlay muted loop playsInline className="w-full rounded-lg">
  <source src="https://mintcdn.com/superglue/u32I4ezswr71mkrq/resources/using-agent-webhooks.mp4?fit=max&auto=format&n=u32I4ezswr71mkrq&q=85&s=a182c46cfbdeabca171b2c43e7e96a92" type="video/mp4" data-path="resources/using-agent-webhooks.mp4" />
</video>

## How it works

When you enable webhooks for a tool, superglue provides a unique webhook URL:

```
POST https://api.superglue.ai/v1/hooks/{toolId}?token={your_api_key}
```

### Using development mode

To execute webhooks against development/sandbox system credentials, add the `mode` parameter:

```
POST https://api.superglue.ai/v1/hooks/{toolId}?token={your_api_key}&mode=dev
```

This is useful for testing webhook integrations with sandbox environments before going live.

<Tip>
  **Example with real values:**

  `https://api.superglue.ai/v1/hooks/`<span style={{color: '#3b82f6', fontWeight: 'bold'}}>handle-stripe-customer</span>`?token=`<span style={{color: '#22c55e', fontWeight: 'bold'}}>a1b2c3d4-e5f6-7890-abcd-ef1234567890</span>

  Replace <span style={{color: '#3b82f6'}}>**{toolId}**</span> with your actual tool ID (e.g., `handle-stripe-customer`) and <span style={{color: '#22c55e'}}>**{your_api_key}**</span> with your API key UUID. **Don't include the curly braces `{}`** — they're just placeholders.
</Tip>

External services send HTTP POST requests to this URL. The request body becomes the tool's input payload, and superglue executes the tool asynchronously.

## Setting up a webhook

<Steps>
  <Step title="Get your webhook URL">
    Your webhook URL follows this pattern:

    ```
    https://api.superglue.ai/v1/hooks/{toolId}?token={your_api_key}
    ```

    Replace `{toolId}` with your tool's ID and `{your_api_key}` with a valid API key. You can create API keys at [https://app.superglue.cloud/api-keys](https://app.superglue.cloud/api-keys).
  </Step>

  <Step title="Configure the external service">
    Add the webhook URL to your external service (Stripe, GitHub, etc.). Most services have a webhooks section in their dashboard.
  </Step>

  <Step title="Design your tool for webhook payloads">
    Your tool receives the raw webhook payload as input. Design your steps to extract the data you need:

    ```typescript theme={null}
    // Example: Stripe webhook payload
    {
      "id": "evt_1234",
      "type": "customer.created",
      "data": {
        "object": {
          "id": "cus_abc123",
          "email": "user@example.com"
        }
      }
    }
    ```

    Use template expressions to access nested fields: `<<(sourceData) => sourceData.data.object.email>>`
  </Step>
</Steps>

## Webhook behavior

* **Asynchronous execution**: Returns `202 Accepted` immediately, executes the tool in the background
* **Run tracking**: Each webhook trigger creates a run record you can view in the dashboard
* **Request source**: Runs triggered via webhook are labeled with source `WEBHOOK` in the runs table

## Example: Stripe webhook integration

Build a tool that handles Stripe events and syncs customer data to your CRM:

```typescript theme={null}
// Tool configuration for handling Stripe customer.created events
{
  id: "handle-stripe-customer",
  steps: [
    {
      id: "addToMailchimp",
      config: {
        systemId: "mailchimp",
        method: "POST",
        url: "https://api.mailchimp.com/3.0/lists/{list_id}/members",
        body: {
          email_address: "<<(sourceData) => sourceData.data.object.email>>",
          status: "subscribed"
        }
      }
    }
  ]
}
```

Webhook URL: `https://api.superglue.ai/v1/hooks/handle-stripe-customer?token={your_api_key}`

## Example: GitHub webhook integration

Trigger a deployment tool when code is pushed to your repository:

```typescript theme={null}
// Tool that deploys when code is pushed to main
{
  id: "deploy-on-push",
  steps: [
    {
      id: "triggerDeploy",
      config: {
        systemId: "vercel",
        method: "POST",
        url: "https://api.vercel.com/v13/deployments",
        body: {
          name: "my-app",
          gitSource: {
            type: "github",
            ref: "<<(sourceData) => sourceData.ref>>",
            repoId: "<<(sourceData) => sourceData.repository.id>>"
          }
        }
      }
    }
  ]
}
```

## Security considerations

<Warning>
  Webhook URLs include your API token. Treat them as secrets.
</Warning>

* **Use HTTPS**: Always use HTTPS webhook URLs
* **Restricted API keys**: Use API keys that only have permission to execute specific tools
* **Validate signatures**: If the source service provides webhook signatures (e.g., Stripe's `stripe-signature` header), validate them in your tool logic
* **Monitor activity**: Regularly review the runs dashboard for unexpected webhook activity
* **Rotate keys**: Periodically rotate API keys used for webhooks

## Filtering webhook events

Many services send multiple event types to the same webhook URL. Filter events in your tool using conditional logic:

```typescript theme={null}
// Only process customer.created events from Stripe
{
  outputTransform: `(sourceData) => {
    if (sourceData.type !== 'customer.created') {
      return { skipped: true, reason: 'Event type not handled' };
    }
    return sourceData.addToMailchimp;
  }`
}
```

## Tool chaining

You can chain tools together so that one tool automatically triggers another when it completes. This is useful for building multi-step workflows where the output of one tool becomes the input of the next.

### How it works

When running a tool via the API, use the special `tool:{toolId}` format for the `webhookUrl` option instead of an HTTP URL:

```bash theme={null}
curl -X POST "https://api.superglue.ai/v1/tools/fetch-orders/run" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "since": "2025-01-01"
    },
    "options": {
      "async": true,
      "webhookUrl": "tool:process-orders"
    }
  }'
```

When `fetch-orders` completes:

1. Its output data becomes the input payload for `process-orders`
2. `process-orders` is triggered automatically
3. The chained run has `requestSource: "tool-chain"`

### Viewing chained runs

You can filter runs by request source to see tool chain executions:

```bash theme={null}
curl "https://api.superglue.ai/v1/runs?requestSources=tool-chain" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Example: ETL pipeline

Build a data pipeline where each stage triggers the next:

1. **extract-data** → fetches raw data from source API
2. **transform-data** → cleans and reshapes the data
3. **load-data** → inserts into destination database

```bash theme={null}
# Start the pipeline - each tool chains to the next
curl -X POST "https://api.superglue.ai/v1/tools/extract-data/run" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": { "table": "customers" },
    "options": {
      "async": true,
      "webhookUrl": "tool:transform-data"
    }
  }'
```

Configure `transform-data` to chain to `load-data` in its tool configuration or pass it at runtime.

<Tip>
  Tool chains execute asynchronously. Use the runs API to monitor progress and check for failures at each stage.
</Tip>
