Skip to content

Guardrails

Guardrails let teams define usage or cost thresholds and connect them to actions.

Example: Create A Customer Cost Guardrail

curl "$SPENDWARE_BASE_URL/api/v1/guardrails/" \
  -H "Authorization: Bearer $SPENDWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Customer monthly cost cap","currency":"USD","usage_threshold_exceeded_criteria":"cost","usage_threshold_exceeded_action_id":"THRESHOLD_ACTION_ID","end_customer_id":"CUSTOMER_ID","cost_threshold":100}'
from spendware_provider_sdk.management import UsageGuardrailCreate

guardrail = client.guardrails.create(
    UsageGuardrailCreate(
        title="Customer monthly cost cap",
        currency="USD",
        usage_threshold_exceeded_criteria="cost",
        usage_threshold_exceeded_action_id="THRESHOLD_ACTION_ID",
        end_customer_id="CUSTOMER_ID",
        cost_threshold=100,
    )
)
const guardrail = await client.guardrails.create({
  title: "Customer monthly cost cap",
  currency: "USD",
  usage_threshold_exceeded_criteria: "cost",
  usage_threshold_exceeded_action_id: "THRESHOLD_ACTION_ID",
  end_customer_id: "CUSTOMER_ID",
  cost_threshold: 100,
});

Notes

  • Guardrail thresholds use raw counts or raw money values.
  • Scope guardrails to the customer, project, or plan that should own enforcement.
  • Confirm the threshold action exists before creating the guardrail.

Cycle windows

Guardrails can reset on a cycle: none (cumulative), daily, weekly, monthly, yearly, or custom with cycle_duration_days.

  • When a cycle is set, enforcement compares usage accrued inside the current cycle window against the thresholds. none keeps comparing lifetime accrued counters.
  • cycle_anchor_date (falling back to start_date) anchors the window; monthly and yearly steps clamp the anchor day to the end of shorter months (anchor on Jan 31 resets on Feb 28/29, Mar 31, ...). Without an anchor, windows align to UTC calendar boundaries (midnight, Monday, the 1st of the month, January 1st).
  • Customer and billing-plan guardrails measure the customer's own counters; project guardrails measure usage across every customer in the project.
  • Customer-scoped cost evaluation subtracts credits consumed inside the window, so consumed credits offset windowed cost the same way they offset cumulative cost. Project guardrails always use gross cost.
  • Custom cycles require cycle_duration_days and either an anchor date or a start date; creation and updates are rejected otherwise.
  • Guardrail responses include the current window (current_cycle_start, current_cycle_end) and the evaluated usage (current_usage). Plan-owned rows include usage when listed with usage_end_customer_id, which supplies the per-customer evaluation context for inherited defaults.
  • Threshold-exceeded alerts embed the evaluated window in the alert payload (cycle_type, cycle_start, cycle_end) alongside the observed value.
  • Threshold-exceeded alerts are deduplicated per cycle window: while a guardrail stays exceeded, only the first evaluation creates an alert (history row, webhook delivery, and in-app notification). Editing the threshold re-arms alerting for the window. Cycle-less guardrails deduplicate within the UTC day. Suppressed duplicates increment the operational counter guardrail.alert_deduped.