Cashback Rewards

Overview

Cashback Rewards let a cardholder earn money back on eligible purchases made with their Upwardli-issued card. Rewards are powered by a rewards configuration that your partner program makes available; once a card is enrolled in a configuration, the cardholder can browse the offers they’re eligible for and cashback is posted to their account automatically.

This guide walks through the full lifecycle:

  1. Find the cardholder’s payment card.
  2. Check whether the card is already enrolled.
  3. List the rewards configurations the card is eligible for.
  4. Enroll the card in an active configuration.
  5. View the offers available to the enrolled card.

Who this is for: partners integrating directly against the API, and the embedded web component that surfaces this same flow to a consumer.

Token scope required: api:rewards:read for the read endpoints, api:rewards:write to enroll. The broader api:read / api:write scopes also grant access.


Prerequisites

  • Valid OAuth 2.0 Bearer token (see Authentication)
  • The consumer has at least one active payment card on your partner network
  • Cashback Rewards are enabled for your partner configuration

How It Works

Partner App / Component Upwardli API
│ │
│ GET .../payment-cards/ │ Resolve the active card
│────────────────────────────────>│
│ │
│ GET .../rewards/enrollments/ │ Already enrolled?
│────────────────────────────────>│
│ ┌── active enrollment ───┤── yes ─> go straight to offers
│ │ │
│ GET .../rewards/ │ no -> list eligible configs
│────────────────────────────────>│
│ │
│ POST .../rewards/{cfg}/enrollments/ Enroll the card
│────────────────────────────────>│
│ │
│ GET .../rewards/{program}/offers/ Browse offers
│────────────────────────────────>│
│ │

Base URLs

Production: https://api.upwardli.com
Sandbox: https://api-sandbox.upwardli.com

1. Find the payment card

Rewards endpoints are keyed by a payment card external ID. List the consumer’s cards and select an active one (skip cards whose status is canceled, closed, or deactivated).

Endpoint

GET /v2/consumers/{consumer_id}/payment-cards/

Example request

$curl "https://api.upwardli.com/v2/consumers/{consumer_id}/payment-cards/" \
> -H "Authorization: Bearer <token>"

The id of the chosen card is the {payment_card_id} used in every step below.

Full API reference

List Consumer Payment Cards →


2. Check the current enrollment

Before showing an activation prompt, check whether the card is already enrolled. An enrollment with is_active: true means the cardholder is already earning rewards — skip to step 5 and use its program_id to fetch offers.

Endpoint

GET /v2/payment-cards/{payment_card_id}/rewards/enrollments/

Example request

$curl "https://api.upwardli.com/v2/payment-cards/{payment_card_id}/rewards/enrollments/" \
> -H "Authorization: Bearer <token>"

Response — 200 OK

1{
2 "count": 1,
3 "next": null,
4 "previous": null,
5 "results": [
6 {
7 "id": "a1b2c3d4-0000-4000-8000-000000000001",
8 "program_id": "9f8e7d6c-0000-4000-8000-0000000000aa",
9 "configuration_name": "Upwardli Cashback",
10 "is_active": true,
11 "created_at": "2026-06-25T14:30:00Z"
12 }
13 ]
14}

If no result has is_active: true, the card is not enrolled yet — continue to step 3.

Full API reference

List Rewards Enrollments →


3. List eligible rewards configurations

When the card has no active enrollment, list the configurations available to it. A configuration with is_active: true can be enrolled in; its id is the {rewards_configuration_id} you pass in step 4. is_enrolled tells you whether the card is already enrolled in that specific configuration.

Endpoint

GET /v2/payment-cards/{payment_card_id}/rewards/

Example request

$curl "https://api.upwardli.com/v2/payment-cards/{payment_card_id}/rewards/" \
> -H "Authorization: Bearer <token>"

Response — 200 OK

