Skip to content
Uthrive

Uthrive

Consumer Business
    • BEST CREDIT CARDS
    • BEST BUSINESS CREDIT CARDS
    • Become a Credit Card Pro
      • Best Credit Cards
      • Best travel credit cards
      • Best balance transfer credit cards
      • Best Cash Back credit cards
      • Best 0% APR Credit Cards
      • Best No Annual Fee Credit Cards
      • Best Rewards Credit Cards
      • Best Airlines Credit Cards
      • Best Hotel Credit Cards
      • Best Credit Cards For groceries
      • Best Credit Cards For Streaming Services
      • Best Credit Cards For Gas
      • Best Credit Cards For Online Shopping
      • Best Credit Cards For Healthcare
      • Best Credit Cards
        Popular reads
        • The Platinum Card® From American Express
        • American Express® Gold Card
        • Blue Cash Preferred
        • Blue Cash Everyday
        • Hilton Honors Card
        • Chase Sapphire Preferred
        • Chase Sapphire Reserve
        • Chase Freedom Unlimited
        • Southwest Rapid Rewards Plus
        • United Quest Card
        • Capital One Venture
        • Capital One Venture X
        • Capital One VentureOne
        • Capital One Quicksilver
        • Capital One SavorOne
      • Best travel credit cards
        Popular reads
        • Best Credit Cards for Travel Insurance
        • Unexpected Travel Expenses
        • Best Places to Travel for Christmas
        • Five Fantastic Ways to Earn Credit Card Points
        • Best Airbnb Credit Cards
      • Best balance transfer credit cards
        Popular reads
        • What Is A Balance Transfer
        • Balance Transfer Credit Card with Bad Credit
        • Balance Transfer Credit Card Mistakes
      • Popular reads
        • Maximize Cash Back Rewards
      • Popular reads
        • Maximize Your Credit Card Shopping Rewards
      • Best Airlines Credit Cards
        Popular reads
        • Best Delta Credit Cards - Is A Delta Credit Card Worth It?
        • Best American Airlines Credit Cards - Airlines Credit Card Offers
        • Best Southwest Airlines credit cards - Southwest Credit Card Benefits
        • Best United Airlines Credit Cards | United Airlines Credit Card Offers
      • Best Credit Cards For Streaming Services
        Popular reads
        • Best Credit Cards for Netflix and Other Streaming Services
        • Best Disney Credit Cards
      • Best Credit Cards For Gas
        Popular reads
        • Beat High Fuel Prices With Rewards Programs
        • How to Beat High Gas Prices with the Best Gas Credit Cards
      • Best Credit Cards For Online Shopping
        Popular reads
        • Best Stores for Holiday Shopping
        • Strategies To Maximize Your Credit Card Shopping Rewards
      • Popular reads
        • Best Card for Walgreens/CVS
      • American Express Business Credit Cards
      • Chase Business Credit Cards
      • Capital One Business Credit Cards
      • Bank Of America Business Credit Cards
      • Popular reads
        • The Business Platinum Card® From American Express
      • Chase Business Credit Cards
        Popular reads
        • Ink Business Preferred® Credit Card
        • Ink Business Unlimited® Credit Card
      • Capital One Business Credit Cards
        Popular reads
        • Capital One Spark Miles Business
        • Capital One Venture X Business
    • CREDIT CARD REWARD PROGRAMS
    • BEST AIRLINE REWARD PROGRAMS
    • BEST HOTEL REWARD PROGRAMS
    • Become a Credit Card Pro
      • American Express Membership Rewards
      • Chase Ultimate Rewards
      • Capital One Miles
      • Citi ThankYou Points
      • Bank Of America Travel Rewards
      • American Airlines AAdvantage Program
      • United Airlines MileagePlus
      • Delta SkyMiles
      • Southwest Rapid Rewards
      • Compare Airline Rewards
      • American Airlines AAdvantage Program
        Popular reads
        • How to earn & redeem American Airlines Miles
        • American Airlines elite status - What is Aa Status Worth in 2024?
        • Best American Airlines Credit Cards - Airlines Credit Card Offer
        • American Airlines Baggage Fees - Changes in 2024 & How to Avoid Them
        • American Airlines flight credit
      • United Airlines MileagePlus
        Popular reads
        • How to Earn & Use/Redeem United Miles - Best Tips & Tricks [2024]
        • Best United Airlines Credit Cards | United Airlines Credit Card Offers
        • United Airlines Baggage Fees - United raises checked bag fee $5
        • United Airlines Partners | Your ultimate guide to United Airlines partners
      • Delta SkyMiles
        Popular reads
        • How to earn & redeem Delta Skymiles
        • Best Delta Credit Cards - Is A Delta Credit Card Worth It?
        • Delta Medallion Status - Guide To SkyMiles Medallion Benefits
        • Top 7 Delta SkyMiles Amex changes I’m most excited about - Uthrive
      • Southwest Rapid Rewards
        Popular reads
        • How to use & redeem Southwest Rapid Rewards
        • Guide To Southwest Transfer Points & Southwest Points Value
        • Best Southwest Airlines credit cards - Southwest Credit Card Benefits
        • How to Find Southwest Airlines Cheap Flights with the Southwest Low Fare Calendar
      • Compare Airline Rewards
        Popular reads
        • American vs. Delta
        • United vs. Delta
        • Southwest vs. Delta
      • Hyatt Rewards Program
      • Mariott Bonvoy Rewards Program
      • Hilton Rewards Program
      • Best Western Rewards Program
    • CARD OFFERS
    • BEST CARD FOR PURCHASES
    • REFER A FRIEND
    • Become a Credit Card Pro
      • Amex Offers: What Are Amex Offers? A Complete Guide
      • Chase Offers: How To Maximize Your Rewards With Chase Offers
      • Best Card For Amazon
      • Best Card For AirBnb
      • Best Card For Apple
      • Best Card For Costco
      • Best Card For Uber/Lyft
      • Best Card For Walmart
      • Best Card For Target
      • Popular reads
        • Best Amazon Credit Cards - How to apply for amazon credit card
      • Popular reads
        • Best Purchase Protection Credit Cards
      • Popular reads
        • Best Extended Warranty Credit Cards
      • American Express Refer A Friend Bonuses
      • Capital One Refer A Friend Program
      • Chase Refer A Friend Bonuses
      • Citi Credit Card Refer A Friend
    • TRAVEL BENEFITS
    • SHOPPING BENEFITS
    • DINNING BENEFITS
    • OTHER BENEFITS
    • Become a Credit Card Pro
      • Free TSA PreCheck
      • Free Checked Bags
      • No Foreign Transaction Fee
      • Free Global Entry
      • Free Airport Lounge
      • Free Priority Pass
      • Free Travel Insurance
      • Airline Credits
      • Hotel Credits
      • Popular reads
        • Best Extended Warranty Credit Cards
      • Cash Back Offers
      • Purchase Protection
      • Extended Warranty
      • Buy Now Pay Later
      • Netflix/Hulu
      • Disney Bundle
      • Credit Cards With Cellphone Insurance
  • Log in
  • Sign up

Maximum Rewards + Savings
on Purchases

Automatic best saving offers
Use best card at checkout
Get up to $800* back on your purchases
Consumer Business
  • Get Uthrive App
  • Sign up
  • Log in

Welcome! Sign-in to your account

×
Don't have an account? Sign up here.

Welcome! Sign-in to your account

×
Don't have an account? Sign up here.
For your convenience we'll send 6-digit code.

*Your email address (Required)

Welcome To Uthrive!

×
Already have an account? Sign In here.

Welcome To Uthrive!

×
Already have an account? Sign In here.
For your convenience we'll send 6-digit code.

*Your email address (Required)

×

Unknown Error

Looks like there is some unknown error.
We apologize for the inconvenience.
Plaid logo
Docs
  • Introduction
  • Authentication
  • Endpoints
  • Errors
  • Schema Objects
Plaid logo
Docs

Endpoints

Calculate Earned Rewards

Copy
POST /reward/earned

URL: https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned

