Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xquik.com/llms.txt

Use this file to discover all available pages before exploring further.

Xquik enforces rate limits to ensure fair usage and platform stability. Limits are applied per user account using a fixed window counter.
Quick answer: 60 GET/1s, 30 POST/60s, 15 DELETE/60s per account. Hit the limit? Respect the Retry-After header. Avoid 429s? Use the client-side rate limiter below.

Rate limit tiers

Read

GET, HEAD, and OPTIONS share a limit of 60 requests per 1 second.

Write

POST, PUT, and PATCH share a limit of 30 requests per 60 seconds.

Delete

DELETE requests are limited to 15 requests per 60 seconds.

Action-specific limits

Some write endpoints have stricter limits that apply on top of the general write tier:

Connect account

POST /x/accounts is limited to 3 attempts per 15 minutes.

Follow

POST /x/users/{id}/follow is limited to 20 requests per 60 seconds and 400 per day.

How limits work

Xquik uses a fixed window counter:
1

Window starts on first request

The first request starts a 1-second read window or a 60-second write/delete window.
2

Each request increments the counter

Every request within the window increments the counter for its tier (read, write, or delete).
3

Counter resets after window expires

After that tier’s window expires, the counter returns to zero.
4

Requests rejected when limit is reached

If the counter exceeds the tier limit within a window, subsequent requests return 429 Too Many Requests until the window resets.
Read tier (60 per 1s):

Time 0.0s: [0/60]   -> Send 40 GET requests -> [40/60]
Time 0.5s: [40/60]  -> Send 20 GET requests -> [60/60] (limit reached)
Time 0.8s: [60/60]  -> GET request -> 429 (rejected, window active)
Time 1.0s: [0/60]   -> Window resets -> requests allowed again

Response headers

When you exceed the rate limit, the response includes:

Retry-After header

Retry-After is the wait time in seconds before retrying. Standard read throttles return Retry-After: 1. Write and delete throttles return Retry-After: 60. Account connection cooldowns return Retry-After: 900.

JSON retry field

The JSON body includes error: "rate_limit_exceeded" and retryAfter in seconds, so clients can back off even when they do not expose response headers directly.
Example 429 response:
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json

{ "error": "rate_limit_exceeded", "message": "Too many requests. Try again later.", "retryAfter": 1 }
Always respect the Retry-After header. Requests sent before the fixed window resets keep returning 429 until Retry-After elapses.

Client-side rate limiter

Prevent hitting server-side limits by implementing a client-side rate limiter. This is more efficient than relying on 429 responses and backoff.
class WindowRateLimiter {
  constructor(maxRequests, windowMs) {
    this.maxRequests = maxRequests;
    this.windowMs = windowMs;
    this.count = 0;
    this.windowStart = Date.now();
  }

  async acquire() {
    const now = Date.now();

    if (now - this.windowStart >= this.windowMs) {
      this.count = 0;
      this.windowStart = now;
    }

    if (this.count >= this.maxRequests) {
      const waitMs = this.windowMs - (now - this.windowStart);
      await new Promise((resolve) => setTimeout(resolve, waitMs));
      this.count = 0;
      this.windowStart = Date.now();
    }

    this.count += 1;
  }
}

// Read tier: 60 requests per 1s
const readLimiter = new WindowRateLimiter(60, 1_000);

async function apiRequest(url) {
  await readLimiter.acquire();
  return fetch(url, {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
}

Rate limiting libraries

Instead of building your own rate limiter, consider these battle-tested libraries:

Node.js libraries

Use bottleneck with npm install bottleneck, or p-limit with npm install p-limit.

Python library

Use ratelimit with pip install ratelimit.

Go library

Use rate with go get golang.org/x/time/rate.
bottleneck example
import Bottleneck from "bottleneck";

const limiter = new Bottleneck({
  reservoir: 60,            // 60 requests per read window
  reservoirRefreshAmount: 60,
  reservoirRefreshInterval: 1_000, // 1 second
  maxConcurrent: 5,
});

const response = await limiter.schedule(() =>
  fetch("https://xquik.com/api/v1/events?limit=50", {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  })
);

Best practices

Fetch events in larger pages (limit=100) instead of many small requests. 1 request for 100 events is better than 10 requests for 10 events each.
Webhooks deliver events in real time with zero polling overhead. You only receive traffic when something happens. See the webhooks overview.
Monitor and webhook configurations change infrequently. Cache GET responses for list endpoints and invalidate only after mutations (create, update, delete).
When you receive a 429, wait for the Retry-After duration. If the retry also fails, double the wait time. See the error handling guide for complete retry implementations.
Avoid sending all requests in a burst at the start of each window. Spread them evenly across each tier’s window to avoid hitting the limit early.

Error Handling

Retry strategies and error recovery patterns.

API Overview

Base URL, authentication, and conventions.
Last modified on May 17, 2026