Skip to main content
A raw statement line like AMZN MKTP US*XX1234 means nothing to the person reading it. Banking, expense, and budgeting apps earn trust by showing a merchant logo and a clean name instead. Your user opens their activity feed and recognizes every charge at a glance: the coffee, the ride, the payout. Each logo is a Logo API image URL built from the merchant’s domain, so there are no logo files to collect or host.

Demo

Here’s the feed rendering five sample transactions: The amounts are sample data, but every merchant logo loads live from img.logo.dev.

Build it with AI

Want merchant logos in your transaction feed? This prompt gives your AI coding tool everything it needs to build it in your framework.

Open in Cursor

Code

This example is in React, but you can get the same result in any frontend framework: each row is one image URL next to data you already have. Paste TransactionFeed.tsx, then render it as the Usage tab shows. Logos render at 40px from an 80px source, so they stay sharp on retina screens.
type Transaction = {
  merchant: string;
  domain: string;
  date: string;
  amount: number; // negative for charges, positive for credits
};

const usd = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
});

export function TransactionFeed({
  token,
  transactions,
}: {
  token: string;
  transactions: Transaction[];
}) {
  return (
    <ul className="max-w-md divide-y divide-zinc-950/5 dark:divide-white/5">
      {transactions.map((tx) => (
        <li
          className="flex items-center gap-3 py-3"
          key={`${tx.domain}-${tx.date}-${tx.amount}`}
        >
          <img
            alt={`${tx.merchant} logo`}
            className="h-10 w-10 rounded-full object-contain"
            height={40}
            loading="lazy"
            src={`https://img.logo.dev/${tx.domain}?token=${token}&format=webp&retina=true&size=80`}
            width={40}
          />
          <div className="min-w-0">
            <div className="truncate text-sm font-medium">{tx.merchant}</div>
            <div className="text-xs text-zinc-500">{tx.date}</div>
          </div>
          <div
            className={`ml-auto text-sm font-medium tabular-nums ${
              tx.amount > 0 ? "text-emerald-600" : ""
            }`}
          >
            {tx.amount > 0 ? "+" : ""}
            {usd.format(tx.amount)}
          </div>
        </li>
      ))}
    </ul>
  );
}
Your publishable key is built for client-side code, so you can ship it in the browser as-is.

How it works

  • Every merchant logo is one image URL. img.logo.dev/:domain returns the merchant’s logo, and query parameters handle the rest: size for dimensions, retina for sharp rendering, format=webp for weight. See all image parameters.
  • Unknown merchants still render. When Logo.dev doesn’t have a logo, it returns a generated monogram instead of a broken image, so a feed full of small or local merchants stays clean. See fallback images.
  • The CDN keeps long feeds fast. Logos load like any other cached image, so scrolling months of history costs nothing beyond normal image requests.
  • The layout is plain markup. Amounts line up in a steady column and logos load as rows scroll into view. The component above carries the details.

Make it your own

  • Start from raw statement strings. Resolve processor text like SBUX_STORE_321_NYC to a merchant with the Transaction API, currently in early access.
  • Look up logos by name. Have clean merchant names but no domains? Use name lookup or resolve names to domains with the Search API.
  • Restyle the logos. Add &greyscale=true for a muted feed or &theme=dark for dark backgrounds. See all image parameters.

Next steps

Transaction API

Identify merchants from raw card transaction strings.

Stock ticker logos

Build the same row pattern for trading and portfolio apps.