A notification rule alerts channels as a budget’s spend reaches thresholds.
Each limit budget can have one rule.
A rule has thresholds, channels, and an optional custom message.
The rule sends alerts to notification channels, which you create once and list in the rules of any budget.
A rule can list up to 10 channels.
A threshold is a share of the limit, set as a whole percent from 1 to 1000.
Spend reaches a threshold when it equals or exceeds that share of the limit.
A threshold above 100 alerts on spend beyond the limit.
A threshold never blocks a request.
A rule holds up to 10 thresholds, and each threshold uses a different percent.
Each threshold triggers an alert at most once per budget window, derived budget, and limit.
When one evaluation finds several thresholds reached, only the highest sends an alert.
The lower thresholds still appear as notification events, with no deliveries.
When you change the limit, the thresholds can trigger alerts again.
When you create or replace a rule, AI Cost Management evaluates it right away.
A threshold that spend has already reached in the current budget window sends an alert, unless a higher threshold has already sent one.
By default, alerts use a standard template, which includes:
- The budget
- The threshold
- The limit
- The budget window
- The spend, with a link to the budget
To change the wording of an alert on every channel, you can set up a custom message with a subject and a body.
The subject is a single line of 1 to 200 characters.
The body is plain text of 1 to 2000 characters, and a blank line starts a new paragraph.
Both fields can contain placeholders in double curly braces, for example {{budget.name}}.
AI Cost Management replaces each placeholder with the value for that alert.
Monetary amounts appear in US dollars, for example $4,125.50.
The custom message accepts any of the following placeholders:
|
Placeholder
|
Value
|
budget.name
|
The budget’s name.
|
budget.url
|
A link to the budget in Konnect.
|
threshold
|
The threshold that spend reached, like 80%.
|
limit
|
The limit that spend is measured against. With each, the limit of one derived budget.
|
spend
|
The spend so far in the budget window.
|
percent
|
The spend as a share of the limit, like 82.51%.
|
remaining
|
What is left of the limit, never below $0.00.
|
projected
|
The spend expected by the end of the budget window at the current pace, as an amount and a share of the limit.
|
period
|
The budget window, in the time zone of its anchor.
|
period.start
|
When the budget window started.
|
period.end
|
When the budget window ends and the budget resets.
|
period.remaining
|
How long is left in the budget window, like 8 days or 3 hours.
|
entity.field
|
The each field as a noun: group, user for subject, or env tag for tags.env.
|
entity.value
|
The value whose derived budget reached the threshold.
|
Note: The entity.field and entity.value placeholders work only on a budget with each.
An unknown placeholder, or an entity placeholder on a budget without each, is rejected with an error.
The following custom message template uses placeholders for a budget that splits its limit by group:
Subject: [Kong Konnect] Budget "{{budget.name}}" reached {{threshold}} of its limit
Body: The {{entity.field}} {{entity.value}} used {{spend}} of its {{limit}} limit ({{percent}}), with {{period.remaining}} left in the period.
For example, if you have a budget named Model spend with an 80% threshold, the template produces this alert:
[Kong Konnect] Budget "Model spend" reached 80% of its limit
The group group/example used $4,125.50 of its $5,000.00 limit (82.51%), with 5 days left in the period.
A notification event records each time spend reaches a threshold for a budget.
To list events or get one by ID, use the /v1/ai-cost-management/notification-events endpoints.
AI Cost Management records an event only after it has stored and evaluated the usage that reached the threshold, so an event can show up some time after the request that caused it.
The following sample event shows an 80% threshold reached by a pooled budget, with one delivery to an email channel:
{
"id": "0198c5b6-d000-7000-8000-000000000101",
"kind": "threshold",
"budget": {
"id": "0198c5b6-d000-7000-8000-000000000001",
"name": "Model spend",
"effect": "limit",
"labels": {},
"scope": {
"filters": [
{
"field": "provider",
"op": "eq",
"value": "openai"
}
],
"each": null
},
"priority": 100,
"limit": {
"currency": "USD",
"value": "5000"
},
"window": {
"type": "fixed",
"interval": "P1M",
"anchor": "2026-01-01T00:00:00+00:00[UTC]"
},
"created_at": "2026-06-01T09:00:00Z",
"updated_at": "2026-06-01T09:00:00Z"
},
"threshold": {
"percent": 80
},
"value": null,
"window": {
"start": "2026-07-01T00:00:00Z",
"end": "2026-08-01T00:00:00Z"
},
"limit": {
"currency": "USD",
"value": "5000"
},
"consumed": {
"currency": "USD",
"value": "4031.4"
},
"fired_at": "2026-07-27T14:05:00Z",
"deliveries": [
{
"channel": {
"id": "0198c5b6-d000-7000-8000-000000000201",
"name": "budget-alerts-email",
"type": "email"
},
"status": "delivered",
"error": null,
"updated_at": "2026-07-27T14:05:02Z"
}
]
}
The value field is null because the budget is pooled.
For a budget with each, value holds the value whose derived budget reached the threshold.
A lower threshold that didn’t send an alert has the same shape, with an empty deliveries array.