Skip to main content

Triggers

Triggers enable agents to execute in response to external events via webhooks. When something happens in another system, it can automatically invoke your agent.

Integration Event Registry

Deeployd maintains a registry of events from connected integrations. When you connect an integration (HubSpot, Slack, GitHub, etc.), you gain access to its events.

Available Integration Events

IntegrationEvents
HubSpotContact Created, Deal Created, Deal Stage Changed, Deal Won/Lost, Ticket Created, Form Submitted, Meeting Booked
SlackMessage Posted, Bot Mentioned, Reaction Added, Channel Created, User Joined, File Shared
GitHubCode Pushed, PR Opened/Merged/Closed, Review Requested, Issue Opened/Closed, Release Published, Workflow Completed/Failed
StripePayment Succeeded/Failed, Invoice Paid, Subscription Created/Updated/Canceled, Customer Created, Dispute Created

Event Categories

Events are organized by category for easier discovery:

  • CRM: Contact, deal, and company events
  • Communication: Messages, mentions, notifications
  • Development: Code, PRs, issues, deployments
  • Payment: Transactions, subscriptions, invoices
  • Support: Tickets, cases, escalations
  • Calendar: Meetings, scheduling
  • HR: User provisioning, onboarding
  • Task: Work items, assignments

Trigger Types

TypeDescription
WebhookExternal system sends event to Deeployd
PollingDeeployd periodically checks for changes
WebSocketReal-time bidirectional connection
EmailTriggers from email events
ManualUser-initiated triggers

Why Triggers?

Connect your agents to the outside world:

  • Form submissions: Process new leads instantly
  • Payment events: Handle Stripe webhooks
  • CI/CD: Run agents on deployment events
  • Custom integrations: Any system that can send HTTP requests

How Triggers Work

External System ──HTTP POST──▶ Trigger Webhook ──▶ Agent Execution
  1. External system sends HTTP request to trigger URL
  2. Trigger receives and validates the request
  3. Trigger extracts and maps input data
  4. Agent executes with the mapped input
  5. Response returned to external system

Creating Triggers

Basic Trigger

const trigger = await client.triggers.create({
name: 'New Lead Processor',
description: 'Process new leads from website form',
targetType: 'agent',
targetId: 'lead-agent-123'
});

console.log(trigger.webhookUrl);
// https://api.deeployd.com/triggers/abc123

With Signature Verification

Secure your trigger with HMAC signature verification:

const trigger = await client.triggers.create({
name: 'Stripe Webhook',
targetType: 'agent',
targetId: 'payment-agent',
requireSignature: true
});

console.log(trigger.webhookUrl); // Public URL
console.log(trigger.webhookSecret); // Use this to verify signatures

With Input Mapping

Transform incoming webhook data before passing to agent:

const trigger = await client.triggers.create({
name: 'GitHub PR Handler',
targetType: 'agent',
targetId: 'code-review-agent',
inputMapping: {
// Extract specific fields using JSONPath
template: {
prNumber: '$.pull_request.number',
prTitle: '$.pull_request.title',
author: '$.pull_request.user.login',
repo: '$.repository.full_name'
},
// Add static fields
staticFields: {
source: 'github',
reviewType: 'automated'
},
// Include specific headers
includeHeaders: ['x-github-event']
}
});

Trigger for Workflow

Triggers can also start workflows:

const trigger = await client.triggers.create({
name: 'Order Processing Workflow',
targetType: 'workflow',
targetId: 'order-workflow-123',
inputMapping: {
template: {
orderId: '$.order.id',
customerId: '$.order.customer_id',
items: '$.order.line_items'
}
}
});

Webhook URL

Each trigger gets a unique webhook URL:

https://api.deeployd.com/triggers/{slug}

This URL accepts POST requests with JSON payloads.

Calling the Webhook

curl -X POST https://api.deeployd.com/triggers/abc123 \
-H "Content-Type: application/json" \
-d '{
"event": "new_lead",
"lead": {
"name": "John Doe",
"email": "john@example.com"
}
}'

Response

{
"success": true,
"executionId": "exec-789",
"message": "Trigger executed successfully"
}

Signature Verification

When requireSignature: true, incoming requests must include a valid HMAC signature.

How It Works

  1. Sender computes HMAC-SHA256 of request body using webhook secret
  2. Sender includes signature in X-Signature-256 header
  3. Deeployd verifies signature before processing

Example: Sending Signed Requests

import crypto from 'crypto';

const webhookSecret = 'your-webhook-secret';
const payload = JSON.stringify({ event: 'test' });

const signature = crypto
.createHmac('sha256', webhookSecret)
.update(payload)
.digest('hex');

await fetch('https://api.deeployd.com/triggers/abc123', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Signature-256': `sha256=${signature}`
},
body: payload
});

Rotate Webhook Secret

If your secret is compromised:

