> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.upwardli.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.upwardli.com/_mcp/server.

# Credit Builder Card Embedded Documentation

> **Info**
>
> **Please note:**  If your company is integrating our Card product using embedded pages, you’re in the right spot!

## Overview

Upward provides a seamless and secure way for businesses to enable a credit building card to their end users. End users can incorporate credit building into their daily activities by loading money to their FDIC insured DDA account and then swiping their card at any location where Mastercard is accepted. Upward’s platform customers are able to monetize the card through interchange, deposit interest, and expedited external payments.

---

# Introduction

Welcome to the Credit Builder Card! Our documentation will walk you through the basics (authentication, request structure) to using and creating the financial products associated with the Credit Builder Card (accounts, cards, payments, etc.).

The introduction covers basic concepts you should be familiar with in order to make the most out of the Upward card issuance and management platform.

---

## How the Credit Builder Card Works

![Credit Builder Card Diagram](/_fern-img/e79028e2259f1170c9324172b0d06303c679a1fe3a0e372e502a76d4f8501fef.webp)

* The card’s available credit is equal to:
  * the available funds that the user maintains in a linked deposit account, plus
  * any verified incoming payments to the user, such as payments due for wages or gig work
* The user may obtain a physical, digital card or both. The user makes purchases anywhere Mastercard is accepted.
* As the user makes purchases on the card, an equal amount of funds in the linked deposit account are put on hold, and the card’s available credit decreases in an equal amount.
* The cardholder may opt in to automatic payments to pay off balances as they incur charges, but must pay the card’s balance in full on the payment due date.
* If the balance is not paid on time and the DDA balance is at zero the card will freeze until the user has made a payment.
* By default, there are no fees to use the card and the user is charged 0% APR.

---

## Implementation Options

Upward offers three ways to integrate the credit builder card into your website or mobile app for your credit program.

* **Use Credit Builder Card APIs**. When integrating credit builder cards into your own website or app, this option offers flexibility in designing a unique user experience including the credit services and financial products you wish to offer. This option provides a secure, PCI-compliant, customizable experience for purchasing and providing basic banking services (i.g statements, transaction, history, card management, etc).
* **Use our Embedded Integration.** The embedded flow is a drop-in module that enables you to seamlessly offer a credit builder card within your app or web page. It allows individuals to easily access their credit and credit builder card details securely without redirecting away from your app or website.
* **Leverage an Upward Hosted App**. If you do not want to build and host a credit account and banking experience, Upward can handle the product build and push to your app store instance. This approach offers less flexibility and, while easier to implement, it requires higher platform fees.

---

# Environments

**There are two types of environments for the Upward Credit Suite:**

1. **Sandbox**\
   You can test out your integration and explore common usage patterns in our sandbox environment. This environment is fully isolated and will not perform any “live” financial transactions.

You can request sandbox access once you have a signed contract.

> **Info**
>
> **Important:** The Sandbox environment is fully secure, but you
> should not store any real consumer data here.

2. **Production**\
   Once you have completed [sandbox testing](/concepts/working-in-sandbox/introduction) and submitted your test plans, you will be provisioned production access keys. These details will be shared with you via a secure sharing mechanism. All transactions in our production environment are live financial activity.

## Getting Started

Regardless of which method you choose for integration you will always need to follow our authentication methods.

### Authentication

Upward’s API uses OAuth 2.0 to authenticate requests. All API calls must include a token. These authentication tokens are used for machine to machine communication.

> **Info**
>
> **Note:** An invalid, missing or expired token will result in an
> \{invalid\_token} response

## URLs

