# AWS Budget Integration

### Overview

AWS Budgets lets you set spending thresholds on your AWS account and get notified when your actual or forecasted costs cross those limits. The alerts don't come directly as webhooks — they travel through Amazon SNS first, which wraps everything in an envelope and delivers it to your endpoint as an HTTP POST.

The `Message` field inside that envelope is a JSON-encoded string containing the real alert details: budget name, spend amounts, notification type, and the billing period. The platform parses this automatically, so you don't have to do anything special on your end.

One thing worth knowing upfront: AWS Budgets only fires when a threshold is crossed. There's no recovery notification when spending drops back down — so alerts created by this integration will need to be closed manually in the platform after you've reviewed them.

***

### Integration Flow

```
AWS Budgets
│
│ Threshold exceeded
▼
Amazon SNS Topic
│
│ HTTPS subscription delivers payload
▼
Platform Webhook Endpoint
│
│ SNS envelope parsed → Message field decoded
│ Fingerprint: md5(BudgetName::AccountId)
▼
Alert Created → Priority mapped → On-Call Team Notified
```

***

### Provider Configuration & Mapping

AWS Budgets uses the same SNS envelope pattern as Amazon CloudWatch — the priority information lives inside a JSON string in the `Message` field, not at the top level. The platform extracts `NotificationType` from the parsed message to determine priority.

**Priority Mapping Config:**

```json
{
  "priority": {
    "field": "_priority",
    "options": [
      { "value": "HIGH", "label": "Actual Spend Exceeded" },
      { "value": "MEDIUM", "label": "Forecasted Spend Exceeded" }
    ],
    "mapping": {
      "HIGH": "HIGH",
      "MEDIUM": "MEDIUM"
    }
  }
}
```

**Priority Mapping Table:**

| NotificationType (inside Message) | Platform Priority | Description                                         |
| --------------------------------- | ----------------- | --------------------------------------------------- |
| `ACTUAL`                          | HIGH              | Real spend has crossed the threshold                |
| `FORECASTED`                      | MEDIUM            | Projected spend is on track to exceed the threshold |

**Fingerprint (Correlation) Field:**\
`md5(BudgetName::AccountId)` — ties all alerts from the same budget in the same account together.

### Alert Payload Example

#### Raised (Actual Spend — OVER\_BUDGET)

This is what arrives at your webhook when actual spending crosses the threshold. The `NotificationType` inside `Message` is `ACTUAL`, which maps to **HIGH** priority.

— *ALARM payload received at webhook.site (Type: Notification, Subject: AWS Budgets Notification)*

```json
{
  "Type": "Notification",
  "MessageId": "4fcbd345-c623-5a4b-baa0-b1643acab804",
  "TopicArn": "arn:aws:sns:us-east-1:288761728549:oncall-budget-alerts",
  "Subject": "AWS Budgets Notification",
  "Message": "{\"AlarmName\":\"test-oncall-budget\",\"AccountId\":\"288761728549\",\"BudgetName\":\"test-oncall-budget\",\"BudgetType\":\"COST\",\"BudgetLimit\":{\"Amount\":\"1.0\",\"Unit\":\"USD\"},\"ActualSpend\":{\"Amount\":\"0.85\",\"Unit\":\"USD\"},\"ForecastedSpend\":{\"Amount\":\"1.20\",\"Unit\":\"USD\"},\"NotificationThreshold\":\"80.0\",\"NotificationType\":\"ACTUAL\",\"AlertType\":\"OVER_BUDGET\",\"TimePeriod\":{\"Start\":\"2026-03-01\",\"End\":\"2026-03-31\"},\"Timestamp\":\"2026-03-04T10:00:00Z\"}",
  "Timestamp": "2026-03-04T09:26:01.834Z",
  "SignatureVersion": "1",
  "Signature": "REDACTED",
  "SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-7506a1e35b36ef5a444dd1a8e7cc3ed8.pem",
  "UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:288761728549:oncall-budget-alerts:a2a819e7-cf5d-4981-9a96-b56238145e7c"
}
```

