v1 · Public API

SuperPay Checkout APIOne call, the top 3 cards.

The SuperPay Checkout API ranks the top 3 credit cards by reward rate for a given purchase. It powers the <script>-tag widget that turns your checkout into an instant top-3 cards prompt (stacked, tappable rows, best first) — and it can be called server-to-server too.

Pricing — Card-Recommendation Widget. 100% free for merchants — forever. No fees, no rev share, no contract minimums. SuperPay treats the widget as a value-add at checkout and a brand / shopper-acquisition channel, not a revenue line.
Ready to integrate? Apply for a live API key → — we review applications within 1 business day. Or email hello@superpayrewards.com for an instant sandbox key to start building now. Read the Merchant Partner Guide (PDF) for the full integration walkthrough and code samples.

Authentication

Every request needs a merchant API key issued by SuperPay. Send it in either of two headers:

Authorization: Bearer sp_live_xxxxxxxx_…
X-SuperPay-Key: sp_live_xxxxxxxx_…

Keys are sp_live_ + 8 hex characters + _ + 48 hex characters. Treat keys like passwords: never commit them to client-side source control. The drop-in widget script is the one exception — it's designed to ship the key in the page so a browser can call /v1/recommend directly.

Origin allowlist

When SuperPay issues your key we register the exact origins (e.g. https://shop.example.com) you'll mount the widget on. Browser requests from any other origin are rejected with HTTP 403 ORIGIN_NOT_ALLOWED. Server-to-server calls (no Origin header) are not subject to this check — the API key alone authorizes them.

POST /v1/recommend

Returns the top 3 cards from our ~320-card catalog for the requested category in top_cards (ordered best first), each with an estimated reward in cents (informational — issued by the shopper's card issuer, not by SuperPay), and a SuperPay signup_url the shopper can tap to install the SuperPay app and get the same recommendations everywhere they shop.

Ranking. Cards are sorted by effective reward rate for the requested category (descending). On ties: the card more SuperPay users currently hold wins (popularity proxy from our wallet snapshot, recomputed daily); on remaining ties the lower-annual-fee card wins.
Deprecated fields. The legacy single-card top_card and lighter alternates[] fields are still populated for backwards compatibility but will be removed one release after this one ships. Please migrate to top_cards[] — it carries the full data for every rank, including the previously-best card at top_cards[0].
v0 is anonymous-only. Recommendations are computed against the public catalog; we do not accept a shopper identifier on this endpoint. A future release will support personalized lookups against a shopper's own linked card portfolio, but only behind a real shopper-authorization flow — not a merchant API key. SuperPay does not hold funds or store value on a shopper's behalf; rewards are always awarded by the shopper's card issuer.

Request body

FieldTypeRequiredNotes
amountnumberyesUSD, e.g. 87.45
mccstringpreferredISO 18245 4-digit code. Takes precedence over category when both are supplied.
categorystringfallbackUsed only when MCC is missing or unmapped. One of dining, groceries, gas, travel, entertainment, online_shopping, streaming, drugstores, home_improvement, transit, shopping, other
merchant_namestringrecommendedDisplay name, e.g. "Whole Foods Market"

Example — curl

curl -X POST https://www.superpayrewards.com/v1/recommend \
  -H "Authorization: Bearer sp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 87.45,
    "mcc": "5411",
    "merchant_name": "Whole Foods Market"
  }'

Response

{
  "recommendation_id": "9f8…",
  "anonymous": true,
  "category": "groceries",
  "amount_cents": 8745,
  "top_cards": [
    {
      "source": "catalog",
      "rank": 1,
      "id": "amex_blue_cash_preferred",
      "name": "Blue Cash Preferred® Card from American Express",
      "issuer": "American Express",
      "network": "American Express",
      "reward_rate": 6,
      "reward_type": "cashback",
      "estimated_reward_cents": 524,
      "estimated_reward_display": "$5.24",
      "reason": "6% on groceries",
      "image_url": "https://…",
      "apply_url": "https://…"
    },
    { "rank": 2, "id": "amex_gold", … },
    { "rank": 3, "id": "citi_custom_cash", … }
  ],
  "top_card":   { /* DEPRECATED — same as top_cards[0]. Will be removed one release after this one. */ },
  "alternates": [ /* DEPRECATED — top_cards[1..] in lighter shape. Will be removed one release after this one. */ ],
  "signup_url": "https://www.superpayrewards.com/r/install/checkout_widget?utm_source=merchant&utm_medium=checkout_widget",
  "display": {
    "headline": "Top 3 cards for this purchase",
    "subline": "Top pick: Blue Cash Preferred · 6% back"
  }
}

Drop-in widget

Paste this into your checkout page. Render the <div> wherever you want the top-3 cards widget to appear and load /v1/widget.js once, anywhere on the page:

<div data-superpay-recommend
     data-amount="87.45"
     data-mcc="5411"
     data-merchant="Whole Foods Market"
     data-theme="light"
     data-superpay-effective-cost-target="#sp-effective-cost"></div>

<!-- Optional: empty target the widget fills with
     "Effective cost with SuperPay: $X.XX — after $Y.YY rewards".
     Place under your Pay / Place Order button. -->
<div id="sp-effective-cost"></div>

<script src="https://www.superpayrewards.com/v1/widget.js" data-key="sp_live_…" async></script>

The widget renders a small card up to 360px wide containing the top 3 recommended cards as stacked rows, themes light/dark via data-theme, and never breaks the merchant's checkout (it silently no-ops on any error). The CORS-allowed JS calls /v1/recommend directly from the browser. The SuperPay-branded header is a single tap target pointing at signup_url so a shopper without SuperPay can install the app; each card row is its own tap target pointing at that card's apply_url. Rewards themselves are always awarded by the shopper's card issuer — SuperPay does not hold funds or pay out rewards.

Optional: effective-cost line

Pass an extra data-superpay-effective-cost-target="<css-selector>" on the mount <div> and place an empty target element (typically directly under your Pay / Place Order button). The widget will fill that element with a single muted line: "Effective cost with SuperPay: $X.XX — after $Y.YY rewards". The line is strictly gated so it never lies to a shopper — it renders only when the top pick is a cashback card with a positive estimated reward, a known cart total, and the resulting effective cost is non-negative (rewards never shown as exceeding the order total). Points/miles cards, $0 reward estimates, missing amounts, or a negative effective cost suppress the line silently.

Errors & rate limits

StatusCodeMeaning
400INVALID_AMOUNTamount missing or out of range
401MISSING_API_KEY / INVALID_API_KEY / API_KEY_REVOKEDauth failed
200top_cards: []no catalog card matches the requested category and merchant — the widget hides itself silently. Replaced the legacy 404 NO_RECOMMENDATION response in Task #739.
429RATE_LIMITEDover 300 requests per minute on this key
500INTERNAL_ERRORSuperPay-side failure — safe to retry

Rate limits are per API key. Headers X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After are set on every response.

Bank Partner API

The Bank Partner API is a private B2B surface for financial institutions. It lets your engineering team surface card recommendations from your own issued portfolio at checkout — only cards your institution has authorized appear in results. Requires a sp_bank_ key issued after your institution's application is reviewed.

Apply for access. Request a Bank Partner key → — review typically takes 1 business day. A sandbox key (prefix sp_bank_) is available immediately on the Bank Partner portal.

Authentication

Bank keys use the prefix sp_bank_ and are sent the same way as merchant keys:

Authorization: Bearer sp_bank_xxxxxxxx_…

POST /v1/bank/recommend

Returns the best card(s) from your authorized portfolio for a given purchase. Same request shape as /v1/recommend, plus an optional card_product_ids array to scope results to a subset of your portfolio.

Request body (additional bank-specific fields)

FieldTypeNotes
amountnumberRequired. USD purchase amount.
mccstringPreferred. 4-digit ISO 18245 code.
merchant_namestringRecommended display name.
card_product_idsstring[]Optional. Restrict results to this subset of your portfolio (e.g. a specific customer segment). Omit = all authorized cards.

Example — curl

curl -X POST https://www.superpayrewards.com/v1/bank/recommend \
  -H "Authorization: Bearer sp_bank_…" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 87.45,
    "mcc": "5411",
    "merchant_name": "Whole Foods Market",
    "card_product_ids": ["amex_gold", "chase_sapphire_preferred"]
  }'

