Statistical cost anomalies (spikes and dips)
const url = 'https://example.com/api/v1/anomalies?groupBy=service';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://example.com/api/v1/anomalies?groupBy=service'Flags spikes and dips in the daily cost series with a robust median/MAD detector computed at QUERY time — stateless, so retroactive FOCUS corrections are automatically re-scored. Uses the SAME groupBy dimensions as /api/v1/costs/daily and scores both the per-day TOTAL series (the sum over the day’s keys) and each grouping key’s own series. Flags are range-INDEPENDENT: the full stored history up to the requested end is scored, then only flags whose day falls inside [start, end] are returned, so a given day yields the identical flag regardless of the queried start. Passing currency scopes scoring to that billing currency. When currency is omitted, scoring defaults to the alphabetically-first billing currency in the requested window [start, end], falling back to full history when the window is empty. Every statistic is an exact decimal string and the detector’s fixed parameters are echoed, so each flag is hand-recomputable.
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Inclusive first calendar day (UTC) of the RETURNED flags; it does not affect the scoring baseline. Defaults to the full range of stored data.
Inclusive last calendar day (UTC) to score and return. Defaults to the full range of stored data.
Cost grouping dimension (the same set as /api/v1/costs/daily).
Optional three-letter uppercase billing currency whose history to score. Omit to use the alphabetically-first currency in the requested window [start, end], falling back to full history when the window is empty.
Responses
Section titled “Responses”Detected anomalies for the requested period; [] when none.
object
Billing currency of the scored costs (FOCUS BillingCurrency). Empty when no data matched.
object
Strict-threshold multiple of the scaled MAD, as a decimal string.
MAD-to-sigma consistency constant (R stats::mad), as a decimal string.
Maximum trailing observed days in the baseline window.
Minimum baseline observations required to score a day.
Fraction of the absolute median a deviation must also reach, as a decimal string.
The grouping dimension echoed verbatim from the request.
Detected flags, ordered date-ascending, then total scope before key scope, then key-ascending. Never null; [] when nothing is flagged.
object
The UTC calendar day flagged.
“total” (the summed daily series) or “key” (one grouping key’s series).
The grouping key whose series flagged; present ONLY when scope is “key” (never for “total”, so a real key literally named “total” is unambiguous).
“increase” when observed is above the median, “decrease” when below.
The day’s observed value, as an exact decimal string.
Baseline median, as an exact decimal string.
Baseline median absolute deviation, as an exact decimal string.
Mad times consistencyConstant, as an exact decimal string.
K times scaledMad — the strict flag threshold, as an exact decimal string.
The absolute difference of observed and median, as a decimal string.
Example
{ "currency": "USD", "parameters": { "k": "3", "consistencyConstant": "1.4826", "windowDays": 30, "minObservations": 10, "relativeFloor": "0.1", "groupBy": "service" }, "anomalies": [ { "date": "2026-06-18", "scope": "total", "key": "Amazon Elastic Compute Cloud", "direction": "increase", "observed": "31.2", "median": "4.6809", "mad": "0.0013", "scaledMad": "0.00192738", "threshold": "0.00578214", "deviation": "26.5191" } ]}Invalid start date, end date, groupBy value, or currency shape; or groupBy=allocation was requested but no allocation rules are configured or the rules file was not found.
The cost query failed, including an unreadable, malformed, or invalid allocation rules file.