IntegrationWebhooks & Triggers

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/abc123def456

GitHub 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
    - main

Custom 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
done

Feature 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…