Webhooks & Triggers
ReAPI supports webhook-based triggers and can send webhooks to external systems, enabling seamless integration with your development workflow.
Incoming Webhooks (Triggering Tests)
Webhook URLs
Each deployment can have a unique webhook URL for external triggering:
# Create deployment with webhook enabled
reapi deployment create \
--name "pr-validation" \
--runner "api-contracts" \
--environment "staging" \
--webhook-enabled
# Get webhook URL
reapi deployment webhook-url "pr-validation"
# Returns: https://api.reapi.com/webhooks/deploy/abc123def456GitHub Integration
Trigger tests on pull requests and pushes:
# .github/workflows/reapi-webhook.yml
name: Trigger ReAPI Tests
on:
pull_request:
types: [opened, synchronize]
push:
branches: [main]
jobs:
trigger-tests:
runs-on: ubuntu-latest
steps:
- name: Trigger ReAPI Webhook
run: |
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Content-Type: application/json" \
-d '{
"trigger": "github",
"event": "${{ github.event_name }}",
"branch": "${{ github.ref_name }}",
"commit": "${{ github.sha }}",
"pr_number": "${{ github.event.number }}",
"repository": "${{ github.repository }}"
}'GitLab Integration
# .gitlab-ci.yml
trigger-api-tests:
stage: test
script:
- |
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Content-Type: application/json" \
-d "{
\"trigger\": \"gitlab\",
\"pipeline_id\": \"$CI_PIPELINE_ID\",
\"commit\": \"$CI_COMMIT_SHA\",
\"branch\": \"$CI_COMMIT_REF_NAME\",
\"project\": \"$CI_PROJECT_PATH\"
}"
only:
- merge_requests
- mainCustom Webhook Payloads
# Basic trigger
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Content-Type: application/json" \
-d '{"trigger": "manual"}'
# Trigger with custom variables
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Content-Type: application/json" \
-d '{
"trigger": "deployment",
"environment": "production",
"version": "v2.1.0",
"variables": {
"testUser": "prod-test-user",
"timeout": "60000"
}
}'
# Trigger with authentication
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-webhook-token" \
-d '{
"trigger": "secure-deployment",
"metadata": {
"deployer": "john.doe@company.com",
"approval_id": "DEPLOY-12345"
}
}'Outgoing Webhooks (Test Results)
Webhook Configuration
Configure ReAPI to send test results to your systems:
// Webhook configuration in deployment
{
"webhooks": {
"onComplete": [
{
"url": "https://your-app.com/api/test-results",
"method": "POST",
"headers": {
"Authorization": "Bearer your-api-token",
"Content-Type": "application/json"
},
"payload": {
"deployment": "{{deployment.name}}",
"environment": "{{deployment.environment}}",
"status": "{{result.status}}",
"summary": "{{result.summary}}",
"details": "{{result.details}}"
}
}
],
"onFailure": [
{
"url": "https://alerts.company.com/webhook",
"method": "POST",
"payload": {
"alert": "API tests failed",
"deployment": "{{deployment.name}}",
"environment": "{{deployment.environment}}",
"failedTests": "{{result.failed}}",
"timestamp": "{{result.timestamp}}"
}
}
]
}
}Slack Integration
Send test results to Slack channels:
// Slack webhook configuration
{
"webhooks": {
"onComplete": [
{
"url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
"method": "POST",
"payload": {
"channel": "#api-testing",
"username": "ReAPI Bot",
"icon_emoji": ":robot_face:",
"attachments": [
{
"color": "{{result.status == 'passed' ? 'good' : 'danger'}}",
"title": "API Test Results - {{deployment.name}}",
"fields": [
{
"title": "Environment",
"value": "{{deployment.environment}}",
"short": true
},
{
"title": "Status",
"value": "{{result.status}}",
"short": true
},
{
"title": "Passed/Total",
"value": "{{result.passed}}/{{result.total}}",
"short": true
},
{
"title": "Duration",
"value": "{{result.duration}}s",
"short": true
}
],
"footer": "ReAPI",
"ts": "{{result.timestamp}}"
}
]
}
}
]
}
}Microsoft Teams Integration
// Teams webhook configuration
{
"webhooks": {
"onComplete": [
{
"url": "https://outlook.office.com/webhook/your-teams-webhook-url",
"method": "POST",
"payload": {
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"summary": "API Test Results",
"themeColor": "{{result.status == 'passed' ? '00FF00' : 'FF0000'}}",
"sections": [
{
"activityTitle": "API Test Results - {{deployment.name}}",
"activitySubtitle": "Environment: {{deployment.environment}}",
"facts": [
{
"name": "Status",
"value": "{{result.status}}"
},
{
"name": "Tests Passed",
"value": "{{result.passed}}/{{result.total}}"
},
{
"name": "Duration",
"value": "{{result.duration}} seconds"
}
]
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "View Details",
"targets": [
{
"os": "default",
"uri": "{{result.detailsUrl}}"
}
]
}
]
}
}
]
}
}Integration Patterns
Deployment Pipeline Integration
#!/bin/bash
# deploy-with-tests.sh
set -e
# Deploy application
echo "Deploying application..."
./deploy.sh $ENVIRONMENT
# Get deployment details
DEPLOYMENT_ID=$(./get-deployment-id.sh)
WEBHOOK_URL="https://api.reapi.com/webhooks/deploy/abc123def456"
# Trigger API tests via webhook
echo "Triggering API tests..."
RESPONSE=$(curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{
\"trigger\": \"deployment\",
\"deploymentId\": \"$DEPLOYMENT_ID\",
\"environment\": \"$ENVIRONMENT\",
\"version\": \"$VERSION\"
}")
# Extract run ID from response
RUN_ID=$(echo "$RESPONSE" | jq -r '.runId')
# Wait for tests to complete
echo "Waiting for tests to complete (Run ID: $RUN_ID)..."
while true; do
STATUS=$(reapi results show "$RUN_ID" --output json | jq -r '.status')
if [[ "$STATUS" == "completed" ]]; then
RESULT=$(reapi results show "$RUN_ID" --output json | jq -r '.result')
if [[ "$RESULT" == "passed" ]]; then
echo "✅ Tests passed! Deployment successful."
exit 0
else
echo "❌ Tests failed! Rolling back deployment."
./rollback.sh $ENVIRONMENT
exit 1
fi
elif [[ "$STATUS" == "failed" ]]; then
echo "❌ Test execution failed! Rolling back deployment."
./rollback.sh $ENVIRONMENT
exit 1
fi
sleep 30
doneFeature Flag Integration
// Trigger tests when feature flags change
const webhook = {
url: "https://api.reapi.com/webhooks/deploy/feature-tests",
method: "POST",
payload: {
trigger: "feature-flag-change",
flag: flagName,
enabled: flagValue,
environment: environment,
variables: {
testFeatureFlag: flagValue,
featureName: flagName
}
}
};
// Send webhook when feature flag changes
await fetch(webhook.url, {
method: webhook.method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(webhook.payload)
});Database Migration Integration
# trigger_tests_after_migration.py
import requests
import sys
def trigger_api_tests(migration_version, environment):
webhook_url = "https://api.reapi.com/webhooks/deploy/migration-tests"
payload = {
"trigger": "database-migration",
"migrationVersion": migration_version,
"environment": environment,
"variables": {
"migrationVersion": migration_version,
"testDataReset": "true"
}
}
response = requests.post(webhook_url, json=payload)
if response.status_code == 200:
run_data = response.json()
print(f"✅ API tests triggered successfully (Run ID: {run_data['runId']})")
return run_data['runId']
else:
print(f"❌ Failed to trigger API tests: {response.status_code}")
sys.exit(1)
if __name__ == "__main__":
migration_version = sys.argv[1]
environment = sys.argv[2]
trigger_api_tests(migration_version, environment)Webhook Security
Authentication
# Webhook with bearer token authentication
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "Authorization: Bearer your-webhook-token" \
-H "Content-Type: application/json" \
-d '{"trigger": "secure-deployment"}'
# Webhook with API key authentication
curl -X POST "https://api.reapi.com/webhooks/deploy/abc123def456" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"trigger": "secure-deployment"}'Signature Verification
// Verify webhook signatures (for outgoing webhooks)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expectedSignature}`, 'utf8'),
Buffer.from(signature, 'utf8')
);
}
// Express.js webhook handler
app.post('/webhook/reapi', (req, res) => {
const signature = req.headers['x-reapi-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook payload
console.log('Test results received:', req.body);
res.status(200).send('OK');
});IP Allowlisting
# Nginx configuration for webhook endpoints
location /webhook/reapi {
# Allow only ReAPI webhook IPs
allow 203.0.113.0/24;
allow 198.51.100.0/24;
deny all;
proxy_pass http://backend;
}Best Practices
Webhook Design
- Use meaningful webhook URLs and names
- Implement proper error handling and retries
- Include relevant context in webhook payloads
- Use appropriate HTTP methods and status codes
Security
- Always use HTTPS for webhook URLs
- Implement signature verification for sensitive webhooks
- Use API keys or bearer tokens for authentication
- Regularly rotate webhook secrets and tokens
Reliability
- Implement idempotency for webhook handlers
- Use proper timeout values for webhook requests
- Implement exponential backoff for retries
- Monitor webhook delivery success rates
Integration
- Design webhooks to be environment-agnostic when possible
- Use structured payload formats (JSON)
- Include sufficient metadata for debugging
- Implement proper logging and monitoring
More webhook integration patterns and advanced examples coming soon…