

# Invoking DevOps Agent through Webhook
<a name="configuring-capabilities-for-aws-devops-agent-invoking-devops-agent-through-webhook"></a>

Webhooks allow external systems to automatically trigger AWS DevOps Agent investigations. This enables integration with ticketing systems, monitoring tools, and other platforms that can send HTTP requests when incidents occur.

## Prerequisites
<a name="prerequisites"></a>

Before configuring webhook access, ensure you have:
+ An Agent Space configured in AWS DevOps Agent
+ Access to the AWS DevOps Agent console
+ The external system that will send webhook requests

## Webhook types
<a name="webhook-types"></a>

AWS DevOps Agent supports the following types of webhooks:
+ **Integration-specific webhooks** – Automatically generated when you configure third-party integrations like Dynatrace, Splunk, Datadog, New Relic, ServiceNow, or Slack. These webhooks are associated with the specific integration and use authentication methods determined by the integration type
+ **Generic webhooks** – Can be manually created for triggering investigations from any source not covered by a specific integration. Generic webhooks currently use **HMAC** authentication (bearer token not currently available).
+ **Grafana alert webhooks** – Grafana can send alert notifications directly to AWS DevOps Agent through webhook contact points. For setup instructions including a custom notification template, see [Connecting Grafana](connecting-telemetry-sources-connecting-grafana.md).

## Webhook authentication methods
<a name="webhook-authentication-methods"></a>

The authentication method for your webhook depends on which integration it's associated with:

**HMAC authentication** – Used by:
+ Dynatrace integration webhooks
+ Generic webhooks (not linked to a specific third-party integration)

**Bearer token authentication** – Used by:
+ Splunk integration webhooks
+ Datadog integration webhooks
+ New Relic integration webhooks
+ ServiceNow integration webhooks
+ Slack integration webhooks

## Configuring webhook access
<a name="configuring-webhook-access"></a>

### Step 1: Navigate to the webhook configuration
<a name="step-1-navigate-to-the-webhook-configuration"></a>

1. Sign in to the AWS Management Console and navigate to the AWS DevOps Agent console

1. Select your Agent Space

1. Go to the **Capabilities** tab

1. In the **Webhook** section, click **Configure**

### Step 2: Generate webhook credentials
<a name="step-2-generate-webhook-credentials"></a>

**For integration-specific webhooks:**

Webhooks are automatically generated when you complete the configuration of a third-party integration. The webhook endpoint URL and credentials are provided at the end of the integration setup process.

**For generic webhooks:**

1. Click **Generate webhook**

1. The system will generate an HMAC key pair

1. Securely store the generated key and secret—you won't be able to retrieve them again

1. Copy the webhook endpoint URL provided

### Step 3: Configure your external system
<a name="step-3-configure-your-external-system"></a>

Use the webhook endpoint URL and credentials to configure your external system to send requests to AWS DevOps Agent. The specific configuration steps depend on your external system.

## Managing webhook credentials
<a name="managing-webhook-credentials"></a>

**Removing credentials** – To delete webhook credentials, go to the webhook configuration section and click **Remove**. After removing credentials, the webhook endpoint will no longer accept requests until you generate new credentials.

**Regenerating credentials** – To generate new credentials, remove the existing credentials first, then generate a new key pair or token.

## Using the webhook
<a name="using-the-webhook"></a>

### Webhook request format
<a name="webhook-request-format"></a>

To trigger an investigation, your external system should send an HTTP POST request to the webhook endpoint URL.

**For Version 1 (HMAC authentication):**

Headers:
+ `Content-Type: application/json`
+ `x-amzn-event-signature: <HMAC signature>`
+ `x-amzn-event-timestamp: <+%Y-%m-%dT%H:%M:%S.000Z>`

The HMAC signature is generated by signing the request body with your secret key using SHA-256.

**For Version 2 (Bearer token authentication):**

Headers:
+ `Content-Type: application/json`
+ `Authorization: Bearer <your-token>`

**Request body:**

The request body should include information about the incident:

```
json

{
  "title": "Incident title",
  "severity": "high",
  "affectedResources": ["resource-id-1", "resource-id-2"],
  "timestamp": "2025-11-23T18:00:00Z",
  "description": "Detailed incident description",
  "data": {
    "metadata": {
        "region": "us-east-1",
        "environment": "production"
    }
  }
}
```

### Example code
<a name="example-code"></a>

**Version 1 (HMAC authentication) - JavaScript:**

