# Review customers nearing their API caps

> Rank customers by monthly API quota consumption, show threshold and projection evidence, and prepare human-reviewed account outreach without sending it.

## Agent adaptation contract

- Canonical human page: https://agentry.sh/workflows/rate-limit-alert-routing
- Execution mode: human_review
- Immutable automation template: none
- Applies to: devtools-api
- Required example events: api_request
- Required Agentry resources: analytics
- Do not use when:
  - Do not use until the example events are mapped to observed project signals, the current onboarding state is verified, and live event/property reads prove the required data is present.
  - Do not automatically send, publish, suppress, mutate, or contact anyone from this workflow.
- Ask before using:
  - Which observed events map to api_request? Is the current onboarding state verified, and do live event/property reads show non-synthetic traffic for them?
  - Which live properties provide api_request.customer_id, api_request.plan, and which stable user or account identifier joins the signals?

This is an adaptable workflow example, not an API recipe. Map event and property names to the project's saved signal map, require status: "verified" from GET /v1/projects/:project_id/onboarding, and confirm the required signals through live event/property metadata and rows. Fetch current OpenAPI or query-blueprint details before making calls. Do not infer unattended authority from this page.

## Why this matters

A customer approaching a monthly cap may face an outage, a legitimate growth
event, or a runaway integration. The same number can lead to very different
decisions. Review usage, remaining quota, month-end projection, plan source,
and recent deploy context before recommending outreach or a limit change.

## Run the review

Prove `api_request.customer_id` and `api_request.plan` are answer-ready through
the saved signal map, verified current onboarding state, and live event-property metadata. Then
fetch the filtered schema for
`POST /v1/projects/:project_id/analytics/query` and, in the interactive owner
session, calculate one bounded row per customer:

```text
customer_id
plan
calls_this_month
authoritative_cap
percent_used
calls_last_24h
projected_month_end
```

The cap mapping must come from an authoritative billing or product source
provided by the reviewer. Do not infer limits from plan names. Use minimum
volume checks so a test account does not dominate the result.

Classify rows for review:

- 80–89%: verify expected growth and remaining days;
- 90–99%: identify the owning team and likely cap date;
- 100% or projected above cap: distinguish growth from a runaway loop;
- sudden step-change: compare with recent deploys and endpoint mix.

## Output format

```text
Quota review — <month and UTC as_of>

Customer | Plan | Used / cap | Projected | Change | Evidence
<id>     | <p>  | <n>/<n>    | <n>       | <n>%   | <source>

Needs account-owner review
- <customer> — <why> — <questions to answer before outreach>

Possible technical anomaly
- <customer> — <endpoint/deploy evidence> — <next investigation>

Draft account note
- <customer> — <draft only; not sent>
```

Customer IDs, plan data, and usage are owner-visible data. Keep the result in
the human-controlled session. A human chooses whether to contact an account,
change a cap, or share a summary.

## Instrumentation

Emit usage from the trusted application server with a stable customer ID:

```ts
await fetch("https://api.agentry.sh/v1/analytics/", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.AGENTRY_SERVER_API_KEY}`,
    "Content-Type": "application/json",
    "User-Agent": "api-service/1.0",
  },
  body: JSON.stringify({
    event: "api_request",
    distinct_id: user.id,
    properties: {
      customer_id: account.id,
      plan: account.plan,
      endpoint: request.route,
    },
  }),
});
```

## Unattended boundary

No current versioned automation template grants a runner raw customer usage,
generic HogQL, messaging, or quota mutation. Do not install an owner key in a
scheduler or use agent-local state for deduplication. Keep this review on
demand until a narrow server-owned source and explicit policy exist.

## Variations

- *"Compare this month with the same elapsed days last month."*
- *"Break sudden growth down by endpoint to find runaway loops."*
- *"Show accounts with no usage after a historically active period."*
- *"Draft a CS handoff for the top five accounts; do not send it."*
