> For the complete documentation index, see [llms.txt](https://titan-exchange.gitbook.io/titan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://titan-exchange.gitbook.io/titan/developer-doc/special-order-types/reference/limits.md).

# Limits & Idempotency

Row caps, TTLs, per-cycle minimums, and the idempotency contract.

## Limits

| Limit                                | Value                                                                                                                                                                                                                                                                                     |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| List endpoints                       | At most **500 rows**, unless stated otherwise. Use `createdAtGte` / `createdAtLte` on `/partners/me/*` for older data.                                                                                                                                                                    |
| `GET /orders/pending/history`        | **50 rows** — the one exception to the 500 cap.                                                                                                                                                                                                                                           |
| SIWS message                         | Max **1024 bytes**; signed bytes must match the canonical form exactly (LF endings, trailing `\n` after `Nonce:`); `Issued At` within **±10 minutes**.                                                                                                                                    |
| Cycle frequency                      | Minimum **60 seconds** (`cycleFrequencySeconds`).                                                                                                                                                                                                                                         |
| Minimum notional                     | **$10 USD** by default, configurable per tenant. For DCA that's per cycle (`amountPerCycle`), enforced at create and whenever it changes. For trigger orders the same floor applies to the full `amount`. USDC/USDT count as $1.00; other mints are priced by the oracle at request time. |
| Trigger order fields                 | `priceDecimals` `0`–`18`. `trailingStopBps` `1`–`9999` (on `stop_loss`, `take_profit`, and the `oco` stop-loss leg). `expiresAt` must be in the future. OCO requires `stopLossPrice < takeProfitPrice`.                                                                                   |
| Pending order TTL                    | **5 minutes** between `intent` and `confirm`.                                                                                                                                                                                                                                             |
| Modification lock                    | **30 seconds** between a modify-intent returning `requiresTransaction: true` and `modify/confirm`. DCA only.                                                                                                                                                                              |
| Idempotency replay window            | **24 hours**. Only `2xx` responses are cached.                                                                                                                                                                                                                                            |
| Order-level withdrawal auto-recovery | A stuck `withdrawalStatus: pending` lock clears on its own within **\~8 minutes**. Call `…/withdraw/abandon` to release it immediately.                                                                                                                                                   |
| API key environment                  | A key is bound to exactly one environment (`staging` or `production`).                                                                                                                                                                                                                    |
| Rate limits                          | Configured per partner during onboarding.                                                                                                                                                                                                                                                 |

## Idempotency

Every authenticated `POST` under the user-scoped tier accepts an `X-Idempotency-Key` header — `/orders/intent`, `/orders/confirm`, `/dca/{id}/modify/confirm`, `/orders/{id}/cancel`, `/orders/{id}/withdraw`, `/orders/{id}/withdraw/confirm`, `/orders/{id}/withdraw/abandon`, `/orders/{id}/pause`, `/orders/{id}/resume`, `/orders/{id}/retry`, `/withdraw/transaction`, and `/withdraw/confirm`. The header is optional — omit it on first-fire calls; include it on calls you intend to retry.

`POST /partner/onboard` doesn't need a key — it's inherently idempotent, since re-calling with the same `sub` replays the same `userId` / `walletAddress`. Idempotency isn't applied to GET endpoints or partner-only endpoints.

**The rules:**

* A key is scoped per **(your tenant, end-user, key string)** — two different users sharing a key value don't collide.
* Same key **+ same body** → Titan replays the exact cached JSON response (with the original `2xx` status) for **24 hours**.
* Same key **+ different body** → `422 IDEMPOTENCY_KEY_REUSED`. Choose a fresh key.
* **Only `2xx` responses are cached.** If the first call returns `4xx` or `5xx`, the key isn't recorded — a retry with the same key runs the handler again. A failed `/orders/intent` (e.g. a bad mint) shouldn't be permanently bound to a request body.

Use a deterministic, client-side key per logical user action — `dca:create:<your-internal-order-id>:v1`. Don't randomize per network attempt; the whole point is that retries hash to the same key.

## Polling, not webhooks

Titan doesn't push state changes — there are no webhooks today. Poll the read endpoints while a user is looking at their orders, and follow the cadence guidance in [Lifecycle & Polling](/titan/developer-doc/special-order-types/guides/lifecycle.md). Trigger orders need a steadier cadence than DCA, because they can fire at any moment rather than on a known schedule.

## Related pages

* [Creating Orders](/titan/developer-doc/special-order-types/guides/creating-orders.md) — where idempotency keys matter most
* [Error Codes](/titan/developer-doc/special-order-types/reference/error-codes.md) — `IDEMPOTENCY_KEY_REUSED` and the retryable codes
* [Lifecycle & Polling](/titan/developer-doc/special-order-types/guides/lifecycle.md) — polling cadence and back-off
