---
title: Limits
description: Batch size, payload size, and rate limits across the Ingestion & Decisioning API.
---

Retidal enforces limits at the request, payload, and rate level. Hitting one returns a specific status code — see [Errors & status codes](/docs/errors).

## Prerequisites

- A project API key — see [Quickstart](/docs/quickstart) — and familiarity with [Authentication](/docs/authentication)'s scopes.

## Batch size

- `POST /api/v1/t` accepts up to **100 events** per request.
- `POST /internal/backfill/events` accepts up to **1000 events** per request.

## Payload size

- `traits` payloads (identify/profile) are capped at **8 KiB**.
- `traits` nesting is capped at **2 levels**.

## Rate limits

- `POST /api/v1/decide` and `POST /api/v1/coupons/redeem` are limited to **30 req/min** per (project, IP).
- `PUT /api/v1/profile` is limited to **60 req/min** per (project, IP).

## What this unlocks

Knowing these caps unlocks designing your integration's batching and retry strategy up front ([Send data](/docs/sending-data/events)) instead of discovering them from `POST /api/v1/decide`'s own `400`/`429` in production.

## Verify it worked

Confirm the batch cap is enforced by sending a request over the ingestion limit:

```bash
# events.json contains 101 events
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://api.retidal.com/api/v1/t \
  -H "X-API-Key: $RETIDAL_API_KEY" -H "Content-Type: application/json" \
  --data @events.json
# expect: 400 — batch-size overflow
```

## If it doesn't work

If a request is rejected for hitting a batch, payload, or rate limit, work through [Events not arriving](/docs/troubleshooting/events-not-arriving). If decisioning stops responding after many rapid calls, work through [Decisioning not firing](/docs/troubleshooting/decisioning-not-firing).