Resulting alert: **Priority → HIGH**, **Type → ALERT**

> AWS Budgets does not send a recovery payload when spending drops below the threshold. Alerts created by this integration must be closed manually in the platform.

***

### Installation & Configuration

#### Step 1: Get Your Webhook URL

Head to **Sources → Add Source**, pick **AWS Budgets** as the provider, give it a name like `AWS Budget Alerts – Production`, and hit Save. Copy the generated **Webhook URL** — you'll need it in the next step.

#### Step 2: Create an SNS Topic

1. Log in to the **AWS Management Console** and navigate to **Simple Notification Service (SNS) → Topics**.
2. Click **Create topic**, select type **Standard** (not FIFO), and give it a name like `oncall-budget-alerts`.
3. Leave everything else as default and click **Create topic**.
4. Note the **Topic ARN** on the detail page — you'll need this when setting up the budget alert.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FZncBHtx90hHR8vIFsBAz%2Fimage.png?alt=media&#x26;token=d4b2915e-6b0e-4566-9e86-15fdcbf810fd" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FNrnbfEmehNL2oHKUF6HZ%2Fimage.png?alt=media&#x26;token=317f1027-e202-448f-a038-75df5ad519b7" alt=""><figcaption></figcaption></figure>

#### Step 3: Subscribe the Webhook to the SNS Topic

1. On the topic detail page, go to the **Subscriptions** tab and click **Create subscription**.
2. Protocol: **HTTPS**
3. Endpoint: Paste your platform webhook URL from Step 1.
4. **Enable raw message delivery:** Leave this **unchecked**. The full SNS envelope needs to reach the platform intact.
5. Click **Create subscription**.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2Fd0UNBzQdX9V8TocWTEpu%2FEkran%20Resmi%202026-03-04%2014.44.27.png?alt=media&#x26;token=cf7bc73a-07f5-4400-ad45-fbc97936c59a" alt=""><figcaption></figcaption></figure>

The subscription will show `PendingConfirmation` right away. AWS fires a `SubscriptionConfirmation` payload to your endpoint — open the `SubscribeURL` value from that payload in your browser to confirm it.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2Fo8Sh6S9PQWZDOxSse4AQ%2FEkran%20Resmi%202026-03-04%2014.45.51.png?alt=media&#x26;token=42e8c837-b631-4f6b-bbdd-3d2df4646cf5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FdCL6mLnUq0DyIAUsDUQy%2FEkran%20Resmi%202026-03-04%2014.48.50.png?alt=media&#x26;token=4b33c7fd-103d-4f5c-b279-d1bb3a4bbf69" alt=""><figcaption></figcaption></figure>

> **Heads up:** The confirmation URL expires in about 3 minutes. If you see `Invalid token`, go to the Subscriptions tab, delete the pending one, and create a fresh subscription.

***

#### Step 4: Create a Budget and Link It to the SNS Topic

1. Navigate to **AWS Billing → Budgets → Create budget**.<br>

   <figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2F43aMYc6UCi14isGO7IzU%2Fimage.png?alt=media&#x26;token=1840c78e-3aac-4d49-acaa-b526a9aa0545" alt=""><figcaption></figcaption></figure>
2. Select **Customize (advanced)** — the simplified template doesn't expose SNS alert options.<br>

   <figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FDS6B4sgu73MzGquQJQDX%2Fimage.png?alt=media&#x26;token=70476d26-2bf6-4318-ad3b-f2f9b317f76f" alt=""><figcaption></figcaption></figure>
3. Set your **Budget name**, **Period** (Monthly), and **Budget amount**.<br>

   <figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FUhAlSDhvvpAGtqmtmqTc%2Fimage.png?alt=media&#x26;token=647e84d3-c31a-4af5-a30c-6d650046e71e" alt=""><figcaption></figcaption></figure>
