---
title: "The monthly quota reached a threshold"
method: POST
path: "quota.threshold_reached"
tags: ["Webhooks"]
---

# The monthly quota reached a threshold

`POST quota.threshold_reached` (webhook)

Posted to the subscriptions to `quota.threshold_reached` at 50, 80, 95 and 100% of the monthly quota, once a month per threshold. Signed and retried like every event. The test event (`POST /api/v1/webhooks/{id}/test`) arrives under this `type` too, with `data: { test: true, message }` and none of the fields of the real event: check `data.test` first.

## Headers

- `Mailcheer-Signature` string, required
- `Mailcheer-Timestamp` string, required
- `Mailcheer-Event-Id` string, required
- `Mailcheer-Event-Type` string, required
- `Mailcheer-Delivery-Id` string, required
- `Mailcheer-Attempt` string, required

## Payload

- union
  - QuotaThresholdEvent: The body of a `quota.threshold_reached` call. The same envelope as every event (`id`, `type`, `created_at`, `data`).
    - `id` string, required
    - `type` 'quota.threshold_reached', required
    - `created_at` string, date-time, required
    - `data` object, required
      - `threshold` 50 | 80 | 95 | 100, required: The threshold reached, in percent of the monthly quota.
      - `plan` 'free' | 'starter' | 'pro' | 'agency', required: The workspace's plan (`free`, `starter`, `pro`, `agency`).
      - `quota` integer, required: Emails a month included in the plan.
      - `sent` integer, required: Emails accepted this month.
      - `in_flight` integer, required: Emails promised but not yet sent (queue).
      - `remaining` integer, required: What can still be sent this month: `quota − sent − in_flight`, never negative.
      - `resets_at` string, date-time, required: When the counter resets: the 1st of next month, 00:00 UTC.
      - `period` string, required: The month counted, `YYYY-MM` (UTC).
  - TestEvent: The body of the test event (`POST /api/v1/webhooks/{id}/test`, or Settings → API). Its `type` is the subscription's first event, but its `data` holds only `test` and `message` — **none of the fields of the real event**. Check `data.test === true` before reading anything else, and answer 2xx without processing it.
    - `id` string, required: `evt_…` — the same on every attempt and every replay of the event: the deduplication key.
    - `type` 'email.sent' | 'email.failed' | 'email.delivered' | 'email.opened' | 'email.clicked' | 'email.bounced' | 'email.complained' | 'email.received' | 'subscriber.created' | 'subscriber.unsubscribed' | 'quota.threshold_reached', required
    - `created_at` string, date-time, required: When the event occurred (not when it was delivered).
    - `data` object, required
      - `test` true, required: Always `true`: this is a test.
      - `message` string, required: A sentence in the language of the request (`Accept-Language`) or of the screen.

## Acknowledgement `2XX`

Any 2xx within 15 seconds acknowledges receipt. Anything else — another status, a redirect (not followed), no answer, a network error — is retried: 5 attempts in all, the next ones 30 s, 2 min, 10 min and 1 h after the previous failure.

---

[API](https://skmtc.dev/mailcheer/apis/mailcheer-api.md) · [All operations](https://skmtc.dev/mailcheer/apis/mailcheer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailcheer/apis/mailcheer-api/revisions/ba64b7ef2170?raw)