Calculate earned credit card rewards for a provided list of transactions. Use this endpoint to show users how much reward value they’ve already received based on their spending history.

Authentication
  • Required.
  • Supply client-id and api-key headers with every request.
Request Headers
HeaderTypeRequiredDescription
client-idstringYesYour Uthrive client ID
api-keystringYesYour Uthrive API key
Content-TypestringYesapplication/json
Request Schema

The request body is a JSON object with an array of transaction objects.

FieldTypeRequiredDescription
transactionsarrayYesList of transaction objects

Each transaction object:

FieldTypeRequiredExample
transactionIdstringYes“12345”
transactionAmountnumberYes100.50
transactionDatestringYes“2023-10-01”
merchantstringYes“Amazon”
cardNamestringYes“Chase Sapphire Preferred”

Example Request

Copy
{
  "transactions": [
    {
      "transactionId": "12345",
      "transactionAmount": 100.50,
      "transactionDate": "2023-10-01",
      "merchant": "Amazon",
      "cardName": "Chase Sapphire Preferred"
    },
    {
      "transactionId": "67890",
      "transactionAmount": 250.75,
      "transactionDate": "2023-10-02",
      "merchant": "Walmart",
      "cardName": "American Express Blue Cash EveryDay"
    }
  ]
}
Response

Returns a JSON object with two main fields:

  • data: Contains the rewards breakdown
  • message: Status message
Example Success Response (200 OK)
Copy
{
  "data": {
    "earnedRewards": [
      {
        "transactionId": "67890",
        "transactionAmount": 250.75,
        "transactionDate": "2023-10-02",
        "merchant": "Walmart",
        "cardName": "American Express Blue Cash EveryDay",
        "rewardValue": 0.01,
        "rewardMultiplier": 1,
        "rewardAmount": 2.5075
      },
      {
        "transactionId": "12345",
        "transactionAmount": 100.5,
        "transactionDate": "2023-10-01",
        "merchant": "Amazon",
        "cardName": "Chase Sapphire Preferred",
        "rewardValue": 0.013,
        "rewardMultiplier": 1,
        "rewardAmount": 1.3065
      }
    ],
    "totalEarnedReward": 3.814
  },
  "message": "Success"
}
Response Field Details
FieldTypeDescription
earnedRewardsarrayList of calculated rewards, one per input transaction
totalEarnedRewardnumberSum of all reward values earned across the input transactions
messagestringOperation status message

Each item in earnedRewards:

