{
  "slug": "usage-limit-alert-email",
  "title": "Usage limit alert email: template and code",
  "url": "https://www.courier.com/recipes/usage-limit-alert-email",
  "markdown": "https://www.courier.com/recipes/usage-limit-alert-email.md",
  "stage": "Monetization",
  "purpose": "Warn customers as they near a plan limit, and tell your own team when they hit it.",
  "summary": "A usage limit alert warns customers when their account nears its plan limit. At 80% and again at 100% it sends an email and an Inbox note to the account admin, and an hour after 100% it emails your own team. Each alert goes out at most once a week, and upgrading cancels the team email.",
  "channels": [
    "email",
    "inbox"
  ],
  "shape": "journey",
  "shows": [
    "One journey for two thresholds, picked by a condition on your data",
    "An email to your own team through a recipient override",
    "A throttle so each alert sends once a week"
  ],
  "data": [
    {
      "name": "account_id",
      "type": "string",
      "example": "acct_8F2k",
      "note": "Builds the cancellation token and the account link in the team email"
    },
    {
      "name": "alert_key",
      "type": "string",
      "example": "acct_8F2k-80",
      "note": "Account ID plus threshold. The throttle keys on it"
    },
    {
      "name": "threshold",
      "type": "string",
      "example": "80",
      "note": "80 or 100. Picks which alert sends, and the lower alert prints it"
    },
    {
      "name": "profile.first_name",
      "type": "string",
      "example": "Dana",
      "note": "From the profile. The emails say \"there\" when it's missing"
    },
    {
      "name": "account_name",
      "type": "string",
      "example": "Northwind"
    },
    {
      "name": "plan_name",
      "type": "string",
      "example": "Team"
    },
    {
      "name": "usage",
      "type": "string",
      "example": "8,000",
      "note": "For display"
    },
    {
      "name": "limit",
      "type": "string",
      "example": "10,000",
      "note": "For display"
    }
  ],
  "steps": [
    {
      "step": "1",
      "when": "When an account reaches 80%",
      "channels": "Email, Inbox",
      "templates": [
        "templates/usage-80-email.json",
        "templates/usage-80-inbox.json"
      ]
    },
    {
      "step": "2",
      "when": "When an account reaches 100%",
      "channels": "Email, Inbox",
      "templates": [
        "templates/usage-100-email.json",
        "templates/usage-100-inbox.json"
      ]
    },
    {
      "step": "3",
      "when": "1 hour after the 100% alert",
      "channels": "Email",
      "templates": [
        "templates/usage-100-team-email.json"
      ]
    }
  ],
  "files": {
    "journey": "journey.json",
    "templates": [
      "templates/usage-80-email.json",
      "templates/usage-80-inbox.json",
      "templates/usage-100-email.json",
      "templates/usage-100-inbox.json",
      "templates/usage-100-team-email.json"
    ],
    "setup": [
      "setup.ts"
    ],
    "start": [
      "start.ts",
      "start.py"
    ],
    "stop": [
      "stop.ts",
      "stop.py"
    ]
  },
  "docs": [
    "https://www.courier.com/docs/journeys/nodes/throttle",
    "https://www.courier.com/docs/journeys/nodes/send",
    "https://www.courier.com/docs/journeys/nodes/delay",
    "https://www.courier.com/docs/journeys/nodes/cancel",
    "https://www.courier.com/docs/journeys/invoke"
  ],
  "related_recipes": [
    "https://www.courier.com/recipes/trial-ending-email-sequence",
    "https://www.courier.com/recipes/customer-health-score-slack-alert",
    "https://www.courier.com/recipes/subscription-renewal-reminder-email"
  ],
  "agent_prompt": "Add usage limit alerts to this app, sent through Courier: an email and Inbox note to the account admin at 80% and again at 100% of a plan limit, plus an email to our own team an hour after 100% if the account hasn't upgraded. Follow the steps at https://www.courier.com/recipes/usage-limit-alert-email.md and use the Courier skill for SDK details.\n\n1. Create the journey and its five templates in my Courier workspace by running setup.ts from that page with COURIER_API_KEY from our environment. Save the journey ID it prints as COURIER_USAGE_ALERT_JOURNEY_ID. Replace the placeholder team address in journey.json (alerts@acme.com), the limit name (API requests), and the Acme links in the templates with ours.\n2. Make sure each admin's Courier profile carries first_name, written when they sign up. Find the job or code that meters plan usage and start the journey with the admin's ID each time an account crosses 80% or 100%. Pass the fields in the Data fields table from our own data.\n3. Find where an account upgrades (usually the billing webhook) and cancel the journey with the token usage-<account_id>.\n4. Match this codebase's language, file layout, and error handling. Never hardcode the API key.\n5. When you're done, start one run for a test user at 100% and show me the run's steps. The admin's email and Inbox note go out right away and the run then waits an hour for the team email, so cancel the test run once you've checked it.",
  "status": {
    "state": "passing",
    "last_tested": "2026-10-19"
  }
}
