nodestash

Rate Limits

Understand and handle API rate limits

nodestash uses a two-tier rate limiting system: daily limits and per-second burst limits. Both are enforced per workspace.

Rate Limit Tiers

PlanDaily LimitBurst LimitPrice
Free1,000 requests5 req/s$0
Starter25,000 requests25 req/s
Pro250,000 requests50 req/s
Scale2,000,000 requests200 req/s
EnterpriseUnlimited500 req/sCustom

Daily limits reset at midnight UTC.

Response Headers

Every API response includes rate limit information:

HeaderDescriptionExample
X-RateLimit-LimitDaily request limit1000
X-RateLimit-RemainingRemaining daily requests742
X-RateLimit-ResetUnix timestamp when daily limit resets1706140800
X-RateLimit-Burst-LimitPer-second burst limit5
X-RateLimit-Burst-RemainingRemaining burst capacity3
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 742
X-RateLimit-Reset: 1706140800
X-RateLimit-Burst-Limit: 5
X-RateLimit-Burst-Remaining: 3
X-Request-Id: req_abc123def456ghi789jkl012

Handling 429 Responses

When you exceed a rate limit, the API returns a 429 Too Many Requests response with a Retry-After header:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Per-second burst limit of 5 requests exceeded for the Free plan.",
    "retry_after": 1,
    "upgrade_url": "https://nodestash.io/pricing"
  },
  "meta": {
    "request_id": "req_abc123def456ghi789jkl012"
  }
}

Implementing Retry Logic

# Check for 429 and use Retry-After header
response=$(curl -s -w "\n%{http_code}" \
  https://api.nodestash.io/v1/contacts \
  -H "Authorization: Bearer $NODESTASH_API_KEY")

status=$(echo "$response" | tail -1)
if [ "$status" = "429" ]; then
  retry_after=$(echo "$response" | head -1 | jq -r '.error.retry_after')
  echo "Rate limited. Retrying in ${retry_after}s..."
  sleep "$retry_after"
fi
// The SDK handles retries automatically.
// Configure max retries when initializing:
const client = new NodeStash({
  apiKey: 'nds_live_...',
  maxRetries: 3, // default: 3
})

// The SDK will:
// 1. Respect Retry-After headers
// 2. Fall back to exponential backoff
// 3. Retry up to maxRetries times
// 4. Throw RateLimitError if all retries fail

try {
  const contacts = await client.contacts.list()
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Rate limited after all retries. Wait ${error.retryAfter}s`)
  }
}

SDK Auto-Retry Behavior

The TypeScript SDK automatically retries rate-limited requests with exponential backoff:

AttemptDelay
1st retry1,000 ms (or Retry-After value)
2nd retry2,000 ms
3rd retry4,000 ms

The maximum backoff is capped at 10 seconds. After exhausting all retries, the SDK throws a RateLimitError.

Best Practices

  • Monitor headers — track X-RateLimit-Remaining to avoid hitting limits
  • Use bulk operations — where possible, batch your requests
  • Cache responses — reduce redundant API calls
  • Implement backoff — use exponential backoff on 429 responses (the SDK does this automatically)
  • Upgrade your plan — if you consistently hit limits, consider upgrading

On this page