Build a travel rewards app

A travel app turns a wallet into trips: which programmes the user's points move to, which credits and perks the cards carry, and which card to pay with abroad.

The plan you need

Pro plan and abovePro ($79/mo) returns every field and endpoint below.

Prototype on the Free plan: it returns each card's basic fields and top 3 reward rates. See what each plan returns.

Fields

  • name
  • reward_currency_name
  • foreign_transaction_fee
  • benefits
  • card_perks
  • statement_credits

Types and descriptions: the card object.

Endpoints

Going further

  • The per-card credits and perks endpoints on their ownGET /v1/cards/:slug/credits, GET /v1/cards/:slug/perksStarter plan and above
  • Alerts when a card's travel credit or fee changesPOST /v1/webhooksEnterprise plan

Displaying and caching the data

  • Cache what you fetch for as long as your plan is active (ISR, a database, a KV store); re-fetch on a schedule so changes reach your users. The data is re-checked against issuer sites every Friday, so a daily or weekly refresh is plenty.
  • Transfer ratios can differ by card within one programme; read a partner row's notes, which name the cards that transfer at another ratio.
  • Show the data to your own users. Don't re-serve it raw: no public API or feed of your own, no CSV or spreadsheet download, no bulk export. A backend that only your own site or app calls is fine.
  • Data fetched during the Starter trial is for evaluation only until the trial becomes a paid plan: build and test on it, publish once the plan is paid.

The full rules are in the Terms of Service.

Code

Runs on your own key (CARDAPI_API_KEY) and fetches at runtime: nothing here ships card data. Uses @cardapi/client 0.4.0 or later.

npm install @cardapi/client

import { CardAPI } from "@cardapi/client";

const api = new CardAPI({ apiKey: process.env.CARDAPI_API_KEY! });

export async function travelProfile(slug: string) {
  const [card, partners, credits] = await Promise.all([
    api.getCard(slug),
    api.getCardTransfers(slug),
    api.getCardCredits(slug),
  ]);
  return {
    card: card.name,
    noForeignFee: card.foreign_transaction_fee === 0,
    partners: partners.map((p) => ({
      programme: p.partner_program,
      ratio: `${p.transfer_ratio_from}:${p.transfer_ratio_to}`,
      notes: p.notes,
    })),
    credits: credits.map((c) => `${c.credit_name} (${c.credit_period})`),
  };
}