# Daily Message Limits

Every plan comes with a number of messages per day. The count resets at **00:00 UTC**. Once you reach the limit, new messages are rejected with `429 Too Many Requests` until the reset — they are not stored and no push is sent.

## Limits by plan

| Plan | Messages per day |
|------|-----------------:|
| Free | 50 |
| Starter | 1,000 |
| Medium | 5,000 |
| Large | Unlimited |

Your current plan and today's usage are on the [Billing](https://pocketalert.app/account/billing) page, and available over the API from [`GET /v1/messages/usage`](https://info.pocketalert.app/api/messages/usage.md).

## What counts

Every message created on your account counts once, on the UTC day it was created:

- **API requests** — [`POST /v1/messages`](https://info.pocketalert.app/api/messages/create.md), including requests with an attachment.
- **Webhook calls** — each call that produces a message.
- **Scheduled messages** — counted on the day you **schedule** them, not the day they are delivered. A message scheduled today for next Tuesday uses today's quota; delivery itself never consumes quota and is never blocked by it.

What does not count:

- Requests that fail validation (`400`, `403`) or fail on our side (`500`) — the quota is refunded.
- Rejected requests themselves. They are tallied separately as `rejected` so you can see what you missed.

> **Warning: Deleting messages does not free up quota**
>
> The counter tracks messages sent, not messages stored. Deleting messages — one by one or all at once — does not give today's quota back.

## When the limit is reached

The API answers `429 Too Many Requests` with a `Retry-After` header holding the number of seconds until the reset:

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 30142
X-PA-Daily-Limit: 50
X-PA-Daily-Remaining: 0
X-PA-Daily-Reset: 1790035200
```

```json
{
  "error": "Daily message limit reached (50/50). New messages are rejected until 00:00 UTC. Upgrade your plan to raise the limit.",
  "limit": 50,
  "used": 50,
  "resets_at": "2026-09-22T00:00:00Z",
  "upgrade_url": "https://pocketalert.app/pricing"
}
```

> **Tip: Handling 429 in your integration**
>
> Treat `429` as "not now", not as a transient failure. Retrying before `Retry-After` elapses gets the same answer — every retry is rejected and counted. Either wait until `resets_at`, or drop the alert and log it.

### Webhooks

Webhook calls over the limit are refused with the same `429`, but each one is still recorded in the webhook's [history](https://info.pocketalert.app/api/webhooks/history.md) with its full payload and the message it would have produced. The entry has `status: "error"` and `error_code: "daily_limit"`, so nothing disappears without a trace — open the history to see what arrived while you were over the limit.

## Rate-limit headers

Every successful `POST /v1/messages` (and every webhook call that creates a message) carries the current quota:

| Header | Meaning |
|--------|---------|
| `X-PA-Daily-Limit` | Messages allowed per day on your plan |
| `X-PA-Daily-Remaining` | Messages left today, after this one |
| `X-PA-Daily-Reset` | Unix timestamp (seconds) of the next reset, 00:00 UTC |

Unlimited plans don't get these headers.

## Emails

Pocket Alert emails the account owner twice at most per day:

- **At 80%** of the daily limit — a heads-up while there is still room.
- **On the first rejected message** — the limit is reached and new messages are being refused.

Unlimited plans never get these emails.

## Upgrading

A new plan applies immediately: once the upgrade goes through, the next request is checked against the new limit — no need to wait for the reset. See [pricing](https://pocketalert.app/pricing).

## Related

- [Create Message](https://info.pocketalert.app/api/messages/create.md) — the `429` response in context
- [Message usage](https://info.pocketalert.app/api/messages/usage.md) — today's usage over the API
- [Webhook history](https://info.pocketalert.app/api/webhooks/history.md) — where rejected webhook calls are kept
- [Scheduled delivery](https://info.pocketalert.app/features/scheduled-delivery.md) — how scheduled messages are counted
