---
title: Errors & rate limits
description: Trigv API HTTP status codes, monthly event limits, and per-key burst rate limits.
---
# Errors & rate limits

Trigv uses standard HTTP status codes. Error bodies are JSON with a `message` string unless validation fails (422), which includes an `errors` object.

## Status code summary

<div>
  <div class="ti-table-scroll"><table class="ti-table">
    <thead>
      <tr><th>Code</th><th>When</th><th>Example message</th></tr>
    </thead>
    <tbody>
      <tr><td><code>200</code></td><td>Duplicate <code>idempotency_key</code></td><td>- (returns existing <code>event</code> object)</td></tr>
      <tr><td><code>202</code></td><td>Event accepted and queued</td><td>- (returns new <code>event</code> object)</td></tr>
      <tr><td><code>401</code></td><td>Missing/invalid Bearer key, Sanctum token on ingest, or ingest key on dashboard routes</td><td><code>Invalid API key.</code> (or type-specific message)</td></tr>
      <tr><td><code>403</code></td><td>Key revoked, expired, wrong scope, or inactive workspace</td><td><code>This API key has been revoked.</code></td></tr>
      <tr><td><code>404</code></td><td>Channel slug not found or inactive</td><td><code>Channel not found.</code></td></tr>
      <tr><td><code>422</code></td><td>Validation failed (missing <code>channel</code>, <code>title</code>, etc.)</td><td>Laravel validation errors object</td></tr>
      <tr><td><code>429</code></td><td>Monthly workspace event cap <strong>or</strong> per-key burst limit</td><td>See below (two distinct cases)</td></tr>
    </tbody>
  </table></div>
</div>

## Monthly event limit (429)

Each workspace has a monthly event allowance based on plan (stored in `workspace_usage_counters`). When `events_count` reaches `events_limit`, ingest returns:

```
{
		"message": "Monthly event limit reached for this workspace."
}
```

Upgrade your plan or wait for the monthly counter reset. `hop`: 10,000/mo · `leap`: 40,000/mo. See [pricing](/#pricing) for current plans.

## Burst rate limit (429)

Each API key is rate-limited to prevent accidental floods. Default: **60 requests per minute** per key (configurable per key via `rate_limit_per_minute`).

```
{
		"message": "Too many requests for this API key."
}
```

Backoff and retry. If you hit this often in cron loops, add jitter or batch alerts.

## Idempotency

Pass the same `idempotency_key` on retries. The first request returns `202`; subsequent identical keys return `200` with the original event and do not increment monthly usage.

<div>
  <strong>Tip</strong>
  Distinguish 429 responses by reading <code>message</code>: monthly cap vs. burst throttle use different strings.
</div>