Example — JavaScript

const res = await fetch('https://www.superpayrewards.com/v1/bank/recommend', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sp_bank_…',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ amount: 87.45, mcc: '5411', card_product_ids: ['amex_gold'] }),
});
const { top_cards, category, portfolio_scoped } = await res.json();

Response

{
  "recommendation_id": "9f8…",
  "category": "groceries",
  "amount_cents": 8745,
  "portfolio_scoped": true,
  "top_cards": [
    {
      "rank": 1, "id": "amex_gold",
      "name": "American Express Gold Card",
      "issuer": "American Express",
      "reward_rate": 4, "reward_type": "points",
      "estimated_reward_cents": 349,
      "reason": "4% on groceries"
    }
  ]
}

POST /v1/bank/portfolio

Analyzes a set of card product IDs against a monthly spend profile and returns per-category winner allocation, gap analysis vs. the broader market, and projected annual rewards per card.

Request body

FieldTypeNotes
card_product_idsstring[]Required. SuperPay card product IDs to analyze.
spend_profileobjectRequired. Category → monthly USD spend. E.g. {"groceries":800,"dining":400}. Keys: groceries, dining, gas, travel, entertainment, streaming, other. Values: positive finite USD amounts. Omitting this field returns 400 MISSING_SPEND_PROFILE.