```
const crypto = require('crypto');

// Webhook configuration
const webhookUrl = 'https://your-webhook-endpoint.amazonaws.com/invoke';
const webhookSecret = 'your-webhook-secret-key';

// Incident data
const incidentData = {  
    eventType: 'incident',
    incidentId: 'incident-123',
    action: 'created',
    priority: "HIGH",
    title: 'High CPU usage on production server',
    description: 'High CPU usage on production server host ABC in AWS account 1234 region us-east-1',
    timestamp: new Date().toISOString(),
    service: 'MyTestService',
    data: {
      metadata: {
        region: 'us-east-1',
        environment: 'production'
      }
    }
};

// Convert data to JSON string
const payload = JSON.stringify(incidentData);
const timestamp = new Date().toISOString();
const hmac = crypto.createHmac("sha256", webhookSecret);
hmac.update(`${timestamp}:${payload}`, "utf8");
const signature = hmac.digest("base64");

// Send the request
fetch(webhookUrl, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-amzn-event-timestamp': timestamp,
    'x-amzn-event-signature': signature
  },
  body: payload
})
.then(res => {
  console.log(`Status Code: ${res.status}`);
  return res.text();
})
.then(data => {
  console.log('Response:', data);
})
.catch(error => {
  console.error('Error:', error);
});
```

**Version 1 (HMAC authentication) - cURL:**

```
#!/bin/bash

# Configuration
WEBHOOK_URL="https://event-ai.us-east-1.api.aws/webhook/generic/YOUR_WEBHOOK_ID"
SECRET="YOUR_WEBHOOK_SECRET"

# Create payload
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
INCIDENT_ID="test-alert-$(date +%s)"

PAYLOAD=$(cat <<EOF
{
"eventType": "incident",
"incidentId": "$INCIDENT_ID",
"action": "created",
"priority": "HIGH",
"title": "Test Alert",
"description": "Test alert description",
"service": "TestService",
"timestamp": "$TIMESTAMP"
}
EOF
)

# Generate HMAC signature
SIGNATURE=$(echo -n "${TIMESTAMP}:${PAYLOAD}" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)

# Send webhook
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "x-amzn-event-timestamp: $TIMESTAMP" \
-H "x-amzn-event-signature: $SIGNATURE" \
-d "$PAYLOAD"
```

**Version 2 (Bearer token authentication) - JavaScript:**

```
function sendEventToWebhook(webhookUrl, secret) {
  const timestamp = new Date().toISOString();
  
  const payload = {
    eventType: 'incident',
    incidentId: 'incident-123',
    action: 'created',
    priority: "HIGH",
    title: 'Test Alert',
    description: 'Test description',
    timestamp: timestamp,
    service: 'TestService',
    data: {}
  };

  fetch(webhookUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-amzn-event-timestamp": timestamp,
      "Authorization": `Bearer ${secret}`,  // Fixed: template literal
    },
    body: JSON.stringify(payload),
  });
}
```

**Version 2 (Bearer token authentication) - cURL:**

```
#!/bin/bash

# Configuration
WEBHOOK_URL="https://event-ai.us-east-1.api.aws/webhook/generic/YOUR_WEBHOOK_ID"
SECRET="YOUR_WEBHOOK_SECRET"

# Create payload
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
INCIDENT_ID="test-alert-$(date +%s)"

PAYLOAD=$(cat <<EOF
{
"eventType": "incident",
"incidentId": "$INCIDENT_ID",
"action": "created",
"priority": "HIGH",
"title": "Test Alert",
"description": "Test alert description",
"service": "TestService",
"timestamp": "$TIMESTAMP"
}
EOF
)

# Send webhook
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "x-amzn-event-timestamp: $TIMESTAMP" \
-H "Authorization: Bearer $SECRET" \
-d "$PAYLOAD"
```

## Troubleshooting webhooks
<a name="troubleshooting-webhooks"></a>

### If you do not receive a 200
<a name="if-you-do-not-receive-a-200"></a>

A 200 and a message like webhook received indicate the authentication passed and the message has been queued for the system to verify and process. If you do not get a 200 but a 4xx most likely there is something wrong with the authentication or headers. Try sending manually using the curl options to help debug the authentication.

### If you receive a 200 but an investigation does not start
<a name="if-you-receive-a-200-but-an-investigation-does-not-start"></a>

Likely cause is a misformated payload.

1. Check both timestamp and incident id are updated and unique. Duplicate messages are deduplicated.

1. Check the message is valid JSON

1. Check the format is correct

### If you receive a 200 and investigation is immediately cancelled
<a name="if-you-receive-a-200-and-investigation-is-immediately-cancelled"></a>

Most likely you have hit the limit for the month. Please talk to your AWS contact to ask for a rate limit change if appropriate.

## Related topics
<a name="related-topics"></a>
+ [Creating an Agent Space](getting-started-with-aws-devops-agent-creating-an-agent-space.md)
+ [What is a DevOps Agent Web App?](about-aws-devops-agent-what-is-a-devops-agent-web-app.md)
+ [DevOps Agent IAM permissions](aws-devops-agent-security-devops-agent-iam-permissions.md)