> **Info**
>
> Environment URL Sandbox Authentication [https://auth-sandbox.upwardli.com/auth/token](https://auth-sandbox.upwardli.com/auth/token)
>
> Production Authentication [https://auth.upwardli.com/auth/token](https://auth.upwardli.com/auth/token)

## Tokens

Upward has the concept of three different tokens:

* **Customer Onboarding Tokens**: are system level and assigned to a specific organization that allows you to onboard new users. Once a user is onboarded you would use the customer token to access their specific information.
* **Customer Access Tokens:** are specific to an end user also known as consumers in our product and only provide data specific to that consumer. These tokens are used to secure our embedded components.
* **Partner API Tokens:** are highly secure tokens that are used to integrate your backend platform with Upward’s APIs. These tokens **SHOULD NOT BE USED OUTSIDE OF DIRECT API CALLS BETWEEN YOUR SYSTEM AND UPWARD.**

When a token is created, it is assigned a set of Scopes. The scopes define the resources that can be accessed using the token, and the access level (read/write) that will be allowed using that token.

> **Info**
>
> **NOTE ON TOKEN EXPIRATION**:
> Partner API Tokens **expire after 10 hours** **have elapsed since creation**, and Customer Access Tokens expire after 1 hour
>
> If a new token is not requested then it will result in a 403 screen.

## Scopes

Scopes define the access level of a token.

**A list of all scopes within Upward:**

| Scope                        | Token Type            | Use                                                                        |
| ---------------------------- | --------------------- | -------------------------------------------------------------------------- |
| `api:read`                   | Partner API Token     | Used to perform read actions on the platform                               |
| `api:write`                  | Partner API Token     | Used to perform full CRUD operations on the platform                       |
| `ui:client-onboarding`       | Partner API Token     | Used for the client onboarding component                                   |
| `api:card-management:read`   | Customer Access Token | Used to populate all card-management pages, card image                     |
| `api:card-management:write`  | Customer Access Token | Perform card management actions (pin change, freeze/unfreeze, lost/stolen) |
| `api:consumer-profile:read`  | Customer Access Token | Used to populate all profile pages (dispute, statements)                   |
| `api:consumer-profile:write` | Customer Access Token | Used for account closing                                                   |
| `api:credit-goals:read`      | Customer Access Token | Used to populate credit goals page                                         |
| `api:purchase:write`         | Customer Access Token | Create an ACH transfer in and out of an individual’s account               |
| `api:purchase:read`          | Customer Access Token | Retrieve an ACH transaction history for an individual                      |
| `api:statements:read`        | Customer Access Token | Retrieve statements directly                                               |
| `api:accounts:read`          | Customer Access Token | Get bank accounts                                                          |
| `api:accounts:write`         | Customer Access Token | Create bank accounts                                                       |
| `api:simulated-card:write`   | Customer Access Token | Simulate funding/auth/settlement                                           |

### Embedded Component Endpoints

**The Credit Builder Card API provides access to several different types of detail.**

**You decide which of the experiences you want to include:**

| Experiences          | URL / Endpoint(s)                                                                                                                      | Description                                                                                                         |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Onboarding           | `https://component-embedded-sandbox.upwardli.com/en/onboarding/card-product/?pcid={$partner_consumer_id}&access_token={$access_token}` | End to End Onboarding                                                                                               |
| Initial ACH transfer | `https://component-embedded-sandbox.upwardli.com/en/onboarding/transfer/?access_token={userscopetoken}`                                | After onboarding is complete and payment card is created you can push the consumer to this page to fund the account |
| Card Management      | `https://component-embedded-sandbox.upwardli.com/card-management?access_token={userscopetoken}`                                        | Home Card Details Transactions Card Management Add External Accounts                                                |
| Payments             | *Coming soon* – available through card management or via API only. No stand-alone option for external transfers is available today     | Transfer Funds                                                                                                      |
| Credit Goals         | `https://component-embedded-sandbox.upwardli.com/en/credit-goals/?access_token={userscopetoken}`                                       | Credit Insights Credit Guides                                                                                       |
| Profile              | `https://component-embedded-sandbox.upwardli.com/consumer-profile/?access_token={userscopetoken}`                                      | Full Profile                                                                                                        |
| Card image           | `https://component-embedded-sandbox.upwardli.com/card-image?access_token={userscopetoken}`                                             | Virtual card image                                                                                                  |
| Card actions         | `https://component-embedded-sandbox.upwardli.com/card-actions?access_token={userscopetoken}`                                           | Display card actions                                                                                                |
| Pin reset            | `https://component-embedded-sandbox.upwardli.com/card-pin-reset?access_token={userscopetoken}`                                         | Display to set/update a card pin                                                                                    |
| Rewards              | `https://component-embedded-sandbox.upwardli.com/en/rewards?access_token={userscopetoken}&latitude={latitude}&longitude={longitude}`   | Display rewards and location-based offers                                                                           |

## Requesting Tokens Using The API

The Upward API uses OAuth 2.0 for authentication and authorization. Before you can use the API, you must obtain an access token using the client\_id and client\_secret provided to you. Once a token has been obtained, it must be passed in the Authorization header of each request to the API.

## Customer Onboarding Token Request

To request a token send a POST to our auth server containing your client ID and client secret values.

POST [https://auth-sandbox.upwardli.com/auth/token/](https://auth-sandbox.upwardli.com/auth/token/)

```json
{
  "header": "content-type: application/json",
  "grant_type": "client_credentials",
  "client_id": "[your id here]",
  "client_secret": "[your secret here]",
  "scope": "ui:client-onboarding"
}
```

Here’s a cURL example for the token request:

```json
POST https://auth-sandbox.upwardli.com/auth/token/ \

    --header 'Content-Type: application/json' \
    --data \
'{
    "grant_type":"client_credentials",
    "client_id":"[api client key]",
    "client_secret":"[api client secret]",
    "scope":"api:read api:write ui:client-onboarding"
}'

curl --location 'https://auth-sandbox.upwardli.com/auth/token/' \
--header 'Content-Type: application/json' \
--data '{
    "grant_type": "client_credentials",
    "client_id": "XXXXXX",
    "client_secret": "XXXXXX",
    "scope":"api:read api:write ui:client-onboarding"
}'
```

Here’s what a successful response looks like:

```json
{
  "access_token": "xxxxx",
  "expires_in": 86400,
  "token_type": "Bearer",
  "scope": "api:read api:write ui:client-onboarding"
}
```

## Exchanging Partner API Token for a Customer Token

Once a valid token has been obtained using the Authentication API, a limited scope token can be obtained using the token exchange API. This token can be used to make requests for a specific consumer, and is safe to send to the client application/web browser as needed.

To request a token exchange send a POST to our auth server containing the access\_token and requested scope.

> **Info**
>
> This token expires after 1 hour and will need to be exchanged for a new token for the customer to continue to have access.

**Notes:**

* The audience must be for the correct Environment.
  * Sandbox: `https://auth-sandbox.upwardli.com`
  * Production: `https://auth.upwardli.com`
* The upward\_consumer\_id is the Upward id that you get from the Consumer API or the `consumer.created` webhook.
* The new access token is a significantly longer string than the original access token.

POST [https://auth-sandbox.upwardli.com/auth/token/exchange/](https://auth-sandbox.upwardli.com/auth/token/exchange/)

```json
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
    "grant_type":"urn:ietf:params:oauth:grant-type:token-exchange",
    "subject_token_type":"urn:ietf:params:oauth:token-type:access_token",
    "subject_token":"[access_token]",
    "audience":"https://auth-sandbox.upwardli.com",
    "scope":"<See scopes table> consumer:[upward_consumer_id]"
}
```

Here’s what a successful response looks like:

```json
{
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "[scoped access token]",
  "scope": "<Scope(s)>",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}
```

---

## Onboarding a New User

A consumer is the individual end user that you are creating a credit product. Consumers are limited to individuals using a valid SSN or ITIN, or single-member LLCs (coming soon).

A Consumer record is automatically created once an application is started and Upward will manage the ongoing regulatory requirements tied to application notice, approval and denial notifications to the end user.

Consumer onboarding is a fully asynchronous process due to the KYC and Banking integrations, which are themselves asynchronous. Our design goal for customers interacting with the Onboarding component is to capture data in realtime, and then process asynchronously. This will reduce elapsed consumer interaction time and improve the customer experience.

> **Info**
>
> NOTE: we recommend listening to [webhooks](/concepts/webhooks/introduction). to be notified of the status of each consumer as they make their way through the application and approval process. You will have access to the consumers financial products once they have been fully onboarded and approved.

All consumers are created as part of our onboarding. Regardless of the integration method you’ll need to use our embedded iframe to offer our application flow. We do allow you to customize the UI of the application but to ensure consistent and fair lending practices we own the specific language and disclosures surrounding the application process.

---

### Authentication & Loading the Onboarding Embedded Flow

Authentication

***Tip: Your API Key and Secret will be shared with you by your Upward client team.***

The first step in integrating your product is to configure authentication. All Upward components and APIs require Oauth tokens for access.

**Important Parameters**

| Parameter      | Value                     | Notes                                                                                                                                                                                                |
| -------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pcid`         | Guid or Similar           | A consumer-specified unique ID. This id value maps to an ID or identifier that your platform stores for this user. This value can be used later to identify Consumers using an ID that you control.  |
| `access_token` | Customer Onboarding Token | A token with the scope `ui:client-onboarding`. You can use this parameter if the platform you are developing on does not allow you to inject the token directly into the web component or web frame. |
| `redirect_url` | URL                       | *(optional)* The url to redirect the web component to once the consumer has completed their onboarding.                                                                                              |

Next, you load the onboarding embedded component in your app using URL below and the a Customer Onboarding Token with the ui:client-onboarding scope.

```javascript
https://component-embedded-sandbox.upwardli.com/en/onboarding/card-product/?pcid={$partner_consumer_id}&access_token={$access_token}
```

When you load the onboarding embedded component, pass in the PCID property (your unique ID) as a query parameter and be sure to include the correct access token.

Once the consumer clicks “Get Started”, the UI component creates their consumer record using the Consumer API endpoint. The user’s pcid will be set to the value you provide us, and we will generate a unique id on our side to identify this record internally and within our APIs.

**Upward sends out a consumer.created webhook message to your server.** The Upward Servers will send a webhook message to you with the following general schema, indicating that the consumer record was created on our side.

```json
{
  "id": "ea04f0a8-b005-47cd-ba33-b02a00c0c426",
  "created_at": "2023-06-23T07:41:50.45-04:00",
  "event_name": "consumer.created",
  "partner_id": "2f221c90-b82d-4e12-9bfd-ae8301097de3",
  "resources": ["https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}"],
  "last_attempted_at": "2023-06-23T07:41:50.45-04:00"
}
```

**You Link the Upward ID to your Local Object.** Upon receiving the webhook message, you will parse it for the eventName property and determine that this message means that a new consumer was created. You can then call the url in the resources property to get information about that consumer.

Example of output via API - assuming the consumer stopped before complete KYC and that you did not pre-fill any data for that user.

```json
{
    "id": "{consumer_id}",
    "pcid": "{pcid}",
    "first_name": null,
    "last_name": null,
    "email": null,
    "is_active": true,
    "kyc_status": "NotStarted",
    "phone_number": null,
	  "date_of_birth": null,
	  "tax_id_type": "SSN",
	  "tax_identifier": null,
	  "address_line1": null,
	  "address_line2": null
    "address_city": null,
    "address_state": null,
    "address_zip": null
}
```

> **Info**
>
> NOTE: At the time of creation, the user has not completed KYC, so their
> personal data has not been captured and will be null in the response body.

**Example**

The following is an example of how to load the onboarding UI Component in a react native application.

```javascript
export default function OnboardingScreen({ route }: Props) {
  const url =
    "https://component-embedded-sandbox.upwardli.com/en/onboarding/card-product/?pcid={$partner_consumer_id}&access_token={$access_token}";
  return (
    <SafeAreaView>
      <View>
        <JwtAuthWebview url={url} />
      </View>
    </SafeAreaView>
  );
}
```

## Onboarding Flow UI Specifics

The details below outline the flow of onboarding a consumer:

1. Get Started
2. Create Consumer
3. Accept Terms, and
4. Ordering a Card.

### Step 1: Get Started

Each consumer will see an entry screen that will highlight the value props and also include the appropriate disclaimers for the product.

### Step 2: Create Consumer

The create consumer step is where we will initiate a consumer record, collect and verify KYC details, as well as complete required PEP and OFAC scans.

> **Info**
>
> We provide the option to pre-fill data for your consumer to reduce onboarding
> friction. If you want to pre-fill data for your consumer see the section
> entitled: *“KYC Data Pre-Fill”* below.

![KYC Details](/_fern-img/c75aaed43ce053a50e50a0d06c2f14eb021928ba28429808769975aa5e9bcf1b.webp)

**Consumer Completes the KYC step(s)**

Once the user has successfully completed KYC, then we will send a further webhook with an event\_name of consumer.updated

```json
{
  "id": "ea04f0a8-b005-47cd-ba33-b02a00c0c426",
  "created_at": "2023-06-23T07:41:50.45-04:00",
  "event_name": "consumer.updated",
  "partner_id": "2f221c90-b82d-4e12-9bfd-ae8301097de3",
  "resources": ["https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}"],
  "last_attempted_at": "2023-06-23T07:41:50.45-04:00"
}
```

When you retrieve the updated consumer record related to this webhook, you will see that the kyc\_status value has changed to `"kyc_status": "Complete"`, indicating that this consumer has successfully completed the KYC step. In some cases, we will need to complete a manual review of the information provided by the consumer.

This webhook will also allow you to see the KYC information that was provided by the consumer when completing this step. We do not provided the full tax\_identifier.

> **Info**
>
> NOTE: KYC completed does not mean the consumer has completed onboarding or
> that a card product has been provisioned.

```json
{
  "id": "{consumer_id}",
  "pcid": "{pcid}",
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@gmail.com",
  "is_active": true,
  "kyc_status": "Complete",
  "phone_number": "+12065559034",
  "date_of_birth": "2000-01-01",
  "tax_id_type": "SSN",
  "tax_identifier": "***-**-1234",
  "address_line1": "100 Main Street",
  "address_line2": null,
  "address_city": "Tuscaloosa",
  "address_state": "AL",
  "address_zip": "354050000"
}
```

> **Info**
>
> **TIP:** If you do not receive the webhook you can call the Consumer endpoint to retrieve the consumer details.
>
> GET [https://api-sandbox.upwardli.com/v2/consumer/\{id}](https://api-sandbox.upwardli.com/v2/consumer/\{id})

**Optional: KYC Data Pre-Fill**

Before loading the embedded component, you can pre populate data for a consumer by calling the api: POST: [https://api-sandbox.upwardli.com/v2/consumer/](https://api-sandbox.upwardli.com/v2/consumer/) and providing the following fields:

```json
{
    "pcid": "{pcid}",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@email.com",
    "phone_number": "+12065559034",
    "date_of_birth": "2000-01-01",
    "address_line1": "100 Main Street",
    "address_line2": "Apt 123"
    "address_city": "Tuscaloosa",
    "address_state": "AL",
    "address_zip": "354050000"
}
```

> **Info**
>
> If you are pre-filling you will need to use the xx token with xx scope to
> correctly send the details. You can also partially send information, however,
> you will always be required to send the PCID field.

![Pre-filled KYC](/_fern-img/b3de44997b47d6e1f85f74cc9c8687e6334858e1da373d93d6dfa351a5a6cffc.webp)

**Edge Cases / Unhappy path:**

1. If a user does not complete KYC, then you will only receive the consumer.created message
2. If a user fails KYC, then we will send a consumer.updated webhook, with a kyc\_status value of Failed. We will not open a credit line for any users who do not pass KYC.

### Step 3: Accept the Credit Card Terms

A user will naturally be sent through to accept the terms of the product -

\*\*However\*\* if a user doesn’t complete KYC or drops off during the signup process, you can restart the session by sending a new unexpired token with the PCID for that consumer and the the correct scopes for accessing onboarding. This will ensure the consumer is dropped back to the right portion of the app.

Example:

> **Info**
>
> [https://component-embedded-sandbox.upwardli.com/en/onboarding/card-product/?pcid=](https://component-embedded-sandbox.upwardli.com/en/onboarding/card-product/?pcid=)
> \{\$partner\_consumer\_id}\&access\_token=\{\$access\_token}

![Accept Terms](/_fern-img/6bfb00cb23b545bc4716f2839f6818876291b3538a02d01da70ff3b60f2efe9b.webp)

### Step 3: Card Selection & Ordering

A user will naturally be sent through to order either a digital or physical card. If they select a physical card they will be asked to verify their shipping address. Once they confirm their card type onboarding will be completed.

**A user will see a success screen.**

![Choose Card Type](/_fern-img/2bfa86481edc8d952b71f2e415ca2a13a154846427572437d6246ccf8c02f813.webp)![Confirm Shipping](/_fern-img/d3a62df07aab3cb4300ec4f71776c5eb3cd6845898caddc40ed4eee653e1c01d.webp)![On The Way](/_fern-img/4eae6be14e056f42814c5b0a35c714e094ab298193ae2954708fb9c1b37045c3.webp)

**After onboarding completion**

* If the partner has provided a redirect\_url the consumer will be redirected.
* Upward will also send an onboarding-success message to parent iFrame.
* A partner can implement a listener to take action from this event.
* The consumer bank account and card may not be open at this point while we are completing the onboarding with the bank. Once the accounts and card are provisioned you will receive a webhook message called PaymentCard.Created
* If a user doesn’t order a physical to start they can order under card management. A partner can order on behalf of a user by calling the card.order API

## iFrame Messaging

As the consumer completes the onboarding flow you’ll receive iFrame message from our component.

Get started page → KYC

```javascript
component.navigation;
{
  KYC: "NotStarted";
  component: "onboarding";
  path_from: "onboarding/card-product";
  path_to: "/onboarding/card-product/verify-identity";
}
```

KYC → Terms

```javascript
{
	...
	path_to: "/onboarding/card-product/terms"
}
```

Terms → Card Confirmation

```javascript
{
	...
	path_to: "/onboarding/card-product/card-confirmation"
}
```

Card Confirmation → Confirm Shipping

```javascript
{
	...
	path_to: "onboarding/card-product/confirm-shipping"
}
->
{
	...
	path_to: "onboarding/card-product/on-the-way"
}
```

Card Confirmation (Digital) → on-the-way

```javascript
{
	...
	path_to: "onboarding/card-product/on-the-way"
}
```

On the way → partner

```javascript
component.closed;
{
  KYC: "NotStarted";
  component: "onboarding";
  path_from: "onboarding/card-product/on-the-way";
  path_to: undefined;
}
```

Example: View all message in the browser

```javascript
window.addEventListener(
  "message",
  (event) => {
    const { Event, body } = event.data;

    switch (Event) {
      case "component.navigation":
        console.log("Navigation detected", body);
        break;

      case "component.closed":
        console.log("The component was closed", body);
        break;

      case "component.alert":
        console.log("Alert received", body);
        console.log(body.message || "Component alert");
        break;

      default:
        console.warn("Unknown event received:", Event);
    }
  },
  false
);
```

# Post Onboarding Display Options

## Plaid + UPW

1. You need a hosted link url from UPW to open the Plaid flow
2. UPW will send an iframe message to the parent frame with a plaid.token event
   1. `"hostedLinkUrl": "https://secure.plaid.com/hl/ls948q0pr159oo9qq0ns8p951n5o83686q"`
3. After receiving the hosted link
4. You’ll need to open a [secure.plaid.com](http://secure.plaid.com/) browser with the hosted link
5. UPW plaid will send out `upwardli://plaid-link` url schema message to notify you when to close the [secure.plaid.com](http://secure.plaid.com/) browser
6. You’ll need add a listener for this url schema (plaid completion\_redirect\_uri) to close the browser
7. Here is the code example.

```typescript
# Plaid completion/close browser
const handleUrl = ({ url }: { url: string }) => {if (url.includes("plaid-link")) { WebBrowser.maybeCompleteAuthSession(); } };
```

### Account ownership verification

After an account is linked, Upward runs a Plaid identity match to confirm the account belongs to the consumer. If the account holder's name does not match the consumer on file, the account is set to `verification_failed` and deactivated, the consumer is emailed, and the [`Consumer.BankAccount.VerificationFailed`](/concepts/webhooks/event-catalog#bank-account-management-webhooks) webhook is sent.

In sandbox this check passes automatically. To test the failure path, link an account for a consumer named **Alexander Upward** (`first_name` `Alexander`, `last_name` `Upward`) — the identity match will fail for that consumer. Any other name passes, and the comparison is not case-sensitive.

## Onboarding options

Once a consumer is onboarded you have two option to display consumer account and card details.

1. **Embedded widget** - we display the UI for you in our hosted components, you have control over the look and feel but not the layout.
2. **API** - you query our platform for the raw data and have full control of how you display it in your own UI (beyond what is listed in the box below)

> **Info**
>
> For PCI reasons you will also need to use our embedded widget for Card Display
> and Card Management such as PIN reset, Freeze / Unfreeze, and Lost / Stolen
> options.

## Card Management

The card management widget is intended to give consumers the ability to view their card, update actions tied to their card (transaction history, PIN set, ATM locator, freeze a card). A consumer will also be able to view their credit score, see statements, make payments and initiate transfers.

## **Card Management via Embedded Widget**

To display the Card Management embedded widget you will follow the same authentication steps that are used to access the initial onboarding form.

Next, you load the card management embedded component in your app using URL below and the a **Customer Access Token** with the api:card-management:read.

**Important Parameters**

| Parameter     | Value                 | Notes                                                                                         |
| ------------- | --------------------- | --------------------------------------------------------------------------------------------- |
| access\_token | Customer Access Token | A token that when used with the scope `api:card-management:read`                              |
| url           | URL                   | `https://component-embedded-sandbox.upwardli.com/card-management?access_token={access_token}` |

Once a user has completed onboarding you will have the ability to display the card management embedded widgets. You can either pull the home screen directly or have individual entry points for each of these experiences

**The details below outline the 3 primary experiences associated with card management:**

1. “Home” experience
2. Card Management
3. Card & Transaction Details

### **Home Experience**

> **Info**
>
> Home - This is the entry spot if you would like to use our home screen for users to access their card, card details, transactions, and credit goals.
>
> [https://component-embedded-sandbox.upwardli.com/card-management?access\_token=\{access\_token}](https://component-embedded-sandbox.upwardli.com/card-management?access_token=\{access_token})

![Home](/_fern-img/8ab322294114da4cd2a21821a88e0ce20594293fbaee5a6693332491eca972c0.webp)

> **Info**
>
> If you use our embedded components, you can still retrieve information via our
> APIs.

## **Card Management via API**

When using our API method post onboarding you will be able to pull specific information regarding card details, transfers, credit insights and other actions directly into your app or website. The only two areas where you will need to use our standalone embedded widgets are (1) card image and (2) card details (i.e PIN set, freeze card, etc).

**Authentication**

You will need to authenticate to get access to the APIs you will use the URL below and the a **Partner API Token** with the applicable API url.

Important Parameters

| Parameter     | Value             | Notes                                                                                             |
| ------------- | ----------------- | ------------------------------------------------------------------------------------------------- |
| access\_token | Partner API token |                                                                                                   |
| redirect\_url | URL               | *(optional)* The URL to redirect the web component to once the consumer has completed onboarding. |
| api\_url      | URL               | See API table below                                                                               |

### **Card Image**

This entry spot will provide a PCI compliant way to display the card image and transaction details for the user. A user will be able to add their card details to their Apple or Google mobile wallet manually. In-app push provisioning will be available in 2H 2025.

> **Info**
>
> [https://component-embedded-sandbox.upwardli.com/card-image?access\_token=\{userscopetoken}](https://component-embedded-sandbox.upwardli.com/card-image?access_token=\{userscopetoken})

![Card Image](/_fern-img/01a375f5beece6f92f76a9187ae04a5a42a3653a089850912844f1cfbb5487c2.webp)

### **Card Details**

This entry spot will provide a user the ability to manage the access to their card, freeze / unfreeze a card, reset a PIN, etc. From this screen users can also view their DDA account and routing numbers to facilitate external transfers or direct deposits to their accounts.

> **Info**
>
> [https://component-embedded-sandbox.upwardli.com/card-details?access\_token=\{consumer\_scope\_token}](https://component-embedded-sandbox.upwardli.com/card-details?access_token=\{consumer_scope_token})
>
> [https://component-embedded-sandbox.upwardli.com/card-actions?access\_token=\{consumer\_scope\_token}](https://component-embedded-sandbox.upwardli.com/card-actions?access_token=\{consumer_scope_token})

![Card Management](/_fern-img/8adc9615b87f7e69f9f8a21a4273c589ba2ca5b755798930cb5769f5190ee376.webp)

## **Related API Table**

Below is a list of the API calls used to populate the **Card Management** embedded component.

| API                 | URL                                                                                                                                                                                    |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Payment Card        | [https://api-sandbox.upwardli.com/v2/consumers/\{consumer\_id}/payment-cards/](https://api-sandbox.upwardli.com/v2/consumers/\{consumer_id}/payment-cards/)                            |
| Accounts            | [https://api-sandbox.upwardli.com/v2/consumers/\{consumer\_id}/accounts/](https://api-sandbox.upwardli.com/v2/consumers/\{consumer_id}/accounts/)                                      |
| Credit Insights     | [https://api-sandbox.upwardli.com/v2/credit-insights/\{consumer\_id}/summary/](https://api-sandbox.upwardli.com/v2/credit-insights/\{consumer_id}/summary/)                            |
| Transactions        | [https://api-sandbox.upwardli.com/v2/payment-cards/\{payment\_card\_id}/transactions/](https://api-sandbox.upwardli.com/v2/payment-cards/\{payment_card_id}/transactions/)             |
| ACH Payments        | [https://api-sandbox.upwardli.com/v2/payments/ach/](https://api-sandbox.upwardli.com/v2/payments/ach/)                                                                                 |
| ATM Locator         | [https://www.allpointnetwork.com/locator](https://www.allpointnetwork.com/locator)                                                                                                     |
| Freeze Card         | [https://api-sandbox.upwardli.com/v2/payment-cards/\{payment\_card\_id}/freeze](https://api-sandbox.upwardli.com/v2/payment-cards/\{payment_card_id}/freeze)                           |
| UnFreeze Card       | [https://api-sandbox.upwardli.com/v2/payment-cards/\{payment\_card\_id}/unfreeze](https://api-sandbox.upwardli.com/v2/payment-cards/\{payment_card_id}/unfreeze)                       |
| Lost or Stolen Card | [https://api-sandbox.upwardli.com/v2/payment-cards/\{payment\_card\_id}/replace-lost-stolen](https://api-sandbox.upwardli.com/v2/payment-cards/\{payment_card_id}/replace-lost-stolen) |
| Replace Card        | [https://api-sandbox.upwardli.com/v2/payment-cards/\{payment\_card\_id}/reissue](https://api-sandbox.upwardli.com/v2/payment-cards/\{payment_card_id}/reissue)                         |

### **Example: Payment Card**

GET `https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/payment-cards/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

```javascript
{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "4a2472ea-75d9-4448-a4f4-e081a324e176",
            "consumer_id": "00000000-0000-0000-0000-000000000003",
            "status": "active",
            "emboss_hold": true,
            "available_balance": 197.02,
            "account_number": "1234567890",
            "routing_number": "021214891",
            "created_at": "2025-02-05T22:57:31.749142Z"
        }
    ]
}
```

### **Example: Bank Accounts**

Get bank accounts

GET `https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/accounts/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

```javascript
{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "083959d1-8282-4512-a52e-5630a5af042f",
            "consumer_id": "00000000-0000-0000-0000-000000000003",
            "bank_name": "Upward Financial Inc",
            "balance": 0,
            "account_name": "Upward Credit Builder",
            "account_number": "******7890",
            "account_type": "Secured Card",
            "account_routing_number": "*****4891",
            "is_primary": false
        },
        {
            "id": "bbd3005f-b6b0-40fe-975e-34bae4b20a5c",
            "consumer_id": "00000000-0000-0000-0000-000000000003",
            "bank_name": ".",
            "balance": 0,
            "account_name": "Account Name",
            "account_number": "******6789",
            "account_type": "checking",
            "account_routing_number": "*****6789",
            "is_primary": true
        }
    ]
}
```

Get partner fbo account

GET `https://api-sandbox.upwardli.com/v2/partners/{partner_id}/accounts/{account_id}`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

Create bank account

POST `https://api-sandbox.upwardli.com/v2/accounts/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
	"account_name": "Account Name"
	"account_number": "0123456789"
	"bank_name": " . "
	"consumer_id": "00000000-0000-0000-0000-000000000003"
	"routing_number": "123456789"
}
```

Response

```javascript
{
    "message": "Bank account created successfully",
    "data": {
        "id": "0f845102-f717-4bb9-a96a-c167a36148d6",
        "consumer_id": "00000000-0000-0000-0000-000000000003",
        "bank_name": ".",
        "balance": 0,
        "account_name": "Account Name",
        "account_number": "******6789",
        "account_type": "checking",
        "account_routing_number": "*****6789",
        "is_primary": true
        "is_active": true
    }
}
```

Delete bank account

Put `https://api-sandbox.upwardli.com/v2/accounts/{account_id}/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
	"is_active": false
}
```

### **Example: Credit Insights**

GET `https://api-sandbox.upwardli.com/v2/credit-insights/{consumer_id}/summary/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

```javascript
{
    "credit_score_card": {
        "score": 655,
        "change": 28,
        "credit_usage": 14,
        "total_tradelines": 3,
        "payment_history": 2,
        "credit_inquiries": 1,
        "credit_age": 35,
        "debt_collection_count": 1,
        "report_date": "2025-01-06",
        "late_payment_percentage": 0,
        "total_public_records": 0,
        "total_open_revolving_accounts": 0,
        "total_open_collection_accounts": 0,
        "total_bankruptcies": 0,
        "credit_report_status": "NotOrdered"
    },
    "credit_score_history": [
        {
            "month": "2025-01",
            "score": 655
        },
        {
            "month": "2024-12",
            "score": 627
        },
        {
            "month": "2024-11",
            "score": 601
        },
        {
            "month": "2024-10",
            "score": 587
        },
        {
            "month": "2024-09",
            "score": 688
        }
    ]
}
```

### **Example: Transactions**

Note: `payment_card_id` is not bank account id

GET `https://api-sandbox.upwardli.com/v2/payment-cards/{payment_card_id}/transactions/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

```javascript
{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "3a8ee16d-a561-4265-886b-186c10e409f2",
            "status": "posted",
            "amount": "57.57",
            "posted_at": "2025-02-03 23:13:38",
            "effective_at": "2025-02-03 23:13:38",
            "description": "Test Client Transaction: 0",
            "direction": "credit"
        }
    ]
}
```

### **Example: Create ACH**

POST`https://api-sandbox.upwardli.com/v2/payments/ach/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
	"amount": 6
	"consumer_id": "Consumer_id"
	"originating_account_id": "Account_id"
	"receiving_account_id": "Account_id"
	"description": "ACH originating_account_id to receiving_account_id"
}
```

### **Example: Create Partner transfer**

POST`https://api-sandbox.upwardli.com/v2/payments/transfer/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
	originating_account_id: "Partner FBO account id"
  receiving_account_id: "Consumer bank account id (not consumer id)"
  amount: 12.12
  description: "Partner FBO account to consumer account"
}
```

> **Info**
>
> Note: if pre funding is enabled set status to “pending”. Pre funding is disabled by default. Contact your POC at UPW to get it enabled.

### **Example: Fund Card**

Note: `payment_card_id` is not bank account id

POST [`https://api-sandbox.upwardli.com/v2/simulations/payment-cards/{{payment_card_id}}/create-simulated-fund-card`](https://api-sandbox.upwardli.com/v2/simulations/payment-cards/%7B%7Bpayment_card_id%7D%7D/create-simulated-fund-card)

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

### **Example: Simulate Card Auth**

Note: `payment_card_id` is not bank account id

POST [`https://api-sandbox.upwardli.com/v2/simulations/payment-cards/{{payment_card_id}}/create-simulated-card-auth`](https://api-sandbox.upwardli.com/v2/simulations/payment-cards/%7B%7Bpayment_card_id%7D%7D/create-simulated-card-auth)

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
    "amount": 10.00,
    "association": "visa",
    "merchant_name": "Testing Transactions" length needs to greater than 5
}
```

### **Example: Simulate Card Settlement**

Note: `payment_card_id` is not bank account id

POST [`https://api-sandbox.upwardli.com/v2/simulations/payment-cards/{{payment_card_id}}/create-simulated-card-settlement`](https://api-sandbox.upwardli.com/v2/simulations/payment-cards/%7B%7Bpayment_card_id%7D%7D/create-simulated-card-settlement)

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
    "auth_id": "<auth_id_from_above_response>",
    "settle_amount": 10.00
}
```

### **Example: Close Upward account**

POST [`https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/cancel-account/`](https://api-sandbox.upwardli.com/v2/simulations/payment-cards/%7B%7Bpayment_card_id%7D%7D/create-simulated-card-settlement)

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

## **Card Actions**

### **Freeze**

Note: `payment_card_id` is not bank account id

POST `https://api-sandbox.upwardli.com/v2/payment-cards/{payment_card_id}/freeze`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
    "end_date": "input_formats=["%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S.%fZ"]",
}
```

### **Unfreeze**

Note: `payment_card_id` is not bank account id

POST `https://api-sandbox.upwardli.com/v2/payment-cards/{payment_card_id}/unfreeze`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

### Lost or Stolen

Note: `payment_card_id` is not bank account id

POST `https://api-sandbox.upwardli.com/v2/payment-cards/{payment_card_id}/replace-lost-stolen/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
		"card_status": "L|S"
}
```

### Replace Card

POST `https://api-sandbox.upwardli.com/v2/payment-cards/{payment_card_id}/reissue/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

# Rewards

The rewards embedded component displays a consumer's rewards along with location-based offers. To load it you will follow the same authentication steps used for the other embedded components, using a **Customer Access Token** (user scope token).

> **Info**
>
> [https://component-embedded-sandbox.upwardli.com/en/rewards?access\_token=\{userscopetoken}\&latitude=37.7749\&longitude=-122.4194](https://component-embedded-sandbox.upwardli.com/en/rewards?access_token=\{userscopetoken}\&latitude=37.7749\&longitude=-122.4194)

**Important Parameters**

| Parameter     | Value                 | Notes                                                                                                              |
| ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ |
| access\_token | Customer Access Token | A user scope token used to load the rewards component                                                              |
| latitude      | Coordinate            | *(optional)* The consumer's latitude. Must be included together with `longitude` to display location-based offers. |
| longitude     | Coordinate            | *(optional)* The consumer's longitude. Must be included together with `latitude` to display location-based offers. |

> **Info**
>
> **Note:** `latitude` and `longitude` are optional, but both must be provided if you want the consumer to see location-based offers.

![Rewards Program](/_fern-img/ce682f1f4e3d3385fa7b9b1c16e762c21ef7bdf162f9330110fbccb7416cc40f.webp)

## Visit website (iFrame message)

Each offer may include a `websiteUrl`. When a consumer opens an offer's detail view
and taps **Visit website**, the rewards component does **not** navigate away on its
own — instead it emits a `component.link` iFrame message to the parent application.
Your app must listen for this message and open the URL (for example, in a new
browser tab or an in-app browser).

**Message**

```js
{
  Event: "component.link",
  body: {
    externalLink: "https://www.example.com"
  }
}
```

| Field               | Type   | Description                                           |
| ------------------- | ------ | ----------------------------------------------------- |
| `Event`             | string | Always `component.link` for the Visit website action. |
| `body.externalLink` | string | The selected offer's `websiteUrl`.                    |

**Listening for the message**

```js
window.addEventListener("message", (event) => {
  const { Event, body } = event.data;

  if (Event === "component.link") {
    // Open the offer's website (new tab, in-app browser, etc.)
    window.open(body.externalLink, "_blank");
  }
}, false);
```

> **Info**
>
> When the component runs inside a React Native WebView, the same payload is
> delivered through `window.ReactNativeWebView.postMessage` as a JSON string.
> Parse `event.nativeEvent.data` and handle `component.link` the same way.

# Credit Goals

## Credit Goals via API

### **Example: Credit Insights**

GET `https://api-sandbox.upwardli.com/v2/credit-insights/{consumer_id}/summary/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Response

```javascript
{
    "credit_score_card": {
        "score": 655,
        "change": 28,
        "credit_usage": 14,
        "total_tradelines": 3,
        "payment_history": 2,
        "credit_inquiries": 1,
        "credit_age": 35,
        "debt_collection_count": 1,
        "report_date": "2025-01-06",
        "late_payment_percentage": 0,
        "total_public_records": 0,
        "total_open_revolving_accounts": 0,
        "total_open_collection_accounts": 0,
        "total_bankruptcies": 0,
        "credit_report_status": "NotOrdered"
    },
    "credit_score_history": [
        {
            "month": "2025-01",
            "score": 655
        },
        {
            "month": "2024-12",
            "score": 627
        },
        {
            "month": "2024-11",
            "score": 601
        },
        {
            "month": "2024-10",
            "score": 587
        },
        {
            "month": "2024-09",
            "score": 688
        }
    ]
}
```

# Profile

**Important Parameters**

| Parameter     | Value                 | Notes                                                                                           |
| ------------- | --------------------- | ----------------------------------------------------------------------------------------------- |
| access\_token | Customer Access Token | A token that when used with the scope `api:card-management:read`                                |
| url           | URL                   | `https://component-embedded-sandbox.upwardli.com/consumer-profile/?access_token={access_token}` |

## Profile via Embedded Widget

## Profile via API

### **Example: Statements**

GET `https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/statements`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

### **Example: Download statements**

GET`https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/statements/{pdf_filename}/download`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

### **Example: Create dispute**

POST`https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/dispute/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
Body
{
	"reason": "Payment not correct",
	"details": "I took out $20 from the ATM. Why do I need $22.50 charge."
}
```

### **Example: List dispute**

GET`https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/dispute/list/`

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

### **Example: Get dispute**

GET`https://api-sandbox.upwardli.com/v2/consumers/{consumer_id}/dispute/{dispute_id}/`

# General API information

If you are utilizing the API approach you will also want to access other APIs for requesting specific information about Upward resources

| Resource                 | URL                                           | Notes |
| ------------------------ | --------------------------------------------- | ----- |
| Consumer - Profile       | /v2/consumers/                                |       |
| Consumer - Statement     | /v2/consumers/\{consumer\_id}/statements      |       |
| Consumer - Close         | /v2/payment-cards/\{payment\_card\_id}/close/ |       |
| Payments - Book Transfer | /v2/payments/transfer                         |       |

# **Using the Upward Webhooks**

By design we do not include extensive information about the webhook data sources. To learn more about the object referenced by the webhook, you can use the url\[s] in the webhook body to make api requests.

## **Available Webhooks**

| Resource                  | Events                                                                                                                                                                                                                      | URL                                                                              |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Consumers                 | Consumer.Created, Consumer.Updated, Consumer.Closed, Consumer.KYC.Started, Consumer.KYC.Pending, Consumer.KYC.Completed, Consumer.KYC.NeedsReview (`consumer.kyc.needs_review`), Consumer.KYC.Approved, Consumer.KYC.Failed | `v2/consumer/{consumer_id}`                                                      |
| Payment Cards             | PaymentCard.Created, PaymentCard.Updated, PaymentCard.Closed, PaymentCard.Frozen, PaymentCard.Unfrozen, PaymentCard.Replaced, PaymentCard.Lost, PaymentCard.Stolen                                                          | `v2/payment-cards/{payment_card_external_id}`                                    |
| Payment Card Transactions | PaymentCard.Transaction.Auth, PaymentCard.Transaction.AuthExpired, PaymentCard.Transaction.Archived, PaymentCard.Transaction.Settlement                                                                                     | `v2/payment-cards/{self.payment_card_external_id}/transactions/{transaction_id}` |
| ACH Payments              | Payment.Ach.Created, Payment.Ach.Sent, Payment.Ach.Completed, Payment.Ach.Failed, Payment.Ach.Received                                                                                                                      | `v2/payments/ach/{ach_external_id}`                                              |
| Transfer Payments         | Payment.Transfer.Created, Payment.Transfer.Completed, Payment.Transfer.Failed                                                                                                                                               | `v2/payments/transfer/{payment_transfer_external_id}/`                           |
| Instant Payments          | Payment.Instant.Created, Payment.Instant.Sent, Payment.Instant.Failed                                                                                                                                                       | `/v2/payments/instant/{instant_payment_id}/`                                     |
| Dispute                   | Consumer.Dispute.Created                                                                                                                                                                                                    | `v2/disputes/{dispute_id}`                                                       |
| Statement                 | Consumer.Statement.Created                                                                                                                                                                                                  | `v2/statements/{file_name}`                                                      |
| BankAccount               | Consumer.BankAccount.Created (`consumer.bank_account.created`), Consumer.BankAccount.Deleted (`consumer.bank_account.deleted`), Consumer.BankAccount.VerificationFailed (`consumer.bank_account.verification_failed`)       | `v2/accounts/{bank_account_external_id}`                                         |

## Webhook Message Description

All Upward webhook messages use the same format. To learn more about the resource(s) that are referenced by a specific webhook message, you can make an API request to the url(s) inside of the `resources` property.

```javascript
{
    "id": "{Unique Webhook Id}",
    "created_at": "Datetime: YYYY-MM-DDTHH:MM:SS.SS-TZ",
    "event_name": "Webhook Message",
    "partner_id": "{Your unique Partner Id}",
    "resources": [
        "https://{environment}.upwardli.com/v2/{resource}/{resource_id}"
    ],
    "last_attempted_at": "Datetime: YYYY-MM-DDTHH:MM:SS.SS-TZ"
}
```

## **Webhook Authentication**

Upward’s webhooks are secured using a Hashed Message Authentication Code (HMAC) in the webhook message header. The name of this header value is `Upwardli-Signature`. The Upwardli-Signature header contains two comma-separated key-value pairs encoding information about the request.

The first key-value pair will be in the form `t=<unix_timestamp>` and represents the unix time that the request was sent. The second key-value pair will be in the form `v1=WeNeedSomethingHere`, where the signature is a sha256 hash computed from the consumers webhook secret and a dot-separated string composed of the unix timestamp joined with the request body.

Note: computing the signature is sensitive to the exact characters input into the algortihm. The request data should be a json string with no whitespace formatting.

### **Sample Data**

```javascript
`client_id => 'public'``signature => 't=2023-10-12T20:44:58.082694+00:00,v1=263a5f79d899f7d5e04eb9a902b173d5901a9088966b932edca7174aec3d9e12'``message => '{"id":"954935cb-be33-47a4-99af-ec8bbc662ec7","createdAt":"2023-10-05T17:39:21.097794+00:00","eventName":"consumer_created","partnerId":"cb739356-5f69-429c-8157-756876d08d27","resources":["api/v2/consumers/00000000-0000-0000-0000-000000000000"],"lastAttemptedAt":"2023-10-05T17:39:21.097794+00:00"}'`;
```

Example decode in Python

```javascript
1t, v1 = [value.split('=')[1] for value in request.headers['Upwardli-Signature'].split(',')]2computed_digest = hmac.new(<YOUR_CLIENT_ID>.encode(), (t + '.' + request.data.decode('utf-8')).encode(), 'sha256').hexdigest()34if hmac.compare_digest(v1, computed_digest):5    # Process webhook
```

## **Registering for Webhook Messages**

POST `https://api-sandbox.upwardli.com/v2/webhooks/registrations/`

**Header**

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Example Request Body

```javascript
{
  "webhook_name": "{webhook_name}",
  "endpoint": "{endpoint to receive messages at}"
}
```

### Get All Webhook Registrations

GET `https://api-sandbox.upwardli.com/v2/webhooks/registrations/`

**Header**

```javascript
Header
{
    "Authorization":"Bearer [access_token]"
}
```

Example Response

```javascript
{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "{webhook_registration_id}",
            "partner_id": "{partner_id}",
            "webhook_name": "consumer.created",
            "endpoint": "{webhook_endpoint}",
            "status": "active",
            "failures": 0,
            "last_failure": null
        },
        {
            "id": "{webhook_registration_id}",
            "partner_id": "{partner_id}",
            "webhook_name": "consumer.updated",
            "endpoint": "{webhook_endpoint}",
            "status": "active",
            "failures": 0,
            "last_failure": null
        }
    ]
}
```

Change Log

| Version  | Description of Changes and Updates                        |
| -------- | --------------------------------------------------------- |
| v2.5.25  | Updated with additional specifics around embedded via API |
| v11.2.24 | Add card management API                                   |