Skip to content

Webhook Triggers

Any task can be triggered via an HTTP POST to a unique webhook URL. This lets external systems — GitHub Actions, monitoring tools, other APIs — fire a task on demand without needing an ApiMeld account.

Setting up a webhook trigger

  1. Open a task and go to the Triggers tab
  2. Enable Webhook trigger
  3. Optionally set a Shared Secret (recommended — see below)
  4. Copy the generated webhook URL — it looks like:
    https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

The GUID in the URL is unique to this task. Anyone with this URL can trigger the task, so treat it like a secret.

Triggering a task

Send an HTTP POST to the webhook URL. No authentication header is required — the GUID in the URL serves as the token.

bash
curl -X POST https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

With a payload:

bash
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"event": "deploy", "version": "1.2.3", "environment": "production"}' \
  https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

The response is immediate — ApiMeld queues the task and returns 202 Accepted. The task runs asynchronously.

Accessing the payload in scripts

The request body is available in the script as the $payload (PowerShell) or payload (JavaScript/TypeScript/Python) variable.

PowerShell:

powershell
if ($payload) {
    $data = $payload | ConvertFrom-Json
    $logger.Info("Deploy version: $($data.version) to $($data.environment)")
}

JavaScript:

javascript
if (payload) {
  const data = JSON.parse(payload)
  logger.info(`Deploy version: ${data.version} to ${data.environment}`)
}

Python:

python
import json, os

raw = os.environ.get('TASK_PAYLOAD', '')
if raw:
    data = json.loads(raw)
    print(f"Deploy version: {data['version']} to {data['environment']}")

Use cases

  • GitHub Actions: trigger a deployment task after a successful build
  • Monitoring: trigger an alert-response task when Grafana fires an alert
  • External schedulers: trigger ApiMeld tasks from an existing scheduler you're migrating away from
  • IoT / edge devices: trigger a data ingestion task when a device reports in

Shared Secret

A shared secret adds a second layer of protection on top of the GUID URL. When set, every request must include the secret in the X-Webhook-Secret header — requests without it or with the wrong value are rejected with 404 (not 401, to avoid confirming that the GUID is valid).

Set the shared secret when creating or editing the webhook trigger. Store it alongside the webhook URL in your calling system.

bash
# Trigger with a shared secret
curl -X POST \
  -H "X-Webhook-Secret: your-shared-secret" \
  https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

With a payload:

bash
curl -X POST \
  -H "X-Webhook-Secret: your-shared-secret" \
  -H "Content-Type: application/json" \
  -d '{"event": "deploy", "version": "1.2.3"}' \
  https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

GitHub Actions example:

yaml
- name: Trigger ApiMeld task
  run: |
    curl -X POST \
      -H "X-Webhook-Secret: ${{ secrets.APIMELD_WEBHOOK_SECRET }}" \
      -H "Content-Type: application/json" \
      -d "{\"ref\": \"${{ github.ref }}\", \"sha\": \"${{ github.sha }}\"}" \
      https://tasks.example.com/api/webhook/a1b2c3d4-e5f6-7890-abcd-ef1234567890

TIP

Use a long random string as the shared secret — at least 32 characters. You can generate one with openssl rand -hex 32.

Rotating the webhook URL

If your webhook URL is compromised, disable and re-enable the webhook trigger on the task — a new GUID is generated and the old URL stops working.

Combining with a cron schedule

A task can have both a cron schedule and a webhook trigger active simultaneously. The task runs on its schedule and can also be fired on demand via the webhook.