Skip to main content

Overview

This recipe shows you how to retrieve cards from a board and filter them by field values on the client side.
The Aptly API does not currently support server-side query parameters for filtering. Filtering is done after fetching the full data set. For large boards, consider using webhooks to maintain a local copy of the data that you can query directly.

What you need

  • Your API key and board ID from Card Sources > API
  • The field name you want to filter on (fetch the schema to confirm exact names)

Step 1: Fetch all cards

Use the pagination pattern to retrieve every card 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: Filter by a single field

const cards = await getAllCards("YOUR_BOARD_ID", "YOUR_API_KEY");

// Filter by stage
const activeCards = cards.filter((card) => card.Stage === "Active");
console.log(`Active cards: ${activeCards.length}`);

Step 3: Filter by multiple fields

const filtered = cards.filter(
  (card) => card.Stage === "Active" && card.Unit !== undefined
);
console.log(`Active cards with a unit assigned: ${filtered.length}`);

Step 4: Filter by a partial string match

const search = "smith";
const results = cards.filter((card) =>
  card.Name?.toLowerCase().includes(search)
);
console.log(`Cards matching "${search}":`, results.map((c) => c.Name));

Step 5: Group results by a field value

const byStage = cards.reduce((acc, card) => {
  const stage = card.Stage || "No Stage";
  if (!acc[stage]) acc[stage] = [];
  acc[stage].push(card);
  return acc;
}, {});

Object.entries(byStage).forEach(([stage, items]) => {
  console.log(`${stage}: ${items.length} cards`);
});

Things to watch out for

  • Field names are case-sensitive. card.stage will always be undefined if the field is named Stage on the board.
  • Cards with no value for a field will have that key missing entirely from the object, not set to null. Use optional chaining (card.Email?.toLowerCase()) to avoid errors.

Next steps