const newSecret = await client.triggers.rotateSecret('trigger-123');
console.log(newSecret.webhookSecret); // New secret

Input Mapping

Control how webhook data is transformed for your agent.

JSONPath Extraction

Extract nested values from webhook payload:

inputMapping: {
template: {
// $.path.to.field syntax
userId: '$.user.id',
userName: '$.user.profile.name',
firstItem: '$.items[0].name',
allTags: '$.metadata.tags'
}
}

Static Fields

Add constant values:

inputMapping: {
staticFields: {
source: 'webhook',
environment: 'production',
priority: 'high'
}
}

Include Headers

Pass specific headers as input:

inputMapping: {
includeHeaders: [
'x-request-id',
'x-correlation-id',
'user-agent'
]
}

Combined Example

inputMapping: {
template: {
orderId: '$.order.id',
customerEmail: '$.customer.email'
},
staticFields: {
notifyTeam: true,
processor: 'order-handler'
},
includeHeaders: ['x-shopify-shop-domain']
}

Managing Triggers

List Triggers

const triggers = await client.triggers.list({
status: 'active',
limit: 50
});

Get Trigger

const trigger = await client.triggers.get('trigger-123');
// Note: webhookSecret is masked in response

Update Trigger

await client.triggers.update('trigger-123', {
name: 'Updated Name',
status: 'paused',
inputMapping: {
template: { newField: '$.new.path' }
}
});

Delete Trigger

await client.triggers.delete('trigger-123');

Trigger Status

StatusDescription
activeAccepting and processing requests
pausedAccepting but not processing (queued)
disabledRejecting all requests

Pause Trigger

await client.triggers.update('trigger-123', {
status: 'paused'
});

Execution History

Track all trigger executions:

const executions = await client.triggers.listExecutions('trigger-123', {
limit: 100,
status: 'failed' // Optional filter
});

for (const exec of executions.data) {
console.log({
id: exec.id,
method: exec.method,
path: exec.path,
status: exec.status,
duration: exec.durationMs,
requestBody: exec.requestBody,
responseBody: exec.responseBody,
error: exec.error
});
}

Integration Examples

Stripe Webhooks

const trigger = await client.triggers.create({
name: 'Stripe Payment Handler',
targetType: 'agent',
targetId: 'payment-agent',
requireSignature: true,
inputMapping: {
template: {
eventType: '$.type',
paymentId: '$.data.object.id',
amount: '$.data.object.amount',
currency: '$.data.object.currency',
customerId: '$.data.object.customer'
}
}
});

GitHub Webhooks

const trigger = await client.triggers.create({
name: 'GitHub PR Review',
targetType: 'agent',
targetId: 'code-review-agent',
requireSignature: true,
inputMapping: {
template: {
action: '$.action',
prNumber: '$.number',
prTitle: '$.pull_request.title',
prBody: '$.pull_request.body',
author: '$.pull_request.user.login',
repo: '$.repository.full_name',
baseBranch: '$.pull_request.base.ref',
headBranch: '$.pull_request.head.ref'
},
includeHeaders: ['x-github-event']
}
});

Slack Events

const trigger = await client.triggers.create({
name: 'Slack Message Handler',
targetType: 'agent',
targetId: 'slack-bot-agent',
inputMapping: {
template: {
eventType: '$.event.type',
userId: '$.event.user',
channelId: '$.event.channel',
text: '$.event.text',
timestamp: '$.event.ts'
}
}
});

Custom CRM Integration

const trigger = await client.triggers.create({
name: 'New Customer Handler',
targetType: 'workflow',
targetId: 'onboarding-workflow',
inputMapping: {
template: {
customerId: '$.customer.id',
email: '$.customer.email',
name: '$.customer.name',
plan: '$.subscription.plan',
source: '$.attribution.source'
},
staticFields: {
workflow: 'customer-onboarding',
notifyTeam: true
}
}
});

Best Practices

1. Always Use Signature Verification

// ✅ Good - verify webhook authenticity
requireSignature: true

// ❌ Bad - anyone can call your trigger
requireSignature: false

2. Extract Only Needed Data

// ✅ Good - specific fields
template: {
orderId: '$.order.id',
status: '$.order.status'
}

// ❌ Bad - passing entire payload
// (can contain sensitive data, bloats input)

3. Add Source Identification

staticFields: {
source: 'stripe',
environment: 'production'
}

4. Monitor Execution History

Check failed executions regularly and set up alerts:

const failures = await client.triggers.listExecutions('trigger-123', {
status: 'failed',
limit: 10
});

if (failures.data.length > 0) {
// Alert or investigate
}

5. Use Descriptive Names

// ✅ Good
name: 'Stripe Payment Success Handler'
name: 'GitHub PR Opened - Code Review'

// ❌ Bad
name: 'Webhook 1'
name: 'Handler'

Next: Learn about Workflows for orchestrating multi-step processes.