All NueForm API endpoints that return lists of resources support page-based pagination. This guide covers the query parameters, response format, and patterns for iterating through all results.
Query Parameters
Control pagination with two query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | The page number to retrieve (1-indexed). |
per_page | integer | 20 | The number of items per page. Minimum: 1, maximum: 100. |
If per_page exceeds 100, the API automatically caps it at 100. Values less than 1 default to 1.
Example Request
/api/v1/forms?page=2&per_page=25curl -X GET "https://app.nueform.com/api/v1/forms?page=2&per_page=25" \
-H "Authorization: Bearer nf_your_api_key_here"
Response Format
Paginated responses include a meta object alongside the data array:
{
"data": [
{
"id": "clx1abc2d3e4f5g6h7i8j9k0",
"title": "Customer Feedback",
"status": "published",
"created_at": "2026-01-15T09:30:00.000Z"
},
{
"id": "clx2def3g4h5i6j7k8l9m0n1",
"title": "Employee Survey",
"status": "draft",
"created_at": "2026-01-20T14:00:00.000Z"
}
],
"meta": {
"page": 2,
"per_page": 25,
"total": 73,
"total_pages": 3
}
}
Meta Fields
| Field | Type | Description |
|---|---|---|
page | integer | The current page number. |
per_page | integer | The number of items per page (as applied). |
total | integer | The total number of items across all pages. |
total_pages | integer | The total number of pages (calculated as ceil(total / per_page)). |
Iterating Through All Pages
When you need to retrieve every item from a list endpoint, iterate through pages until page exceeds total_pages.
JavaScript
async function fetchAllForms() {
const allForms = [];
let page = 1;
let totalPages = 1;
do {
const response = await fetch(
`https://app.nueform.com/api/v1/forms?page=${page}&per_page=100`,
{
headers: {
"Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
},
}
);
const { data, meta } = await response.json();
allForms.push(...data);
totalPages = meta.total_pages;
page++;
} while (page <= totalPages);
console.log(`Fetched ${allForms.length} forms in total.`);
return allForms;
}
Python
import os
import requests
API_KEY = os.environ["NUEFORM_API_KEY"]
BASE_URL = "https://app.nueform.com/api/v1"
def fetch_all_forms():
all_forms = []
page = 1
total_pages = 1
while page <= total_pages:
response = requests.get(
f"{BASE_URL}/forms",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"page": page, "per_page": 100},
)
body = response.json()
all_forms.extend(body["data"])
total_pages = body["meta"]["total_pages"]
page += 1
print(f"Fetched {len(all_forms)} forms in total.")
return all_forms
Async Generator (JavaScript)
For large datasets, use an async generator to process items as they arrive rather than loading everything into memory:
async function* paginatedForms(perPage = 100) {
let page = 1;
let totalPages = 1;
do {
const response = await fetch(
`https://app.nueform.com/api/v1/forms?page=${page}&per_page=${perPage}`,
{
headers: {
"Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
},
}
);
const { data, meta } = await response.json();
totalPages = meta.total_pages;
for (const form of data) {
yield form;
}
page++;
} while (page <= totalPages);
}
// Usage
for await (const form of paginatedForms()) {
console.log(`Processing: ${form.title}`);
}
Edge Cases
Empty Results
If no items match the query, the API returns an empty data array with total: 0:
{
"data": [],
"meta": {
"page": 1,
"per_page": 20,
"total": 0,
"total_pages": 0
}
}
Page Beyond Total
Requesting a page number beyond total_pages returns an empty data array. The meta values still reflect the overall collection:
{
"data": [],
"meta": {
"page": 10,
"per_page": 20,
"total": 73,
"total_pages": 4
}
}
Invalid Parameters
Invalid pagination parameters are handled gracefully:
| Input | Behavior |
|---|---|
page=0 or page=-1 | Defaults to 1 |
page=abc | Defaults to 1 |
per_page=0 or per_page=-5 | Defaults to 1 |
per_page=500 | Capped at 100 |
per_page=abc | Defaults to 20 |
Best Practices
Use the maximum per_page for bulk retrieval
When fetching all resources, set per_page=100 to minimize the number of API calls. Each call counts against your rate limit.
Check total_pages before iterating
Always read total_pages from the meta object to determine when to stop. Do not iterate indefinitely or assume a fixed number of pages.
Add a delay between pages for large datasets
If you are fetching many pages, add a small delay between requests to avoid hitting rate limits:
// Add a 200ms delay between page requests
await new Promise((resolve) => setTimeout(resolve, 200));
Cache the total when appropriate
If you only need the total count (e.g., to display "47 forms"), request per_page=1 and read meta.total to minimize data transfer:
curl -X GET "https://app.nueform.com/api/v1/forms?per_page=1" \
-H "Authorization: Bearer nf_your_api_key_here"
Pagination results reflect the state of the data at the time of each request. If items are created or deleted between page requests, you may see duplicates or miss items. For consistent snapshots, fetch all pages quickly or use webhooks for real-time updates.