FieldTypeDescription
transactionIdstringThe transaction’s unique reference
transactionAmountnumberSpend amount for this transaction
transactionDatestringPurchase date (YYYY-MM-DD)
merchantstringMerchant name
cardNamestringThe card used
rewardValuenumberDollar equivalent per point/mile for this card
rewardMultipliernumberMultiplier applied (depends on merchant/category)
rewardAmountnumberTotal reward value earned for the transaction
Error Responses
HTTP CodeMeaningExample Response
400Malformed input or missing fields{ “message”: “Invalid request body” }
401Authentication failed{ “message”: “Unauthorized” }
500Internal server error{ “message”: “Internal error” }
    cURL
    Copy
    curl -X POST "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned" \
      -H "Content-Type: application/json" \
      -H "client-id: YOUR_CLIENT_ID" \
      -H "api-key: YOUR_API_KEY" \
      -d '{
        "transactions": [
          {
            "transactionId": "12345",
            "transactionAmount": 100.50,
            "transactionDate": "2023-10-01",
            "merchant": "Amazon",
            "cardName": "Chase Sapphire Preferred"
          }
        ]
      }'
    
    NodeJS
    Copy
    const axios = require('axios');
    
    async function postEarnedRewards() {
      const url = 'https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned';
      const headers = {
        'Content-Type': 'application/json',
        'client-id': 'YOUR_CLIENT_ID',
        'api-key': 'YOUR_API_KEY'
      };
      const data = {
        transactions: [
          {
            transactionId: "12345",
            transactionAmount: 100.50,
            transactionDate: "2023-10-01",
            merchant: "Amazon",
            cardName: "Chase Sapphire Preferred"
          }
        ]
      };
    
      try {
        const response = await axios.post(url, data, { headers });
        console.log('Response:', response.data);
      } catch (error) {
        if (error.response) {
          console.error('API Error:', error.response.status, error.response.data);
        } else {
          console.error('Error:', error.message);
        }
      }
    }
    
    postEarnedRewards();
    
    Python
    Async Python example with aiohttp
    Copy
    pip install aiohttp
    import aiohttp
    import asyncio
    
    async def post_earned_rewards():
        url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned"
        headers = {
            "Content-Type": "application/json",
            "client-id": "YOUR_CLIENT_ID",
            "api-key": "YOUR_API_KEY"
        }
        data = {
            "transactions": [
                {
                    "transactionId": "12345",
                    "transactionAmount": 100.50,
                    "transactionDate": "2023-10-01",
                    "merchant": "Amazon",
                    "cardName": "Chase Sapphire Preferred"
                }
            ]
        }
    
        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=data, headers=headers) as resp:
                print("Status code:", resp.status)
                response_json = await resp.json()
                print("Response body:", response_json)
    
    # Run the async function
    asyncio.run(post_earned_rewards())
    
    Java
    Using Spring RestTemplate
    Copy
    import org.springframework.http.*;
    import org.springframework.web.client.RestTemplate;
    import java.util.*;
    
    public class UthriveApiSpring {
        public static void main(String[] args) {
            RestTemplate restTemplate = new RestTemplate();
    
            String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned";
    
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("client-id", "YOUR_CLIENT_ID");
            headers.set("api-key", "YOUR_API_KEY");
    
            Map<String, Object> transaction = new HashMap<>();
            transaction.put("transactionId", "12345");
            transaction.put("transactionAmount", 100.50);
            transaction.put("transactionDate", "2023-10-01");
            transaction.put("merchant", "Amazon");
            transaction.put("cardName", "Chase Sapphire Preferred");
    
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put("transactions", Arrays.asList(transaction));
    
            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(reqBody, headers);
    
            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
    
            System.out.println("Status code: " + response.getStatusCodeValue());
            System.out.println("Response body: " + response.getBody());
        }
    }
    
    Java 11+ with Jackson for JSON construction

    If you prefer strong typing and JSON serialization

    Copy
    import com.fasterxml.jackson.databind.ObjectMapper;
    import java.net.URI;
    import java.net.http.*;
    import java.util.*;
    
    public class UthriveApiJackson {
        public static void main(String[] args) throws Exception {
            String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned";
            HttpClient client = HttpClient.newHttpClient();
    
            Map<String, Object> transaction = new HashMap<>();
            transaction.put("transactionId", "12345");
            transaction.put("transactionAmount", 100.50);
            transaction.put("transactionDate", "2023-10-01");
            transaction.put("merchant", "Amazon");
            transaction.put("cardName", "Chase Sapphire Preferred");
    
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put("transactions", Arrays.asList(transaction));
    
            ObjectMapper mapper = new ObjectMapper();
            String jsonBody = mapper.writeValueAsString(reqBody);
    
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .header("Content-Type", "application/json")
                    .header("client-id", "YOUR_CLIENT_ID")
                    .header("api-key", "YOUR_API_KEY")
                    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                    .build();
    
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.statusCode());
            System.out.println(response.body());
        }
    }
    
    Android

    Android Example Using OkHttp

    1. Add OkHttp to Your build.gradle (Module):
    Copy
    dependencies {
        implementation 'com.squareup.okhttp3:okhttp:4.10.0'
    }
    1. Android Java code example
    Copy
    import android.os.Bundle;
    import androidx.appcompat.app.AppCompatActivity;
    import okhttp3.*;
    
    import org.json.JSONArray;
    import org.json.JSONObject;
    
    import java.io.IOException;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String URL = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/earned";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // You may wish to run this inside an AsyncTask, background thread, or ViewModel (for production)
            new Thread(this::postUthriveEarnedReward).start();
        }
    
        private void postUthriveEarnedReward() {
            OkHttpClient client = new OkHttpClient();
    
            try {
                JSONObject transaction = new JSONObject();
                transaction.put("transactionId", "12345");
                transaction.put("transactionAmount", 100.50);
                transaction.put("transactionDate", "2023-10-01");
                transaction.put("merchant", "Amazon");
                transaction.put("cardName", "Chase Sapphire Preferred");
    
                JSONArray transactions = new JSONArray();
                transactions.put(transaction);
    
                JSONObject requestBodyJson = new JSONObject();
                requestBodyJson.put("transactions", transactions);
    
                RequestBody body = RequestBody.create(
                    requestBodyJson.toString(),
                    MediaType.get("application/json; charset=utf-8")
                );
    
                Request request = new Request.Builder()
                        .url(URL)
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .addHeader("client-id", "YOUR_CLIENT_ID")
                        .addHeader("api-key", "YOUR_API_KEY")
                        .build();
    
                Response response = client.newCall(request).execute();
                if (response.isSuccessful() && response.body() != null) {
                    String responseStr = response.body().string();
                    runOnUiThread(() -> {
                        // Handle the API response (update UI, Toast, Log, etc.)
                        // Example:
                        System.out.println("Response: " + responseStr);
                    });
                } else {
                    runOnUiThread(() -> {
                        System.err.println("Error: " + response.code());
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    Best Practices

    • transactionId can be any string unique to a transaction in your system.
    • Ensure cardName matches Uthrive’s supported list for best accuracy.
    • The sum of rewardAmount fields will equal totalEarnedReward.

    Calculate Missed Rewards

    Copy
    POST /reward/missed

    URL: https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed

    Calculate missed rewards for a batch of transactions, showing how much additional reward value a user could have earned if they had used the optimal card—including both cards they already have and cards they may want to apply for.

    Authentication
    • Required.
    • Supply client-id and api-key headers with every request
    Request Headers
    HeaderTypeRequiredDescription
    client-idstringYesYour Uthrive client ID
    api-keystringYesYour Uthrive API key
    Content-TypestringYesapplication/json
    Request Body Schema
    FieldTypeRequiredDescription
    transactionsarrayYesList of transaction objects (see below)
    yourCardsarrayYesList of card names you currently hold

    Each transaction object:

    FieldTypeRequiredDescription
    transactionIdstringYesUnique ID
    transactionAmountnumberYesSpend amount
    transactionDatestringYesYYYY-MM-DD
    merchantstringYesMerchant name
    cardNamestringYesCard used

    yourCards is an array of card name strings (must match Uthrive’s supported cards list).

    Example Request

    Copy
    {
      "transactions": [
        {
          "transactionId": "12345",
          "transactionAmount": 100.5,
          "transactionDate": "2023-10-01",
          "merchant": "Amazon",
          "cardName": "Chase Sapphire Preferred"
        }
      ],
      "yourCards": [
        "American Express Platinum",
        "Chase Sapphire Preferred"
      ]
    }
    
    
    Success Response (200 OK)

    Returns a breakdown of:

    • missed rewards if a different card in the user’s wallet (yourCards) was used,
    • missed rewards if a potential new card (not in wallet) was used, and summary statistics.
    Copy
    {
      "data": {
        "missedRewards": [
          {
            "transactionId": "12345",
            "transactionAmount": 100.5,
            "transactionDate": "2023-10-01",
            "merchant": "Amazon",
            "cardName": "Chase Sapphire Preferred",
            "rewardAmount": 1.3065,
            "missedRewardYourCards": [
              {
                "cardId": 43,
                "cardName": "Capital One QuickSilver",
                "transactionId": "12345",
                "rewardValue": 0.01,
                "rewardMultiplier": 1.5,
                "missedReward": 0.201
              }
            ],
            "missedRewardNewCards": [
              {
                "cardId": 99,
                "cardName": "Amex Green",
                "transactionId": "12345",
                "rewardValue": 0.02,
                "rewardMultiplier": 2,
                "missedReward": 0.5
              }
            ],
            "bestCard": {
              "cardId": 99,
              "cardName": "Amex Green",
              "transactionId": "12345",
              "rewardValue": 0.02,
              "rewardMultiplier": 2,
              "missedReward": 0.5
            }
          }
        ],
        "overallMissedRewardsExisting": 0.201,
        "overallMissedRewardsNew": 0.5
      },
      "message": "Success"
    }
    Response Fields

    Top-level:

    FieldTypeDescription
    data.missedRewardsarrayList of per-transaction missed reward breakdowns
    data.overallMissedRewardsExistingnumberTotal missed by not using the best card you have
    data.overallMissedRewardsNewnumberTotal missed if you had access to all cards
    messagestringSuccess or error string

    Inside each object in missedRewards:

    FieldTypeDescription
    transactionIdstringThe transaction’s unique ID
    transactionAmountnumberSpend amount
    transactionDatestringPurchase date (YYYY-MM-DD)
    merchantstringMerchant
    cardNamestringThe card actually used for the transaction
    rewardAmountnumberRewards earned with the actual card used
    missedRewardYourCardsarrayMissed rewards for other cards you hold
    missedRewardNewCardsarrayMissed rewards if you had other (potential) cards
    bestCardobjectTheoretical card with maximum possible reward

    Each object in missedRewardYourCards and missedRewardNewCards:

    FieldTypeDescription
    cardIdintegerUthrive-internal card ID
    cardNamestringCard name
    transactionIdstringTransaction ID
    rewardValuenumber$ value per point/mile
    rewardMultipliernumberPoints multiplier
    missedRewardnumberExtra dollars you would have earned
      cURL
      Copy
      curl -X POST "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed" \
        -H "Content-Type: application/json" \
        -H "client-id: YOUR_CLIENT_ID" \
        -H "api-key: YOUR_API_KEY" \
        -d '{
          "transactions": [
            {
              "transactionId": "12345",
              "transactionAmount": 100.5,
              "transactionDate": "2023-10-01",
              "merchant": "Amazon",
              "cardName": "Chase Sapphire Preferred"
            }
          ],
          "yourCards": [
            "American Express Platinum",
            "Chase Sapphire Preferred"
          ]
        }'
      
      Node
      1. Install Axios
      Copy
      npm install axios
      1. Async/Await Node.js Script with Error Handling
      Copy
      const axios = require('axios');
      async function postMissedRewards() {
        const url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed";
        const headers = {
          'Content-Type': 'application/json',
          'client-id': 'YOUR_CLIENT_ID',
          'api-key': 'YOUR_API_KEY'
        };
        const data = {
          transactions: [
            {
              transactionId: "12345",
              transactionAmount: 100.5,
              transactionDate: "2023-10-01",
              merchant: "Amazon",
              cardName: "Chase Sapphire Preferred"
            }
          ],
          yourCards: [
            "American Express Platinum",
            "Chase Sapphire Preferred"
          ]
        };
      
        try {
          const response = await axios.post(url, data, { headers });
          console.log('Status:', response.status);
          console.log('Response:', JSON.stringify(response.data, null, 2));
        } catch (error) {
          if (error.response) {
            // Server responded with an error status
            console.error('API Error:', error.response.status);
            console.error('Error body:', JSON.stringify(error.response.data, null, 2));
          } else if (error.request) {
            // Request was made but no response
            console.error('No response received:', error.request);
          } else {
            // Error in setting up the request
            console.error('Request setup error:', error.message);
          }
        }
      }
      
      postMissedRewards();
      
      Python
      1. Using Aync/Await with error handling
      Copy
      pip install requests
      import requests
      
      url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed"
      
      headers = {
          "Content-Type": "application/json",
          "client-id": "YOUR_CLIENT_ID",
          "api-key": "YOUR_API_KEY"
      }
      
      data = {
          "transactions": [
              {
                  "transactionId": "12345",
                  "transactionAmount": 100.5,
                  "transactionDate": "2023-10-01",
                  "merchant": "Amazon",
                  "cardName": "Chase Sapphire Preferred"
              }
          ],
          "yourCards": [
              "American Express Platinum",
              "Chase Sapphire Preferred"
          ]
      }
      
      try:
          response = requests.post(url, json=data, headers=headers, timeout=10)
          response.raise_for_status()  # Raises HTTPError for bad HTTP status codes
          print("Status:", response.status_code)
          print("Response:", response.json())
      except requests.exceptions.HTTPError as e:
          print(f"HTTP error occurred: {e} - Response body: {response.text}")
      except requests.exceptions.ConnectionError as e:
          print("A connection error occurred:", e)
      except requests.exceptions.Timeout as e:
          print("Request timed out:", e)
      except requests.exceptions.RequestException as e:
          print("An error occurred while making the request:", e)
      
      1. Using Async request with aiohttp
      Copy
      import asyncio
      import aiohttp
      
      async def post_missed_rewards():
          url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed"
          headers = {
              "Content-Type": "application/json",
              "client-id": "YOUR_CLIENT_ID",
              "api-key": "YOUR_API_KEY"
          }
          data = {
              "transactions": [
                  {
                      "transactionId": "12345",
                      "transactionAmount": 100.5,
                      "transactionDate": "2023-10-01",
                      "merchant": "Amazon",
                      "cardName": "Chase Sapphire Preferred"
                  }
              ],
              "yourCards": [
                  "American Express Platinum",
                  "Chase Sapphire Preferred"
              ]
          }
          try:
              async with aiohttp.ClientSession() as session:
                  async with session.post(url, json=data, headers=headers, timeout=10) as resp:
                      print("Status:", resp.status)
                      resp_json = await resp.json()
                      print("Response:", resp_json)
                      resp.raise_for_status()
          except aiohttp.ClientResponseError as e:
              print(f"HTTP error occurred: {e.status} - {e.message}")
          except aiohttp.ClientConnectionError as e:
              print("A connection error occurred:", e)
          except asyncio.TimeoutError as e:
              print("Request timed out:", e)
          except Exception as e:
              print("An error occurred while making the request:", e)
      
      asyncio.run(post_missed_rewards())
      
      Java

      Using standard HttpClient API

      Copy
      import java.io.IOException;
      import java.net.URI;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;
      
      public class UthriveMissedRewardExample {
          public static void main(String[] args) {
              String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed";
              String clientId = "YOUR_CLIENT_ID";
              String apiKey = "YOUR_API_KEY";
      
              String jsonBody = """
              {
                "transactions": [
                  {
                    "transactionId": "12345",
                    "transactionAmount": 100.5,
                    "transactionDate": "2023-10-01",
                    "merchant": "Amazon",
                    "cardName": "Chase Sapphire Preferred"
                  }
                ],
                "yourCards": [
                  "American Express Platinum",
                  "Chase Sapphire Preferred"
                ]
              }
              """;
      
              HttpClient client = HttpClient.newHttpClient();
              HttpRequest request = HttpRequest.newBuilder()
                      .uri(URI.create(url))
                      .header("Content-Type", "application/json")
                      .header("client-id", clientId)
                      .header("api-key", apiKey)
                      .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                      .build();
      
              try {
                  HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
      
                  int status = response.statusCode();
                  String body = response.body();
      
                  System.out.println("Status: " + status);
                  System.out.println("Response body:\n" + body);
      
                  if (status >= 200 && status < 300) {
                      // Success
                      // Optionally, parse the JSON here using a library like Jackson or Gson
                  } else {
                      System.err.println("API returned an error. Status: " + status);
                  }
              } catch (IOException e) {
                  System.err.println("I/O Exception during API call: " + e.getMessage());
                  e.printStackTrace();
              } catch (InterruptedException e) {
                  System.err.println("Request was interrupted: " + e.getMessage());
                  Thread.currentThread().interrupt();
              } catch (Exception e) {
                  System.err.println("Unexpected error: " + e.getMessage());
                  e.printStackTrace();
              }
          }
      }
      

      Using Spring

      If you are using Maven
      Copy
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>5.3.30</version> <!-- or your compatible version -->
      </dependency>
      If you use Gradle
      Copy
      implementation 'org.springframework:spring-web:5.3.30'
      Spring RestTemplate example
      Copy
      import org.springframework.http.*;
      import org.springframework.web.client.RestClientException;
      import org.springframework.web.client.RestTemplate;
      
      import java.util.*;
      
      public class UthriveSpringExample {
      
          public static void main(String[] args) {
              String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed";
      
              // Build the request JSON as Java Maps
              Map<String, Object> transaction = new HashMap<>();
              transaction.put("transactionId", "12345");
              transaction.put("transactionAmount", 100.5);
              transaction.put("transactionDate", "2023-10-01");
              transaction.put("merchant", "Amazon");
              transaction.put("cardName", "Chase Sapphire Preferred");
      
              Map<String, Object> requestBody = new HashMap<>();
              requestBody.put("transactions", Arrays.asList(transaction));
              requestBody.put("yourCards", Arrays.asList("American Express Platinum", "Chase Sapphire Preferred"));
      
              // Set HTTP headers
              HttpHeaders headers = new HttpHeaders();
              headers.setContentType(MediaType.APPLICATION_JSON);
              headers.set("client-id", "YOUR_CLIENT_ID");
              headers.set("api-key", "YOUR_API_KEY");
      
              HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
      
              RestTemplate restTemplate = new RestTemplate();
      
              try {
                  ResponseEntity<String> response = restTemplate.exchange(
                      url, HttpMethod.POST, entity, String.class);
      
                  int statusCode = response.getStatusCodeValue();
                  System.out.println("Status: " + statusCode);
                  System.out.println("Body:\n" + response.getBody());
      
                  if (statusCode >= 200 && statusCode < 300) {
                      // Success, parse the JSON if needed (Jackson auto-mapping available)
                  } else {
                      System.err.println("API returned non-success status.");
                  }
              } catch (RestClientException e) {
                  System.err.println("Exception during API request: " + e.getMessage());
              }
          }
      }
      

      Using Spring WebClient with error handling.

      WebClient is a part of Spring WebFlux, suitable for both reactive and non-blocking use cases in modern Spring Boot projects.

      Add dependency

      For maven , add to pom.xml
      Copy
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-webflux</artifactId>
      </dependency>
      
      For Gradle:
      Copy
      implementation 'org.springframework.boot:spring-boot-starter-webflux'
      
      import org.springframework.http.HttpHeaders;
      import org.springframework.http.MediaType;
      import org.springframework.web.reactive.function.BodyInserters;
      import org.springframework.web.reactive.function.client.WebClient;
      import reactor.core.publisher.Mono;
      
      import java.util.*;
      
      public class UthriveWebClientExample {
          public static void main(String[] args) {
              String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed";
      
              Map<String, Object> transaction = new HashMap<>();
              transaction.put("transactionId", "12345");
              transaction.put("transactionAmount", 100.5);
              transaction.put("transactionDate", "2023-10-01");
              transaction.put("merchant", "Amazon");
              transaction.put("cardName", "Chase Sapphire Preferred");
      
              Map<String, Object> body = new HashMap<>();
              body.put("transactions", List.of(transaction));
              body.put("yourCards", List.of("American Express Platinum", "Chase Sapphire Preferred"));
      
              WebClient webClient = WebClient.builder()
                      .baseUrl(url)
                      .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                      .defaultHeader("client-id", "YOUR_CLIENT_ID")
                      .defaultHeader("api-key", "YOUR_API_KEY")
                      .build();
      
              webClient.post()
                      .body(BodyInserters.fromValue(body))
                      .retrieve()
                      .toEntity(String.class)
                      .doOnSuccess(response -> {
                          System.out.println("Status: " + response.getStatusCode().value());
                          System.out.println("Body:\n" + response.getBody());
                      })
                      .doOnError(error -> {
                          System.err.println("Error during API request: " + error.getMessage());
                      })
                      .block(); // For demo main method usage; in production use subscribe() or chain in reactive flow
          }
      }
      

      Controller/Service WebFlux example with POJO mapping

      Project Setup

      Add to your pom.xml
      Copy
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-webflux</artifactId>
      </dependency>
      

      Or with Gradle

      Copy
      implementation 'org.springframework.boot:spring-boot-starter-webflux'
      POJO Model Classes
      Copy
      
      // MissedRewardResponse.java
      public class MissedRewardResponse {
          private Data data;
          private String message;
      
          // getters and setters
      
          public static class Data {
              private double overallMissedRewardsExisting;
              private double overallMissedRewardsNew;
              // Add missedRewards etc. as needed
      
              // getters and setters
          }
      }
      
      Service Layer using WebClient
      Copy
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.http.HttpHeaders;
      import org.springframework.http.MediaType;
      import org.springframework.stereotype.Service;
      import org.springframework.web.reactive.function.BodyInserters;
      import org.springframework.web.reactive.function.client.WebClient;
      import reactor.core.publisher.Mono;
      
      import java.util.List;
      import java.util.Map;
      
      @Service
      public class UthriveService {
      
          private final WebClient webClient;
      
          public UthriveService(
              @Value("${uthrive.api.client-id}") String clientId,
              @Value("${uthrive.api.api-key}") String apiKey
          ) {
              this.webClient = WebClient.builder()
                      .baseUrl("https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging")
                      .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                      .defaultHeader("client-id", clientId)
                      .defaultHeader("api-key", apiKey)
                      .build();
          }
      
          public Mono<MissedRewardResponse> getMissedRewards(List<Map<String, Object>> transactions, List<String> yourCards) {
              Map<String, Object> body = Map.of(
                  "transactions", transactions,
                  "yourCards", yourCards
              );
      
              return webClient.post()
                      .uri("/reward/missed")
                      .body(BodyInserters.fromValue(body))
                      .retrieve()
                      .bodyToMono(MissedRewardResponse.class);
          }
      }
      
      Controller Layer
      Copy
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;
      import reactor.core.publisher.Mono;
      import java.util.List;
      import java.util.Map;
      
      @RestController
      @RequestMapping("/api")
      public class UthriveController {
      
          @Autowired
          private UthriveService uthriveService;
      
          @PostMapping("/reward/missed/proxy")
          public Mono<MissedRewardResponse> proxyMissedReward(@RequestBody MissedRewardRequest request) {
              return uthriveService.getMissedRewards(request.getTransactions(), request.getYourCards());
          }
      }
      
      // --- You would also need this request DTO for clean deserialization ---
      class MissedRewardRequest {
          private List<Map<String, Object>> transactions;
          private List<String> yourCards;
      
          public List<Map<String, Object>> getTransactions() { return transactions; }
          public void setTransactions(List<Map<String, Object>> transactions) { this.transactions = transactions; }
      
          public List<String> getYourCards() { return yourCards; }
          public void setYourCards(List<String> yourCards) { this.yourCards = yourCards; }
      }
      
      Android

      Example using OkHttp for the HttpClient and Gson for deserialization

      Add dependencies in build.gradle
      Copy
      implementation 'com.squareup.okhttp3:okhttp:4.10.0'
      implementation 'com.google.code.gson:gson:2.10.1'
      Model classes (POJOs)
      Copy
      public class MissedRewardResponse {
          private Data data;
          private String message;
      
          public Data getData() { return data; }
          public String getMessage() { return message; }
      
          public static class Data {
              private double overallMissedRewardsExisting;
              private double overallMissedRewardsNew;
              // Add other fields as needed
      
              public double getOverallMissedRewardsExisting() { return overallMissedRewardsExisting; }
              public double getOverallMissedRewardsNew() { return overallMissedRewardsNew; }
              // Add other getters/setters...
          }
      }
      
      Make the HTTP request

      Run as a background thread

      Copy
      import android.os.Bundle;
      import androidx.appcompat.app.AppCompatActivity;
      import okhttp3.*;
      import com.google.gson.Gson;
      import java.io.IOException;
      import java.util.*;
      
      public class MainActivity extends AppCompatActivity {
      
          private static final String URL = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/reward/missed";
          private static final Gson gson = new Gson();
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              // Run in a background thread:
              new Thread(this::postMissedReward).start();
          }
      
          private void postMissedReward() {
              OkHttpClient client = new OkHttpClient();
      
              Map<String, Object> transaction = new HashMap<>();
              transaction.put("transactionId", "12345");
              transaction.put("transactionAmount", 100.5);
              transaction.put("transactionDate", "2023-10-01");
              transaction.put("merchant", "Amazon");
              transaction.put("cardName", "Chase Sapphire Preferred");
      
              Map<String, Object> requestBodyMap = new HashMap<>();
              requestBodyMap.put("transactions", Collections.singletonList(transaction));
              requestBodyMap.put("yourCards", Arrays.asList("American Express Platinum", "Chase Sapphire Preferred"));
      
              String requestBodyStr = gson.toJson(requestBodyMap);
      
              RequestBody body = RequestBody.create(
                  requestBodyStr,
                  MediaType.parse("application/json; charset=utf-8")
              );
      
              Request request = new Request.Builder()
                  .url(URL)
                  .post(body)
                  .addHeader("Content-Type", "application/json")
                  .addHeader("client-id", "YOUR_CLIENT_ID")
                  .addHeader("api-key", "YOUR_API_KEY")
                  .build();
      
              try (Response response = client.newCall(request).execute()) {
                  if (response.isSuccessful() && response.body() != null) {
                      String responseBody = response.body().string();
                      MissedRewardResponse missedRewardResponse = gson.fromJson(responseBody, MissedRewardResponse.class);
                      runOnUiThread(() -> {
                          // Use your POJO here (update UI, etc.)
                          System.out.println("Success! Message: " + missedRewardResponse.getMessage());
                          System.out.println("Overall Missed Existing: " + missedRewardResponse.getData().getOverallMissedRewardsExisting());
                      });
                  } else {
                      runOnUiThread(() -> {
                          System.err.println("API error: " + response.code());
                      });
                  }
              } catch (IOException e) {
                  runOnUiThread(() -> {
                      System.err.println("Network or parsing error: " + e.getMessage());
                  });
              }
          }
      }
      

      Use WorkManager/LiveData/Coroutines for modern Android apps. To update the UI, use runOnUiThread only when necessary.

      Error Responses

      HTTP CodeDescriptionExample Response
      400Malformed input, missing fields{ “message”: “Invalid request body” }
      401Authentication failed{ “message”: “Unauthorized” }
      500Internal server error{ “message”: “Internal error” }

      Best Practices

      • Card name values in both transactions.cardName and yourCards must match the supported card list for accurate matching.
      • Use this endpoint after transactions post to help users see real, actionable “missed value.”
      • Use overallMissedRewardsExisting to surface “missed with your current cards” and overallMissedRewardsNew for “missed if you had all available cards.”

      Best card recommendation

      Copy
      POST /recommend/advice

      URL: https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice

      Get the best personalized card usage advice for a specific purchase scenario. This endpoint tells you which of the user’s cards (and optionally, any new/potential cards) will maximize rewards for a given merchant and spend amount.

      Authentication
      • Required: Include client-id and api-key headers in every request
      Request Headers
      HeaderTypeRequiredDescription
      client-idstringYesYour Uthrive client ID
      api-keystringYesYour Uthrive API key
      Content-TypestringYesapplication/json
      Request Body Schema
      FieldTypeRequiredDescription
      merchantstringYesMerchant name (e.g., “Amazon”)
      yourCardsarrayYesList of card names you currently hold
      spendAmountnumberYesAmount (USD) to be spent

      Example Request:

      Copy
      {
        "merchant": "Amazon",
        "yourCards": [
          "American Express Platinum",
          "Chase Sapphire Preferred"
        ],
        "spendAmount": 300
      }
      
      Success Response (200 OK)

      Returns:

      • The best card in the user’s wallet for this merchant/spend amount.
      • Other cards in the wallet, with their respective reward calculations (ordered by reward value).
      Example:
      Copy
      {
        "data": {
          "bestCard": {
            "cardName": "Chase Sapphire Preferred",
            "rewardValue": 0.013,
            "rewardMultiplier": 1,
            "rewardAmount": 3.9,
            "bonus": 0.013
          },
          "otherCards": [
            {
              "cardName": "American Express Platinum",
              "rewardValue": 0.01,
              "rewardMultiplier": 1,
              "rewardAmount": 3,
              "bonus": 0.01
            }
          ]
        },
        "message": "Success"
      }
      
      Response Fields

      Top-level:

      FieldTypeDescription
      dataobjectCard advice data (see below)
      messagestringStatus message

      Inside data:

      FieldTypeDescription
      bestCardobjectCard with the maximum total reward for this scenario
      otherCardsarrayOther cards in wallet, with computed reward amounts

      Each card object:

      FieldTypeDescription
      cardNamestringCard name
      rewardValuenumber$ value per reward point/mile
      rewardMultipliernumberMultiplier for this merchant/amount
      rewardAmountnumberTotal reward earned for spendAmount (in USD)
      bonusnumberBonus reward value, if applicable
        cURL
        Copy
        curl -X POST "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice" \
          -H "Content-Type: application/json" \
          -H "client-id: YOUR_CLIENT_ID" \
          -H "api-key: YOUR_API_KEY" \
          -d '{
            "merchant": "Amazon",
            "yourCards": [
              "American Express Platinum",
              "Chase Sapphire Preferred"
            ],
            "spendAmount": 300
          }'
        
        NodeJS
        1. Install dependencies
        Copy
        npm install axios
        npm install --save-dev typescript @types/node
        1. Create recommendAdvice.ts
        Copy
        import axios from 'axios';
        
        // ---- POJO Type Definitions ----
        interface CardReward {
          cardName: string;
          rewardValue: number;
          rewardMultiplier: number;
          rewardAmount: number;
          bonus: number;
        }
        
        interface AdviceResponse {
          data: {
            bestCard: CardReward;
            otherCards: CardReward[];
          };
          message: string;
        }
        
        async function getRecommendationAdvice(): Promise<void> {
          const url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice";
          const headers = {
            "Content-Type": "application/json",
            "client-id": "YOUR_CLIENT_ID",
            "api-key": "YOUR_API_KEY"
          };
          const body = {
            merchant: "Amazon",
            yourCards: [
              "American Express Platinum",
              "Chase Sapphire Preferred"
            ],
            spendAmount: 300
          };
        
          try {
            const response = await axios.post<AdviceResponse>(url, body, { headers });
            const advice = response.data;
        
            // POJO mapping in action
            console.log("Best Card Advice:", advice.data.bestCard);
            advice.data.otherCards.forEach((card, i) => {
              console.log(`Other Card ${i + 1}:`, card);
            });
            console.log("Message:", advice.message);
        
            // Example individual field access:
            // console.log("Best card name:", advice.data.bestCard.cardName);
        
          } catch (error: any) {
            if (error.response) {
              console.error('API Error:', error.response.status);
              console.error('Error response body:', error.response.data);
            } else if (error.request) {
              console.error('No response received:', error.request);
            } else {
              console.error('Request setup error:', error.message);
            }
          }
        }
        
        // Run the function
        getRecommendationAdvice();
        

        The above example returns a strongly-typed POJO (AdviceResponse and CardReward)—true POJO mapping as in Java.

        Python

        Object oriented approach

        1. Define Python classes for POJO mapping
        Copy
        from typing import List, Optional
        
        class CardReward:
            def __init__(self, cardName: str, rewardValue: float, rewardMultiplier: float, rewardAmount: float, bonus: float):
                self.card_name = cardName
                self.reward_value = rewardValue
                self.reward_multiplier = rewardMultiplier
                self.reward_amount = rewardAmount
                self.bonus = bonus
        
            @classmethod
            def from_dict(cls, data):
                return cls(
                    cardName=data.get("cardName"),
                    rewardValue=data.get("rewardValue"),
                    rewardMultiplier=data.get("rewardMultiplier"),
                    rewardAmount=data.get("rewardAmount"),
                    bonus=data.get("bonus")
                )
        
            def __repr__(self):
                return (f"CardReward(card_name={self.card_name!r}, reward_value={self.reward_value}, "
                        f"reward_multiplier={self.reward_multiplier}, reward_amount={self.reward_amount}, bonus={self.bonus})")
        
        class AdviceResponse:
            def __init__(self, best_card: CardReward, other_cards: List[CardReward], message: str):
                self.best_card = best_card
                self.other_cards = other_cards
                self.message = message
        
            @classmethod
            def from_dict(cls, data):
                best_card = CardReward.from_dict(data["data"]["bestCard"])
                other_cards = [CardReward.from_dict(card) for card in data["data"].get("otherCards", [])]
                message = data.get("message", "")
                return cls(best_card, other_cards, message)
        
            def __repr__(self):
                return (f"AdviceResponse(best_card={self.best_card}, other_cards={self.other_cards}, message={self.message!r})")
        
        1. Request Function With Error Handling
        Copy
        import requests
        
        def get_recommendation_advice(client_id: str, api_key: str) -> Optional[AdviceResponse]:
            url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice"
            headers = {
                "Content-Type": "application/json",
                "client-id": client_id,
                "api-key": api_key
            }
            data = {
                "merchant": "Amazon",
                "yourCards": [
                    "American Express Platinum",
                    "Chase Sapphire Preferred"
                ],
                "spendAmount": 300
            }
            try:
                response = requests.post(url, json=data, headers=headers, timeout=10)
                response.raise_for_status()
                advice = AdviceResponse.from_dict(response.json())
                return advice
            except requests.exceptions.HTTPError as e:
                print(f"HTTP error occurred: {e} - Response body: {getattr(e.response, 'text', '')}")
            except requests.exceptions.ConnectionError as e:
                print("A connection error occurred:", e)
            except requests.exceptions.Timeout as e:
                print("Request timed out:", e)
            except requests.exceptions.RequestException as e:
                print("A general error occurred while making the request:", e)
            except Exception as e:
                print("Unexpected error:", e)
            return None
        
        1. Example Usage
        Copy
        if __name__ == "__main__":
            CLIENT_ID = "YOUR_CLIENT_ID"
            API_KEY = "YOUR_API_KEY"
        
            advice = get_recommendation_advice(CLIENT_ID, API_KEY)
            if advice:
                print("Best Card:")
                print(advice.best_card)
                print("\nOther Cards:")
                for card in advice.other_cards:
                    print(card)
                print("\nMessage:", advice.message)
        

        Using aiohttp async library with DTO validation

        Install prerequisites

        Copy
        pip install aiohttp pydantic
        Copy
        import asyncio
        import aiohttp
        from pydantic import BaseModel, ValidationError, conlist, constr, condecimal
        from typing import List, Optional
        
        # --- DTOs and Response Mapping ---
        
        class AdviceRequest(BaseModel):
            merchant: constr(min_length=1)
            yourCards: conlist(constr(min_length=2), min_items=1)
            spendAmount: condecimal(ge=0)
        
        class CardReward(BaseModel):
            cardName: str
            rewardValue: float
            rewardMultiplier: float
            rewardAmount: float
            bonus: float
        
        class AdviceData(BaseModel):
            bestCard: CardReward
            otherCards: List[CardReward]
        
        class AdviceResponseDTO(BaseModel):
            data: AdviceData
            message: str
        
        # --- Async Function ---
        
        async def get_recommendation_advice(client_id: str, api_key: str, request_body: AdviceRequest) -> Optional[AdviceResponseDTO]:
            url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice"
            headers = {
                "Content-Type": "application/json",
                "client-id": client_id,
                "api-key": api_key,
            }
        
            try:
                async with aiohttp.ClientSession() as session:
                    async with session.post(url, json=request_body.dict(), headers=headers, timeout=10) as resp:
                        print("Status:", resp.status)
                        resp_json = await resp.json()
                        if resp.status >= 200 and resp.status < 300:
                            try:
                                advice = AdviceResponseDTO.parse_obj(resp_json)
                                return advice
                            except ValidationError as ve:
                                print("Response validation error:", ve)
                        else:
                            print('API Error:', resp.status, resp_json)
            except asyncio.TimeoutError:
                print("Request timed out")
            except aiohttp.ClientConnectionError as e:
                print("Connection error:", e)
            except Exception as e:
                print("Error:", e)
            return None
        
        # --- Example usage ---
        
        async def main():
            CLIENT_ID = "YOUR_CLIENT_ID"
            API_KEY = "YOUR_API_KEY"
            try:
                # Validate DTO input before request!
                request_body = AdviceRequest(
                    merchant="Amazon",
                    yourCards=[
                        "American Express Platinum",
                        "Chase Sapphire Preferred"
                    ],
                    spendAmount=300
                )
            except ValidationError as ve:
                print("Input validation error:", ve)
                return
        
            advice = await get_recommendation_advice(CLIENT_ID, API_KEY, request_body)
            if advice:
                print("\nBest Card:")
                print(advice.data.bestCard)
                print("\nOther Cards:")
                for card in advice.data.otherCards:
                    print(card)
                print("\nMessage:", advice.message)
        
        if __name__ == "__main__":
            asyncio.run(main())
        

        How this works:

        • DTO Validation: Input (your request body) is validated with pydantic, ensuring correct schema before the request.
        • HTTP POST with aiohttp, with async/await for maximum efficiency.
        • Response Mapping: JSON result is mapped to a pydantic object (AdviceResponseDTO). Any validation error is clearly printed.
        • Error Handling: Handles timeouts, connection errors, and reports validation errors (both request and response)
        Java

        Spring Boot with WebFlux

        1. Add dependencies for Maven projects
        Copy
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <!-- Optionally, Lombok for POJOs: -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        
        1. POJO (DTO) classes
        AdviceRequest.java
        Copy
        import lombok.Data;
        import java.math.BigDecimal;
        import java.util.List;
        
        @Data
        public class AdviceRequest {
            private String merchant;
            private List<String> yourCards;
            private BigDecimal spendAmount;
        }
        
        CardReward.java
        Copy
        import lombok.Data;
        
        @Data
        public class CardReward {
            private String cardName;
            private double rewardValue;
            private double rewardMultiplier;
            private double rewardAmount;
            private double bonus;
        }
        
        AdviceData.java
        Copy
        import lombok.Data;
        import java.util.List;
        
        @Data
        public class AdviceData {
            private CardReward bestCard;
            private List<CardReward> otherCards;
        }
        
        AdviceResponseDTO.java
        Copy
        import lombok.Data;
        
        @Data
        public class AdviceResponseDTO {
            private AdviceData data;
            private String message;
        }
        

        WebClientServiceBean

        UthriveAdviceService.java
        Copy
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.http.HttpHeaders;
        import org.springframework.http.MediaType;
        import org.springframework.stereotype.Service;
        import org.springframework.web.reactive.function.client.WebClient;
        import org.springframework.web.reactive.function.client.WebClientResponseException;
        import reactor.core.publisher.Mono;
        
        @Service
        public class UthriveAdviceService {
        
            private final WebClient webClient;
        
            public UthriveAdviceService(
                    @Value("${uthrive.api.client-id}") String clientId,
                    @Value("${uthrive.api.api-key}") String apiKey
            ) {
                this.webClient = WebClient.builder()
                        .baseUrl("https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging")
                        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .defaultHeader("client-id", clientId)
                        .defaultHeader("api-key", apiKey)
                        .build();
            }
        
            public Mono<AdviceResponseDTO> getAdvice(AdviceRequest request) {
                return webClient.post()
                        .uri("/recommend/advice")
                        .bodyValue(request)
                        .retrieve()
                        .onStatus(status -> !status.is2xxSuccessful(),
                            response -> response.bodyToMono(String.class)
                                .flatMap(body -> Mono.error(new RuntimeException("Api error: " + body)))
                        )
                        .bodyToMono(AdviceResponseDTO.class)
                        .doOnError(WebClientResponseException.class, ex -> {
                            System.err.println("WebClientResponseException: " + ex.getRawStatusCode() + " " + ex.getResponseBodyAsString());
                        })
                        .doOnError(Exception.class, ex -> {
                            System.err.println("General exception: " + ex.getMessage());
                        });
            }
        }
        
        Controller
        Copy
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.http.ResponseEntity;
        import org.springframework.web.bind.annotation.*;
        import reactor.core.publisher.Mono;
        
        @RestController
        @RequestMapping("/api/uthrive")
        public class UthriveAdviceController {
        
            @Autowired
            private UthriveAdviceService adviceService;
        
            @PostMapping("/recommend/advice")
            public Mono<ResponseEntity<AdviceResponseDTO>> recommendAdvice(@RequestBody AdviceRequest request) {
                return adviceService.getAdvice(request)
                        .map(ResponseEntity::ok)
                        .onErrorResume(e -> Mono.just(ResponseEntity.badRequest().body(null)));
            }
        }
        

        Configure your credentials In application.properties or application.yml

        Copy
        uthrive.api.client-id=YOUR_CLIENT_ID
        uthrive.api.api-key=YOUR_API_KEY
        
        Android
        1. Add dependencies in your build.gradle
        Copy
        implementation 'com.squareup.okhttp3:okhttp:4.10.0'
        implementation 'com.google.code.gson:gson:2.10.1'
        
        1. Create POJO(DTOs) for mapping
        AdviceRequest.java
        Copy
        import java.util.List;
        
        public class AdviceRequest {
            private String merchant;
            private List<String> yourCards;
            private double spendAmount;
        
            public AdviceRequest(String merchant, List<String> yourCards, double spendAmount) {
                this.merchant = merchant;
                this.yourCards = yourCards;
                this.spendAmount = spendAmount;
            }
            // getters and setters (or use Lombok)...
        }
        
        CardReward.java
        Copy
        public class CardReward {
            private String cardName;
            private double rewardValue;
            private double rewardMultiplier;
            private double rewardAmount;
            private double bonus;
        
            // getters and setters...
        }
        AdviceData.java
        Copy
        import java.util.List;
        
        public class AdviceData {
            private CardReward bestCard;
            private List<CardReward> otherCards;
        
            // getters and setters...
        }
        
        AdviceResponseDTO.java
        Copy
        public class AdviceResponseDTO {
            private AdviceData data;
            private String message;
        
            public AdviceData getData() { return data; }
            public String getMessage() { return message; }
        }
        

        Service class

        UthriveAdviceService.java
        Copy
        import android.util.Log;
        
        import com.google.gson.Gson;
        import com.google.gson.JsonSyntaxException;
        
        import java.io.IOException;
        import java.util.concurrent.Executor;
        import java.util.concurrent.Executors;
        
        import okhttp3.*;
        
        public class UthriveAdviceService {
            private final String url = "https://h0n277p4vd.execute-api.us-east-1.amazonaws.com/staging/recommend/advice";
            private final OkHttpClient client = new OkHttpClient();
            private final Gson gson = new Gson();
            private final String clientId;
            private final String apiKey;
            private final Executor executor = Executors.newSingleThreadExecutor();
        
            public UthriveAdviceService(String clientId, String apiKey) {
                this.clientId = clientId;
                this.apiKey = apiKey;
            }
        
            public interface Callback {
                void onSuccess(AdviceResponseDTO advice);
                void onError(Exception e);
            }
        
            public void getRecommendationAdvice(AdviceRequest adviceRequest, Callback callback) {
                executor.execute(() -> {
                    try {
                        RequestBody body = RequestBody.create(
                                gson.toJson(adviceRequest),
                                MediaType.get("application/json; charset=utf-8")
                        );
        
                        Request request = new Request.Builder()
                                .url(url)
                                .post(body)
                                .addHeader("Content-Type", "application/json")
                                .addHeader("client-id", clientId)
                                .addHeader("api-key", apiKey)
                                .build();
        
                        try (Response response = client.newCall(request).execute()) {
                            if (response.isSuccessful() && response.body() != null) {
                                String responseStr = response.body().string();
                                try {
                                    AdviceResponseDTO adviceResp = gson.fromJson(responseStr, AdviceResponseDTO.class);
                                    callback.onSuccess(adviceResp);
                                } catch (JsonSyntaxException je) {
                                    callback.onError(new Exception("Response parsing error: " + je.getMessage()));
                                }
                            } else {
                                callback.onError(new Exception("API Error: Code " + response.code() + " Body: " +
                                        (response.body() != null ? response.body().string() : "")));
                            }
                        }
                    } catch (IOException e) {
                        callback.onError(new Exception("Network error: " + e.getMessage(), e));
                    } catch (Exception e) {
                        callback.onError(e);
                    }
                });
            }
        }
        
        Use in your Activity/Fragment
        Copy
        import android.os.Bundle;
        import androidx.appcompat.app.AppCompatActivity;
        import java.util.Arrays;
        
        public class MainActivity extends AppCompatActivity {
        
            private static final String CLIENT_ID = "YOUR_CLIENT_ID";
            private static final String API_KEY = "YOUR_API_KEY";
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
        
                UthriveAdviceService service = new UthriveAdviceService(CLIENT_ID, API_KEY);
        
                AdviceRequest req = new AdviceRequest(
                    "Amazon",
                    Arrays.asList("American Express Platinum", "Chase Sapphire Preferred"),
                    300.0
                );
        
                service.getRecommendationAdvice(req, new UthriveAdviceService.Callback() {
                    @Override
                    public void onSuccess(AdviceResponseDTO advice) {
                        runOnUiThread(() -> {
                            // Access POJO fields
                            if (advice != null && advice.getData() != null) {
                                CardReward best = advice.getData().getBestCard();
                                if (best != null) {
                                    System.out.println("Best card: " + best.getCardName() + " Reward: " + best.getRewardAmount());
                                }
                                // And so on...
                            }
                        });
                    }
        
                    @Override
                    public void onError(Exception e) {
                        runOnUiThread(() -> {
                            System.err.println("Error: " + e.getMessage());
                        });
                    }
                });
            }
        }
        

        Error Responses

        HTTP CodeDescriptionExample Response
        400Malformed or incomplete input{ “message”: “Invalid request body” }
        401Authentication failed{ “message”: “Unauthorized” }
        500Internal server error{ “message”: “Internal error” }

        Usage

        • The Merchant must match a recognized merchant in Uthrive’s system for best results.
        • yourCards must be an array of the user’s actual card names (must match Uthrive’s supported list).
        • All returned reward calculations assume the provided spend amount and merchant.
        • Use this endpoint for real-time “which card should I use?” advice in apps, widgets, or POS scenarios.
        Uthrive U Log It's Your Money! Uthrive QR

        Download The App

        Point your phone camera to scan the code

        Best Credit Cards

        • Best balance transfer credit cards
        • Best Cash Back credit cards
        • Best 0% APR Credit Cards
        • Best No Annual Fee Credit Cards
        • Best Rewards Credit Cards
        • Best Airlines Credit Cards
        • Best Hotel Credit Cards
        • Best Credit Cards For Groceries
        • Best Credit Cards For Streaming Services
        • Best Credit Cards For Gas
        • Best Credit Cards For Online Shopping
        • Best Credit Cards For Healthcare

        Credit Cards Rewards

        • Credit Card Reward Programs
        • American Express Membership Rewards
        • Chase Ultimate Rewards
        • Capital One Miles
        • Citi ThankYou Points
        • Bank Of America Travel Rewards

        Credit Card Benefits

        • Costco credit card benefits
        • Amazon credit card benefits
        • Apple credit card benefits
        • Southwest credit card benefits
        • United credit card benefits
        • Delta credit card benefits
        • Home depot credit card benefits

        Best Airline Reward Programs

        • American Airlines AAdvantage Program
        • United Airlines MileagePlus
        • Delta SkyMiles
        • Southwest Rapid Rewards

        Best Hotel Reward Programs

        • Hyatt Rewards Program
        • Mariott Bonvoy Rewards Program
        • Hilton Rewards Program
        • Best Western Rewards Program

        Best Business Credit Cards

        • American Express Business Credit Cards
        • Capital One Business Credit Cards
        • Chase Business Credit Cards
        • Bank Of America Business Credit Cards

        Best Balance Transfer Credit Cards

        • What Is A Balance Transfer
        • Balance Transfer Credit Card With Bad Credit
        • Balance Transfer Credit Card Mistakes

        Refer A Friend

        • American Express Refer A Friend Bonuses
        • Capital One Refer A Friend Program
        • Chase Refer A Friend Bonuses
        • Citi Credit Card Refer A Friend

        Credit Card Pro Series

        • Credit card management app
        • Credit card referral
        • Best credit card for Airbnb
        • Best credit card for Uber
        • Best credit card for Walmart
        Best Credit Cards Caret Down
        • Best balance transfer credit cards
        • Best Cash Back credit cards
        • Best 0% APR Credit Cards
        • Best No Annual Fee Credit Cards
        • Best Rewards Credit Cards
        • Best Airlines Credit Cards
        • Best Hotel Credit Cards
        • Best Credit Cards For Groceries
        • Best Credit Cards For Streaming Services
        • Best Credit Cards For Gas
        • Best Credit Cards For Online Shopping
        • Best Credit Cards For Healthcare
        Credit Cards Rewards Caret Down
        • Credit Card Reward Programs
        • American Express Membership Rewards
        • Chase Ultimate Rewards
        • Capital One Miles
        • Citi ThankYou Points
        • Bank Of America Travel Rewards
        Credit Card Benefits Caret Down
        • Costco credit card benefits
        • Amazon credit card benefits
        • Apple credit card benefits
        • Southwest credit card benefits
        • United credit card benefits
        • Delta credit card benefits
        • Home depot credit card benefits
        Best Airline Reward Programs Caret Down
        • American Airlines AAdvantage Program
        • United Airlines MileagePlus
        • Delta SkyMiles
        • Southwest Rapid Rewards
        Best Hotel Reward Programs Caret Down
        • Hyatt Rewards Program
        • Mariott Bonvoy Rewards Program
        • Hilton Rewards Program
        • Best Western Rewards Program
        Best Business Credit Cards Caret Down
        • American Express Business Credit Cards
        • Capital One Business Credit Cards
        • Chase Business Credit Cards
        • Bank Of America Business Credit Cards
        Best Balance Transfer Credit Cards Caret Down
        • What Is A Balance Transfer
        • Balance Transfer Credit Card With Bad Credit
        • Balance Transfer Credit Card Mistakes
        Refer A Friend Caret Down
        • American Express Refer A Friend Bonuses
        • Capital One Refer A Friend Program
        • Chase Refer A Friend Bonuses
        • Citi Credit Card Refer A Friend
        Credit Card Pro Series Caret Down
        • Credit card management app
        • Credit card referral
        • Best credit card for Airbnb
        • Best credit card for Uber
        • Best credit card for Walmart

        About

        • Our Story
        • Uthrive in Media

        Help

        • Help
        • support@Uthrive.club

        Legal

        • Terms & Conditions
        • Privacy Policy

        All corporate logos and trademarks are for illustrative purposes only and are not a recommendation, an offer to sell, or a solicitation of an offer. Trademarks and logos are the property of their respective owners and do not represent endorsements of any kind. Examples and/or pictures above are for illustrative purposes only and are not real customers. View our Disclaimer for more details.

        © Copyright 2022 Uthrive Inc. All rights reserved.

        Always use Best card + Savings
        Offers on Purchases
        ✕
        Unlock $800+, Don't leave it on the table
        Open the App
        Verifying...

        Sign in to Uthrive

        No more passwords to remember. Signing in is fast, simple and secure.

        * I agree with Terms & Conditions and Privacy Policy of Uthrive. View more >
        I understand that I am providing written instructions in accordance with the Fair Credit Reporting Act and other applicable law for Uthrive to request and receive information about me from third parties, including but not limited to a copy of my consumer report and score from consumer reporting agencies, at any time for so long as I have an active Uthrive account. I further authorize Uthrive to retain a copy of my credit information for it’s use and to match with credit products.
        View less
        Always use Best card + Savings Offers on Purchases
        Don't leave your money on the table
        Scan to
        Download
        The App.
        Uthrive
        Proudly powered by WordPress.