NueForm

Rate Limits

Understand NueForm API rate limits, how to monitor your usage with response headers, and best practices for staying within your quota.

The NueForm API enforces rate limits to ensure fair usage and platform stability. Limits are applied per user account using a sliding window of 60 seconds.

Limits by Plan

PlanRequests per MinuteWindow
Pro10060 seconds (sliding)
Enterprise50060 seconds (sliding)

Rate limits are applied at the account level, not per API key. If you have multiple keys, they share the same rate limit quota.

Rate Limit Headers

Every API response includes rate limit headers so you can monitor your usage in real time:

HeaderDescriptionExample
X-RateLimit-LimitMaximum requests allowed per window100
X-RateLimit-RemainingRequests remaining in the current window87
X-RateLimit-ResetISO 8601 timestamp when the window resets2026-02-28T14:30:45.000Z

Example response headers:

text
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 2026-02-28T14:30:45.000Z

When You Are Rate Limited

If you exceed your rate limit, the API returns a 429 Too Many Requests response. The response includes the standard rate limit headers plus a Retry-After header indicating how many seconds to wait before retrying.

Response

json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Please try again later.",
    "status": 429
  }
}

Headers on a 429 Response

text
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-02-28T14:31:12.000Z
Retry-After: 27

The Retry-After value is the number of seconds until the oldest request in your current window expires and capacity frees up.

Monitoring Usage

Use the rate limit headers proactively to avoid hitting the limit:

JavaScript

javascript
async function callApi(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    headers: {
      "Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  // Log rate limit status
  const remaining = response.headers.get("X-RateLimit-Remaining");
  const limit = response.headers.get("X-RateLimit-Limit");
  console.log(`Rate limit: ${remaining}/${limit} remaining`);

  if (response.status === 429) {
    const retryAfter = parseInt(response.headers.get("Retry-After"), 10);
    console.warn(`Rate limited. Retrying in ${retryAfter} seconds...`);
    await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
    return callApi(url, options); // Retry
  }

  return response;
}

Python

python
import os
import time
import requests

API_KEY = os.environ["NUEFORM_API_KEY"]
BASE_URL = "https://app.nueform.com/api/v1"

def call_api(path, method="GET", **kwargs):
    url = f"{BASE_URL}{path}"
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }

    response = requests.request(method, url, headers=headers, **kwargs)

    # Log rate limit status
    remaining = response.headers.get("X-RateLimit-Remaining")
    limit = response.headers.get("X-RateLimit-Limit")
    print(f"Rate limit: {remaining}/{limit} remaining")

    if response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 5))
        print(f"Rate limited. Retrying in {retry_after} seconds...")
        time.sleep(retry_after)
        return call_api(path, method, **kwargs)  # Retry

    return response

Best Practices

Implement exponential backoff

When you receive a 429 response, use exponential backoff rather than retrying immediately. Start with the Retry-After value and increase the delay with each subsequent retry.

javascript
async function fetchWithBackoff(url, options = {}, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, {
      ...options,
      headers: {
        "Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
        "Content-Type": "application/json",
        ...options.headers,
      },
    });

    if (response.status !== 429) {
      return response;
    }

    if (attempt === maxRetries) {
      throw new Error("Max retries exceeded due to rate limiting");
    }

    const retryAfter = parseInt(
      response.headers.get("Retry-After") || "5",
      10
    );
    const backoff = retryAfter * Math.pow(2, attempt);
    console.warn(`Rate limited. Retry attempt ${attempt + 1} in ${backoff}s`);
    await new Promise((resolve) => setTimeout(resolve, backoff * 1000));
  }
}

Cache responses

Avoid making redundant API calls by caching responses locally. Form definitions and theme configurations change infrequently and are good candidates for caching.

javascript
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function getCachedForm(formId) {
  const cacheKey = `form_${formId}`;
  const cached = cache.get(cacheKey);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const response = await fetch(
    `https://app.nueform.com/api/v1/forms/${formId}`,
    {
      headers: {
        "Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
      },
    }
  );

  const { data } = await response.json();
  cache.set(cacheKey, { data, timestamp: Date.now() });
  return data;
}

Use webhooks for real-time data

Instead of polling the API for new form responses, set up webhooks to receive notifications when submissions arrive. This eliminates repetitive polling requests and delivers data faster.

Batch operations when possible

If you need to retrieve multiple resources, use list endpoints with pagination rather than making individual requests for each resource. A single call to

GET/api/v1/forms?per_page=100
is far more efficient than 100 separate calls.

Monitor the X-RateLimit-Remaining header

Track your remaining quota and throttle your requests before hitting the limit. If X-RateLimit-Remaining drops below 10, consider adding a short delay between requests.

Rate limits protect the platform for all users. Applications that consistently exceed rate limits or attempt to circumvent them may have their API access suspended. If you need higher limits, consider upgrading to the Enterprise plan or contacting support.

Upgrading Your Rate Limit

If you need more than 100 requests per minute, upgrade to the Enterprise plan for 500 requests per minute. For limits beyond Enterprise, contact our sales team to discuss custom arrangements.

PlanRate LimitPrice
Pro100 req/min$29/month
Enterprise500 req/min$99/month
CustomNegotiableContact sales
Last updated: July 9, 2026