Documentation Index
Fetch the complete documentation index at: https://aptly-1c228e04.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
This recipe shows you how to pull all cards from a board and produce a summary report. The example groups cards by stage and calculates counts, but the same pattern works for any grouping or aggregation you need.
What you need
- Your API key and board ID from Card Sources > API
- Node.js 18 or later
Step 1: Fetch all cards from the board
async function getAllCards(boardId, apiKey) {
const allCards = [];
let page = 0;
while (true) {
const response = await fetch(
`https://app.getaptly.com/api/aptlet/${boardId}?page=${page}`,
{ headers: { "x-token": apiKey } }
);
const cards = await response.json();
if (cards.length === 0) break;
allCards.push(...cards);
page++;
}
return allCards;
}
Step 2: Group cards by stage
function groupByStage(cards) {
return cards.reduce((acc, card) => {
const stage = card.Stage || "No Stage";
if (!acc[stage]) acc[stage] = [];
acc[stage].push(card);
return acc;
}, {});
}
Step 3: Generate the report
async function runReport(boardId, apiKey) {
const cards = await getAllCards(boardId, apiKey);
const grouped = groupByStage(cards);
console.log(`\n===== Board Report =====`);
console.log(`Total cards: ${cards.length}`);
console.log(`Generated: ${new Date().toLocaleString()}\n`);
Object.entries(grouped)
.sort((a, b) => b[1].length - a[1].length)
.forEach(([stage, items]) => {
console.log(`${stage}: ${items.length} cards`);
});
}
runReport("YOUR_BOARD_ID", "YOUR_API_KEY");
Example output:
===== Board Report =====
Total cards: 143
Generated: 2/27/2026, 9:00:00 AM
Active: 61 cards
New Lead: 34 cards
In Progress: 28 cards
Completed: 15 cards
On Hold: 5 cards
Step 4: Export to CSV
To share the report or open it in a spreadsheet, write the results to a CSV file.
import { writeFileSync } from "fs";
function exportToCSV(cards, filename) {
if (cards.length === 0) return;
const headers = Object.keys(cards[0]).join(",");
const rows = cards.map((card) =>
Object.values(card)
.map((v) => `"${String(v ?? "").replace(/"/g, '""')}"`)
.join(",")
);
writeFileSync(filename, [headers, ...rows].join("\n"));
console.log(`Exported ${cards.length} cards to ${filename}`);
}
const cards = await getAllCards("YOUR_BOARD_ID", "YOUR_API_KEY");
exportToCSV(cards, "board-report.csv");
Variations
Count cards updated in the last 7 days
const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
const recentCards = cards.filter(
(card) => new Date(card.updatedAt).getTime() > sevenDaysAgo
);
console.log(`Cards updated in the last 7 days: ${recentCards.length}`);
Find cards missing a required field
const incomplete = cards.filter((card) => !card.Email);
console.log(`Cards missing an email address: ${incomplete.length}`);
incomplete.forEach((card) => console.log(` ${card.Name} (${card._id})`));
Next steps