Skip to content
Dashboard

Pagination

Navigate large result sets with page-and-limit pagination.

Query Parameters

The three list endpoints (/articles, /social/content, /projects) all accept the same two pagination parameters. There is no offset or cursor pagination.

ParameterTypeDefaultDescription
pageinteger1Page number, 1-indexed. Minimum 1.
limitinteger20Results per page. Minimum 1, maximum 100.

Values outside these ranges are rejected with a 400 VALIDATION_ERROR rather than being clamped.

Response Format

Every paginated response includes a pagination object alongside the data array, providing all the information you need to navigate through result pages.

200Paginated response
{
  "success": true,
  "data": [
    "..."
  ],
  "pagination": {
    "total": 142,
    "page": 2,
    "limit": 20,
    "total_pages": 8,
    "has_more": true
  },
  "meta": {
    "timestamp": "2026-02-01T12:00:00Z"
  }
}

Pagination Fields

FieldTypeDescription
totalintegerTotal number of matching records
pageintegerCurrent page number
limitintegerResults per page
total_pagesintegerTotal number of pages
has_morebooleanWhether more pages exist after the current one

Iterating All Pages

To fetch all records, loop through pages until has_more is false:

async function fetchAllArticles(apiKey) {
  const articles = [];
  let page = 1;
  let hasMore = true;

  while (hasMore) {
    const res = await fetch(
      `https://www.brainpercent.app/api/v1/articles?page=${page}&limit=100`,
      { headers: { 'Authorization': `Bearer ${apiKey}` } }
    );
    const { data, pagination } = await res.json();
    articles.push(...data);
    hasMore = pagination.has_more;
    page++;
  }

  return articles; // All articles
}

Sorting

Only /articles takes sort and order. The other two list endpoints always return newest first.

EndpointOrdering
/api/v1/articlessort: created_at (default), updated_at, title. order: asc or desc (default desc).
/api/v1/social/contentFixed: created_at descending
/api/v1/projectsFixed: created_at descending

Filters available alongside pagination: /articles takes status, project_id, and search; /social/content takes platform, status, article_id, and project_id; /projects takes status and search.

// Get newest articles first (default)
const res = await fetch(
  'https://www.brainpercent.app/api/v1/articles?sort=created_at&order=desc',
  { headers: { 'Authorization': 'Bearer bp_your_key' } }
);

// Get articles alphabetically
const res2 = await fetch(
  'https://www.brainpercent.app/api/v1/articles?sort=title&order=asc',
  { headers: { 'Authorization': 'Bearer bp_your_key' } }
);

Combining Filters with Pagination

Filter parameters can be combined with pagination and sorting to narrow down results efficiently:

// Get finished articles from a specific project, page 2.
// 'cms' is the completed status. There is no 'published' status.
const res = await fetch(
  'https://www.brainpercent.app/api/v1/articles?status=cms&project_id=d290f1ee-6c54-4b01-90e6-d701748f0851&page=2&limit=25&sort=updated_at&order=desc',
  { headers: { 'Authorization': 'Bearer bp_your_key' } }
);

// Social posts that already have an Instagram variant, newest first.
const social = await fetch(
  'https://www.brainpercent.app/api/v1/social/content?platform=instagram&status=ready&limit=50',
  { headers: { 'Authorization': 'Bearer bp_your_key' } }
);

Best Practices

  • Use limit=100 (maximum) when fetching all records to minimize requests
  • Always check has_more rather than comparing page to total_pages
  • Add a small delay between page requests to respect rate limits
  • Cache total counts if you only need them for display purposes
  • Use filters to reduce result sets before paginating