1{
2 "count": 1,
3 "next": null,
4 "previous": null,
5 "results": [
6 {
7 "id": "5c4b3a29-0000-4000-8000-0000000000bb",
8 "configuration_name": "Upwardli Cashback",
9 "is_active": true,
10 "provider": "kard",
11 "created_at": "2026-06-01T00:00:00Z",
12 "is_enrolled": false
13 }
14 ]
15}

No active configuration means rewards aren’t available for this card yet — surface a “coming soon” state rather than an activation prompt.

Full API reference

List Rewards Configurations →


4. Enroll the card

Enroll the card in an active configuration. No request body is required — the card and configuration are identified entirely by the path. The response is the new enrollment, which carries the program_id you’ll need to fetch offers.

Endpoint

POST /v2/payment-cards/{payment_card_id}/rewards/{rewards_configuration_id}/enrollments/

Example request

$curl -X POST \
> "https://api.upwardli.com/v2/payment-cards/{payment_card_id}/rewards/{rewards_configuration_id}/enrollments/" \
> -H "Authorization: Bearer <token>" \
> -H "Content-Type: application/json"

Response — 201 Created

1{
2 "id": "a1b2c3d4-0000-4000-8000-000000000001",
3 "program_id": "9f8e7d6c-0000-4000-8000-0000000000aa",
4 "configuration_name": "Upwardli Cashback",
5 "is_active": true,
6 "created_at": "2026-06-25T14:30:00Z"
7}

Full API reference

Create Rewards Enrollment →


5. View available offers

With an active enrollment, fetch the offers the cardholder is eligible for. Pass the program_id from the enrollment as the {program_id} path parameter. To surface nearby in-store offers, include the cardholder’s latitude and longitude (and an optional radius).

Endpoint

GET /v2/payment-cards/{payment_card_id}/rewards/{program_id}/offers/

Query parameters

ParameterTypeDescription
latitudefloatLatitude used to surface nearby in-store offers
longitudefloatLongitude used to surface nearby in-store offers
radiusfloatSearch radius, in miles, around the coordinates
searchstringFilter offers by a search term
limit / offsetintegerPagination controls

Example request

$curl "https://api.upwardli.com/v2/payment-cards/{payment_card_id}/rewards/{program_id}/offers/?latitude=30.2672&longitude=-97.7431" \
> -H "Authorization: Bearer <token>"

Response — 200 OK

1{
2 "count": 1,
3 "next": null,
4 "previous": null,
5 "results": [
6 {
7 "type": "offer",
8 "id": "off_8a72b1",
9 "relationships": {
10 "category": { "data": [{ "id": "cat_grocery", "type": "GROCERY" }] }
11 },
12 "attributes": {
13 "name": "Whole Foods Market",
14 "description": "Earn cash back on groceries",
15 "terms": "Excludes gift cards and alcohol where prohibited.",
16 "purchaseChannel": ["INSTORE"],
17 "userReward": { "type": "PERCENT", "value": 5 },
18 "assets": [
19 { "type": "IMG_VIEW", "url": "https://cdn.example.com/wf.png", "alt": "Whole Foods" }
20 ],
21 "expirationDate": "2026-09-30",
22 "websiteUrl": "https://www.wholefoodsmarket.com"
23 },
24 "address": {
25 "street": "525 N Lamar Blvd",
26 "city": "Austin",
27 "state": "TX",
28 "zipCode": "78703"
29 }
30 }
31 ]
32}

Reward types

The attributes.userReward object describes how much the cardholder earns:

typeMeaningExample display
FLATA fixed dollar amount back$5.00 cash back
PERCENTA percentage of the purchase5% cash back

purchaseChannel is ["INSTORE"] for in-store offers (which include an address) or ["ONLINE"] for online offers (use websiteUrl).

Full API reference

List Rewards Offers →


Error Reference

HTTP statusCause
401Missing or invalid Bearer token
403Token scope does not include api:rewards:read (reads) or api:rewards:write (enroll) — api:read / api:write also work
404Payment card, configuration, or program not found, or not on your partner network
500Unexpected server error — open a support ticket