Create webhook endpoints that allow external services to invoke your agents
Triggers create webhook endpoints that allow external services (like GitHub, Slack, Stripe, or custom applications) to invoke your agents. When a webhook is received, the payload is validated, transformed, and used to start a new conversation with the agent.
Triggers are useful for:
Event-driven workflows - Respond to events from external services (GitHub issues, Stripe payments, etc.)
Third-party integrations - Connect services that can send webhooks to your agents
Automated tasks - Trigger agent actions based on external events
Custom applications - Allow your own services to invoke agents via HTTP
import { agent , trigger , subAgent } from "@inkeep/agents-sdk" ;
const slackTrigger = trigger ({
name : "Slack Messages" ,
description : "Handle incoming Slack messages" ,
messageTemplate : "New message from {{user.name}}: {{text}}" ,
authentication : { type : "none" },
});
export default agent ({
id : "support-agent" ,
name : "Support Agent" ,
defaultSubAgent : subAgent ({
id : "support" ,
name : "Support Assistant" ,
prompt : "You help answer support questions." ,
}),
triggers : () => [ slackTrigger ],
});
Use JSON Schema or Zod to validate incoming webhook payloads:
import { z } from "zod" ;
const githubWebhookTrigger = trigger ({
name : "GitHub Events" ,
description : "Handle GitHub webhook events" ,
inputSchema : z . object ({
action : z . string (),
repository : z . object ({
full_name : z . string (),
}),
sender : z . object ({
login : z . string (),
}),
}),
messageTemplate :
"GitHub event: {{action}} on {{repository.full_name}} by {{sender.login}}" ,
authentication : { type : "none" },
signingSecret : process . env . GITHUB_WEBHOOK_SECRET ,
});
Triggers support multiple authentication methods:
Option Type Required Description namestringYes Human-readable name for the trigger descriptionstringNo Description of what the trigger does enabledbooleanNo Whether the trigger is active (default: true) inputSchemaobject | ZodObjectNo JSON Schema or Zod schema for payload validation messageTemplatestringYes Template for the message sent to the agent authenticationobjectNo Authentication configuration signingSecretstringNo HMAC-SHA256 secret for signature verification outputTransformobjectNo Payload transformation configuration
Message templates use {{placeholder}} syntax to interpolate values from the webhook payload:
const trigger = trigger ({
name : "Order Webhook" ,
messageTemplate : `
New order received:
- Order ID: {{order.id}}
- Customer: {{customer.name}} ({{customer.email}})
- Total: ${ {order. total } }
- Items: {{order.items.length}} items
Please process this order and send a confirmation.
` . trim (),
authentication : { type : "none" },
});
Nested properties are accessed with dot notation ({{customer.email}}). Array length can be accessed with .length.
Transform incoming payloads before they reach the message template:
const transformingTrigger = trigger ({
name : "Transformed Webhook" ,
messageTemplate : "Event: {{eventType}} - {{summary}}" ,
outputTransform : {
// JMESPath expression for complex transformations
jmespath : "{ eventType: type, summary: data.description }" ,
},
authentication : { type : "none" },
});
// Or use simple object mapping
const mappingTrigger = trigger ({
name : "Mapped Webhook" ,
messageTemplate : "User {{userName}} performed {{actionName}}" ,
outputTransform : {
objectTransformation : {
userName : "payload.user.display_name" ,
actionName : "payload.action.type" ,
},
},
authentication : { type : "none" },
});
For services that sign webhooks (like GitHub, Stripe, Slack), use signingSecret:
const githubTrigger = trigger ({
name : "GitHub Webhook" ,
messageTemplate : "GitHub: {{action}} on {{repository.full_name}}" ,
authentication : { type : "none" },
signingSecret : process . env . GITHUB_WEBHOOK_SECRET ,
});
The framework automatically verifies HMAC-SHA256 signatures in the X-Hub-Signature-256 header.
After pushing your agent configuration, each trigger gets a unique webhook URL:
POST /tenants/{tenantId}/projects/{projectId}/agents/{agentId}/triggers/{triggerId}
You can find the full webhook URL in the Inkeep dashboard or via the API response when creating/listing triggers.
Every webhook invocation is tracked with:
Invocation ID - Unique identifier for the invocation
Status - pending, success, or failed
Request Payload - Original webhook payload
Transformed Payload - Payload after transformation
Conversation ID - ID of the conversation created
Error Message - Error details if the invocation failed
Query invocation history via the API:
# List invocations for a trigger
curl "https://api.inkeep.com/v1/tenants/{tenantId}/projects/{projectId}/agents/{agentId}/triggers/{triggerId}/invocations"
# Filter by status or date range
curl "https://api.inkeep.com/v1/.../invocations?status=failed&from=2024-01-01T00:00:00Z"
Here's a complete example with a GitHub webhook trigger that handles issue events:
import { z } from "zod" ;
import { agent , trigger , subAgent } from "@inkeep/agents-sdk" ;
// Define the expected GitHub webhook payload
const githubIssueSchema = z . object ({
action : z . enum ([ "opened" , "closed" , "reopened" , "edited" ]),
issue : z . object ({
number : z . number (),
title : z . string (),
body : z . string (). nullable (),
user : z . object ({
login : z . string (),
}),
labels : z . array (
z . object ({
name : z . string (),
})
),
}),
repository : z . object ({
full_name : z . string (),
}),
});
const githubIssueTrigger = trigger ({
name : "GitHub Issues" ,
description : "Responds to GitHub issue events" ,
enabled : true ,
inputSchema : githubIssueSchema ,
messageTemplate : `
GitHub Issue {{action}}:
- Repository: {{repository.full_name}}
- Issue #{{issue.number}}: {{issue.title}}
- Author: {{issue.user.login}}
- Body: {{issue.body}}
Please analyze this issue and provide a helpful response.
` . trim (),
authentication : { type : "none" },
signingSecret : process . env . GITHUB_WEBHOOK_SECRET ,
});
const issueResponder = subAgent ({
id : "issue-responder" ,
name : "Issue Responder" ,
prompt : `You are a helpful assistant that responds to GitHub issues.
When an issue is opened, analyze the content and provide:
1. A summary of the issue
2. Suggested labels if appropriate
3. Initial guidance or questions for the issue author` ,
});
export default agent ({
id : "github-bot" ,
name : "GitHub Bot" ,
defaultSubAgent : issueResponder ,
triggers : () => [ githubIssueTrigger ],
});
Always validate input - Use inputSchema to ensure payloads match expected format
Use signing secrets - Verify webhook authenticity when the source supports it
Write clear templates - Make message templates readable and include relevant context
Handle errors gracefully - Check invocation status and logs for failed webhooks
Use descriptive names - Name triggers clearly to identify their purpose in dashboards