429 Too Many Requests response.
Default Limits by Endpoint
Different endpoint categories carry different default limits, reflecting the relative cost of each operation.Rate limits are tracked per API key. If you run multiple agents sharing one key, their requests all count toward the same bucket. Use a dedicated key per agent to isolate rate limits.
The 429 Response
When you exceed a rate limit, the daemon returns429 Too Many Requests with a Retry-After header and a structured JSON body:
retry_after_ms (or the Retry-After header in seconds) and wait at least that long before retrying. Sending requests immediately after a 429 wastes your token budget and prolongs the throttle window.
Retry Strategy
Use exponential backoff when handling429 responses. This prevents a flood of retries from cascading into further throttling.
- Python SDK
- curl / shell
- Python (raw requests)
The Python SDK raises
NSPRateLimitError on a 429 response. The retry_after attribute contains the wait time in seconds.How the Python SDK Surfaces Rate Limit Errors
NSPRateLimitError is raised any time the daemon responds with 429. The exception carries the following fields:
Configuring Rate Limits in axon.toml
Adjust the defaults by editing the[rate_limit] section in axon.toml:
Changes to
axon.toml take effect on daemon restart. Unlike axon_keys.json, the rate limit configuration is not hot-reloaded.Best Practices
Use WebSocket streaming instead of polling
The
/watch WebSocket stream is not rate-limited and delivers state-change events as they happen. Replace any tight GET /state polling loop with a WebSocket subscription to stay well within limits.Batch state reads
A single
GET /state call returns all state keys for an app. If your agent needs values from five fields, read them all in one request instead of five — every request counts against the same bucket.Respect the Retry-After header
The daemon tells you exactly how long to wait. Honouring that value avoids wasting additional tokens on requests that will also be rejected.
Raise limits only for known workloads
Increase
action_per_second in axon.toml only when you have profiled your agent and confirmed it genuinely needs higher throughput — lower limits reduce blast radius if agent code loops unexpectedly.