Limits & defaults
Know the number before you hit it: every default and ceiling Duraton applies to pagination, request size, retries, AI steps, and connections.
A reference for the numbers Duraton applies when you don't set one. Where a value is configurable, the option is linked.
Requests & pagination
| Limit | Value | Notes |
|---|---|---|
| Request body size | 1 MiB | Applies to every JSON request body and inbound webhook payload. Larger bodies are rejected. |
| Cursor page size | 30 default, 200 max | GET /runs, GET /webhook-deliveries, and GET /webhook-source-deliveries. Set limit to change it; over 200 is clamped to 200. |
| Log & list page size | 100 default, 1000 max | GET /events, /approvals, /control-actions, and a run's logs. Over 1000 is clamped to 1000. |
| Session page size | 100 default, 500 max | GET /sessions. Over 500 is clamped to 500. |
| Unpaged reads | whole list | A run's steps and scores take no limit - they return every row for that run. |
| Pagination cursor | X-Next-Cursor header | GET /runs, /webhook-deliveries, and /webhook-source-deliveries use keyset pagination; pass the returned cursor to fetch the next page. |
| Event name / id length | 256 characters | Applies to name, app, runner, targetApp, dedupeId, and session on POST /events. Over the bound returns 400. |
API rate limits
Duraton does not impose a fixed per-second request rate limit on the API. There is no requests/second
quota on POST /events or on the read endpoints, and no 429 Too Many Requests / Retry-After back-off
protocol to code against - a well-formed request is admitted regardless of how many preceded it. Two
real ceilings apply instead:
| Ceiling | Effect |
|---|---|
| Request body size (1 MiB) | A larger JSON body or inbound webhook payload is rejected outright (see above). |
| Usage / plan limit | When a workspace reaches its plan's metered ceiling the project is suspended, and subsequent run-starting calls are refused with 403 Forbidden rather than throttled. |
Suspension is the ceiling that actually gates throughput, and it is not a rate limit - it is a hard stop until usage falls back under the plan or the plan is raised. Its shape differs by endpoint:
POST /eventson a suspended project still returns202 Accepted, but starts no new run: the response carriessuspended: truewith norunId, and any in-flightwaitForEventwaiters are still woken. The event is recorded; only the fan-out into new runs is withheld.- Other run-creating actions (and cron-triggered runs) on a suspended project are refused with
403 Forbidden.
Because there is no request-rate throttle, protect a busy ingest path with your own client-side batching or concurrency limit; the durable back-pressure you can configure is per-workflow flow control (concurrency, throttle, rate-limit, debounce, batch), which shapes how fast admitted events turn into runs.
Retries & delivery
| Limit | Value | Configurable |
|---|---|---|
| Step retries | none by default (maxAttempts: 1) | Per workflow via retry. A failed step waits a backoff delay, then retries up to maxAttempts total. |
| Outbound webhook attempts | up to 5 | Duraton retries a failed delivery with a backoff between attempts, then marks it exhausted. |
| Outbound webhook timeout | 10s per attempt | A slower endpoint counts as a failed attempt. |
| Webhook signing | HMAC-SHA256 | The X-Duraton-Signature header on every inbound and outbound delivery. |
AI steps
| Default | Value | Option |
|---|---|---|
| Provider | anthropic | provider on step.ai.generate. |
| Re-asks on invalid output | 1 | reask; applies only when an output schema is set. |
| Inference cache TTL | 24 hours | cache - pass { ttlMs } to change it. |
| Inference cache eligibility | temperature set and <= 0.2 | The cache is a no-op when temperature is above 0.2 or left unset (a provider default is often non-deterministic), so only near-deterministic calls are reused. |
| Embedding batch size | 100 inputs per durable batch | batchSize on step.ai.embed. |
| Eval fan-out | 200 items per run | A dataset eval runs at most 200 items; a larger dataset is truncated to the first 200. |
Per-run and rolling-window AI spend ceilings are opt-in and unlimited by default - see
cap and budget.
Connection defaults
These are what the SDK uses when a value and its environment variable are both unset:
| Setting | Default | Environment variable |
|---|---|---|
url | none - set it to your Duraton base URL, shown in the console under API Keys | DURATON_URL |
apiKey | none - required on every request | DURATON_API_KEY |
| App | default | DURATON_APP |
| Runner heartbeat interval | 30s | - (the serve re-registration; a connect endpoint is refreshed on its socket heartbeat at the same cadence) |
| Runner liveness TTL | 90s since the last heartbeat | - (both transports; a runner past it shows as Stale and is listed with live: false) |
| Protocol version | 1 | - (sent as X-Duraton-Protocol; see the wire protocol) |