4. In the **Alerts** section:
   * Threshold: your desired percentage (e.g., `80%`)
   * Trigger: `Actual` or `Forecasted`
   * SNS alert: paste the **Topic ARN** from Step 2<br>

     <figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2Ftl4kjtALgl1OYxUhed2Y%2Fimage.png?alt=media&#x26;token=ea8b9df4-f3ed-44e2-98c7-29e78dc7b4f6" alt=""><figcaption></figcaption></figure>

     <figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FVXNmdc9gWsHPCRddKdd3%2FEkran%20Resmi%202026-03-04%2014.53.43.png?alt=media&#x26;token=fc1feb54-a64b-4913-92db-ce1e0566eb51" alt=""><figcaption></figcaption></figure>
5. Click **Next → Next → Create budget**.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FLSTy9cj6yiNixuALbkvv%2Fimage.png?alt=media&#x26;token=381664af-6cc5-45a2-9ded-d7bd87b1b278" alt=""><figcaption></figcaption></figure>

***

#### Step 5: Test the Integration

Real budget alerts only fire when a threshold is actually crossed, which can take days. Instead, use SNS Publish to send a test payload right now.

1. Go to **SNS → Topics → `oncall-budget-alerts`** and click **Publish message**.
2. **Subject:** `AWS Budgets Notification`
3. **Message body:**

```json
{
  "AlarmName": "test-oncall-budget",
  "AccountId": "123456789012",
  "BudgetName": "test-oncall-budget",
  "BudgetType": "COST",
  "BudgetLimit": {"Amount": "1.0", "Unit": "USD"},
  "ActualSpend": {"Amount": "0.85", "Unit": "USD"},
  "ForecastedSpend": {"Amount": "1.20", "Unit": "USD"},
  "NotificationThreshold": "80.0",
  "NotificationType": "ACTUAL",
  "AlertType": "OVER_BUDGET",
  "TimePeriod": {"Start": "2026-03-01", "End": "2026-03-31"},
  "Timestamp": "2026-03-04T10:00:00Z"
}
```

4. Click **Publish message** and check your webhook endpoint.

— *SNS Publish message form with Subject and Message body filled in*

— *Test payload received (Type: Notification, Message field visible)*

***

### Verification Checklist

* A budget notification payload was received by the platform (status: PROBLEM).
* The `Subject` field reads `AWS Budgets Notification`.
* The `Message` field contains a valid JSON string with `BudgetName`, `AccountId`, `NotificationType`, and `AlertType`.
* Priority mapped correctly: `ACTUAL` → HIGH, `FORECASTED` → MEDIUM.
* The platform created an alert with the budget name visible in the alert title.

***

### Troubleshooting

| Issue                                                                    | Possible Cause                                   | Resolution                                                                                                   |
| ------------------------------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| Subscription stuck on `PendingConfirmation`                              | Confirmation URL expired or endpoint unreachable | Delete the subscription and create a new one. Open the `SubscribeURL` immediately after it arrives.          |
| No alerts received after budget creation                                 | Threshold not yet crossed                        | Use SNS Publish with a test message body to validate without waiting for a real breach.                      |
| `Invalid payload` error                                                  | Raw message delivery is enabled                  | Disable **Enable raw message delivery** on the SNS subscription. The full SNS envelope is required.          |
| Priority always maps to MEDIUM                                           | `NotificationType` not parsed correctly          | Verify the `Message` field is a valid JSON string and `NotificationType` is either `ACTUAL` or `FORECASTED`. |
| Alerts not closing automatically                                         | AWS Budgets does not send recovery events        | This is an AWS limitation. Close budget alerts manually in the platform after investigation.                 |
| Duplicate alerts for the same budget                                     | Multiple SNS subscriptions for the same endpoint | Remove duplicate subscriptions from the SNS topic.                                                           |
| `SubscriptionConfirmation` payload received but status stays unconfirmed | `SubscribeURL` not opened in time                | Copy the `SubscribeURL` from the confirmation payload and open it in a new browser tab.                      |
