Skip to main content
Every Xquik API error returns a consistent JSON body with an error code. Use these codes to build reliable integrations with automatic recovery.

Error Codes

StatusCodeDescriptionRecommended Action
400invalid_inputRequest body failed validationFix the request body. Check required fields and types.
400invalid_idPath parameter is not a valid IDFix the path parameter. IDs are numeric strings.
401unauthenticatedMissing or invalid API keyCheck the x-api-key header. Regenerate the key if revoked.
403monitor_limit_reachedPlan monitor limit exceededDelete an existing monitor or add capacity ($10/month per extra monitor).
404not_foundResource does not existVerify the resource ID. It may belong to another account or have been deleted.
409monitor_already_existsDuplicate monitor for this X accountUse the existing monitor. Call Update Monitor to change event types.
429Rate limitedRetry with exponential backoff. Respect the Retry-After header.
500internal_errorServer errorRetry with backoff. Contact support if the error persists.
502stream_registration_failedUpstream stream registration failedRetry the request.
Response format:
{ "error": "error_code" }
Some errors include additional context:
{
  "error": "monitor_limit_reached",
  "limit": 1
}

Retry with Exponential Backoff

Retry only on 429 and 5xx responses. Use exponential backoff with random jitter to avoid thundering herds. Max 3 retries. Formula: delay = baseDelay * 2^attempt + random(0, jitter)
#!/bin/bash
# Retry wrapper for cURL requests
retry_request() {
  local url="$1"
  local max_retries=3
  local base_delay=1

  for attempt in $(seq 0 $max_retries); do
    response=$(curl -s -w "\n%{http_code}" "$url" \
      -H "x-api-key: xq_YOUR_KEY_HERE")

    status=$(echo "$response" | tail -1)
    body=$(echo "$response" | head -n -1)

    if [ "$status" -lt 429 ]; then
      echo "$body"
      return 0
    fi

    if [ "$status" -eq 429 ] || [ "$status" -ge 500 ]; then
      if [ "$attempt" -eq "$max_retries" ]; then
        echo "Max retries reached. Last status: $status" >&2
        return 1
      fi

      delay=$(echo "$base_delay * (2 ^ $attempt) + $RANDOM % 1000 / 1000" | bc -l)
      echo "Retry $((attempt + 1)) in ${delay}s (status $status)" >&2
      sleep "$delay"
    else
      echo "$body"
      return 1
    fi
  done
}

retry_request "https://xquik.com/api/v1/events?limit=10"

Rate Limit Handling

When you exceed the rate limit, Xquik returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait. Detecting rate limits:
SignalValue
HTTP status429
Retry-After headerSeconds until the limit resets (e.g. 2)
Recovery flow:
1

Detect the 429 status

Check the HTTP response status code before reading the body.
2

Read the Retry-After header

Parse the header value as an integer (seconds).
3

Wait the specified duration

Sleep for the full Retry-After duration before retrying.
4

Retry the request

Send the same request again. If it returns another 429, apply exponential backoff.
async function respectRateLimit(url, options = {}) {
  const response = await fetch(url, options);

  if (response.status === 429) {
    const retryAfter = parseInt(
      response.headers.get("Retry-After") || "1",
      10
    );
    console.log(`Rate limited. Waiting ${retryAfter}s...`);
    await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
    return fetch(url, options); // retry once
  }

  return response;
}

Best Practices

4xx errors (except 429) indicate a problem with your request. Fix the request before retrying. 5xx errors and 429 are transient — retry with backoff.
Always log the full error response including status code and error body. This makes it easy to diagnose issues in production.
monitor_already_exists is not a failure — the monitor you need already exists. List monitors to find it instead of treating this as an error.
Set a 30-second timeout on all API requests. If a request hangs, retry it rather than waiting indefinitely.
Creating a monitor for the same username returns 409. Deleting a non-existent resource returns 404. Both are safe to retry.