Skip to content
Hightop docs header art
Hightop
API and Integrations

Rate Limits#

Every Agent API endpoint belongs to a rate-limit class. Limits are enforced per agent over a rolling window. The live, authoritative state for your agent is always available from GET /v1/agent/self/usage (see the Endpoints catalog); the values below are the current defaults.

Classes#

ClassLimitBurstWindowApplies to
read60010060sGET reads (balances, operations, account, activity)
write602060sMutations (payments, conversions, earn, borrow, withdrawals)
simulate1203060sPOST /v1/agent/simulate and other dry-run checks
webhook_management10560sAll /v1/agent/webhooks routes — list and get and create/update/delete/rotate/test (only GET .../deliveries is charged as read)
bulk_write20560sReserved for batched mutations

The class for each endpoint is shown in the Endpoints reference and in the generated SDK, CLI, and MCP references.

Headers#

Every response carries the current window state:

text
example
X-RateLimit-Limit: <max requests in the window>
X-RateLimit-Remaining: <requests left>
X-RateLimit-Reset: <ISO 8601 reset time>
X-RateLimit-Window-Seconds: <window length>

When you exceed a class limit the API additionally returns HTTP 429 with the rate_limited error code and a Retry-After header (seconds).

Handling 429#

Back off for at least the Retry-After duration before retrying.

  • Treat Retry-After as the minimum wait, and add jitter when running many agents.
  • The error details include limit_count (the effective limit, a number) and attempted_count.
  • The SDK surfaces this as HightopAgentSDKError with code === 'rate_limited'; the CLI exits non-zero and prints the error.
typescript
example
import { getAgentApiErrorByCode } from '@hightop/sdk'
 
const rateLimit = getAgentApiErrorByCode(error, 'rate_limited')
if (rateLimit) {
  // back off for Retry-After, then retry the same logical request with the same key
  console.log(rateLimit.details.limit_count)
}

A 429 itself creates no idempotency record (see Conventions), so there is nothing to "replay". Retrying the same logical request with the same idempotency key and body is still the right move: it avoids creating a duplicate if an earlier attempt did land.

Reducing pressure#

  • Prefer a single read poll loop with backoff over tight polling. For operation status, use the SDK operations.wait() helper or the CLI --wait flag, which poll efficiently.
  • Batch related reads where an endpoint supports it, and use pagination cursors rather than re-fetching whole lists.
  • Keep webhook management (a low-limit class) to setup and rotation, not steady-state traffic — subscribe once and let deliveries flow. See Webhooks.

Next#

Previous

Capabilities

Next

OpenAPI and Artifacts