Example — curl

curl -X POST https://www.superpayrewards.com/v1/bank/portfolio \
  -H "Authorization: Bearer sp_bank_…" \
  -H "Content-Type: application/json" \
  -d '{
    "card_product_ids": ["amex_gold", "chase_sapphire_preferred", "citi_double_cash"],
    "spend_profile": { "groceries": 800, "dining": 400, "travel": 600 }
  }'

Example — Python

import requests

r = requests.post(
    'https://www.superpayrewards.com/v1/bank/portfolio',
    headers={'Authorization': 'Bearer sp_bank_…'},
    json={
        'card_product_ids': ['amex_gold', 'chase_sapphire_preferred'],
        'spend_profile': {'groceries': 800, 'dining': 400},
    }
)
data = r.json()
for cat, winner in data['optimal_allocation'].items():
    print(f"{cat}: {winner['card_name']} @ {winner['reward_rate']}%")

Response

{
  "analysis_id": "…",
  "portfolio_card_count": 3,
  "cards": [
    {
      "id": "amex_gold", "name": "American Express Gold Card",
      "found_in_catalog": true, "best_category": "dining",
      "best_rate": 4, "projected_annual_reward_cents": 57600
    }
  ],
  "optimal_allocation": {
    "groceries": { "card_id": "amex_gold", "card_name": "American Express Gold Card", "reward_rate": 4, "estimated_monthly_reward_cents": 3200 },
    "dining":    { "card_id": "amex_gold", "reward_rate": 4, "estimated_monthly_reward_cents": 1600 },
    "travel":    { "card_id": "chase_sapphire_preferred", "reward_rate": 3, "estimated_monthly_reward_cents": 1800 }
  },
  "summary": {
    "total_monthly_portfolio_reward_cents": 6600,
    "total_projected_annual_reward_cents": 79200,
    "total_monthly_gap_cents": 1200,
    "coverage_rate": 1.0
  },
  "top_gaps": [ … ],
  "by_category": [ … ]
}

Bank API error codes

StatusCodeMeaning
400NO_CARDS_IN_PORTFOLIOThe requested card_product_ids have no cards with a bonus in the requested category. Widen the portfolio or try a different category.
400MISSING_CARD_IDScard_product_ids missing or empty on /v1/bank/portfolio.
400MISSING_SPEND_PROFILEspend_profile missing on /v1/bank/portfolio. Must be a non-empty object of category → monthly USD spend.
400INVALID_SPEND_PROFILEspend_profile contains non-finite values (Infinity, NaN, or negative). All spend values must be positive finite numbers.
401MISSING_API_KEY / INVALID_API_KEYAuth failed — check your sp_bank_ key.
403ACCESS_DENIEDYour key's access level does not include this endpoint.
403ORIGIN_NOT_ALLOWEDThe Origin header is not in your key's allowed origins list. Remove the Origin header for server-to-server calls, or contact us to add the origin.
429RATE_LIMITEDOver 300 req/min on this key.
500INTERNAL_ERRORSuperPay-side failure — safe to retry with exponential back-off.

Read the full Bank Partner Guide (PDF) for onboarding steps, portfolio ID lookup, and integration best practices.

Brand assets

Sandbox vs live keys

SuperPay issues two types of API keys:

Key typePrefixHow to getRate limitBehavior
Sandboxsp_test_Email hello@superpayrewards.com300 req/minReturns static mock recommendations; no analytics tracked. Use for development & testing.
Livesp_live_Apply on the Developers page300 req/minReturns real catalog recommendations; usage logged and visible in your merchant dashboard.

Sandbox keys are available immediately on request. Live keys require a brief application review (typically < 1 business day) to ensure origin allowlists and integration quality.

Get an API key

Ready to integrate? Apply for a live API key →

Submit your business name, contact email, store origins, and a brief description of your integration. We'll verify your email and review your application — you'll receive your sp_live_… key via email once approved, typically within 1 business day.

Just exploring? Email hello@superpayrewards.com for a sandbox key — no application needed. Sandbox keys work identically to live keys but return static mock data so you can build and test without going through the review process.

Need to rotate a lost key or update your allowed origins? Email hello@superpayrewards.com.