> 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 as a Service

This tutorial walks you through the basic steps of integrating your fintech product with the Upward Credit Builder as a Service (CBaaS) product.

## 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.

For a deeper dive into authentication, you can read these [further details](/concepts/authentication).

## Consumer Onboarding

Once you are able to successfully request and receive authentication tokens, you can start onboarding your end users. Our onboarding process has three main steps:

1. End User KYC
2. View the Offer/Terms
3. Accept the Credit Terms Agreement

These steps are all managed automatically using our [onboarding UI component](/ui-components/onboarding), and you can view a detailed overview of the onboarding process [here](/products/credit-builder-as-a-service-c-baa-s#detailed-ui-onboarding-walkthrough).

## Purchase Flow

The User Purchase Flow is a three stage process:

Recording transactions with Upward is a three stage process:

### Requesting a Hold

The transaction starts by requesting a hold. If there are sufficient funds in the end user's account, then a new transaction will be created and the funds will be held until the transaction is completed, or for 1 calendar day. If there are insufficient funds in the account, a `4XX` error will be returned with an error description in the body.

### Clearing the Transaction

Once a hold is created, you can convert that hold into a transaction by calling the clear endpoint. This will disburse the funds from the end user's line of credit and create the liability. This step should happen at the time of purchase in your system.

### Close the Transaction

In this final step, the transaction is closed and recorded a complete. Successful closes will extinguish the liability that was created in the Clearing step and make those funds available, again, to the end user.

You can view [further details](/api-access/api-reference/credit-lines/create-c-baa-s-purchase-hold) about the Purchase Flow, and a detailed overview of the purchase cycle [here](/products/credit-builder-as-a-service-c-baa-s#the-cbaas-transaction-flow).

## APIs

All of our UI components use the same APIs that we make available to our consumers. You can view our full API documentation [here](/api-access/getting-started).

## Detailed UI Onboarding Walkthrough:

The following steps outline the steps encountered when onboarding a new consumer via our [UI Components](/ui-components/onboarding).

### \[Consumer] loads the onboarding embedded component in your app.

When you load the [onboarding embedded component](/ui-components/onboarding) passing in the pcid property (your unique ID) as a query parameter. 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 Severs 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"
}
```

### \[Consumer] Links the Upward ID to their Local Object

Upon receiving the webhook messge, 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.

```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
}
```

> **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\_

### \[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 `complete` indicating that this consumer has successfully passed our KYC checks.

```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
}
```

> **Tip**
>
> In the event that you do not receive the webhook or there are data processing/sync issues on your end, you can always call the get consumer by Partner Consumer ID endpoint: `GET https://api-sandbox.upwardli.com/v2/consumer/pcid/{pcid}/` where the `{pcid}` property is the internal ID you provided as a query parameter to the onboarding component.

### Optional: KYC Data Pre-Fill

Before redirecting the user to our page, you can prepopulate data for a consumer by calling the  api: `POST: 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"
}
```

> **Note**
>
> all fields are optional except for `pcid` and `email`

### Edge Cases / Unhappy path:

1. If a user does not complete KYC, then you will only receive the first 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.

## The CBaaS Transaction Flow

Recording transactions with Upward is a three stage process:

1. Request a Hold
2. Clear the Transaction
3. Close the Transaction

### Requesting a Hold

The transaction starts by requesting a hold. If there are sufficient funds in the end user's account, then a new transaction will be created and the funds will be held until the transaction is completed, or for 1 calendar day. If there are insufficient funds in the account, a `4XX` error will be returned with an error description in the body.

The system will then send a webhook with an `eventName` of `creditline.transaction.created` immediately.

### Clearing the Transaction

Once a hold is created, you can convert that hold into a transaction by calling the clear endpoint. This will disburse the funds from the end user's line of credit and create the liability. This step should happen at the time of purchase in your system.

The system will then send a webhook with an `eventName` of `creditline.transaction.cleared` when the funds have successfully been transfered to the user's account.
*note: This could be delayed for up to a couple minutes from the time that the clear api was called to allow funds to settle.*

### Close the Transaction

In this final step, The transaction is closed and recorded a complete. Successful closes will extinguish the liability that was created in the Clearing step and make those funds available, again, to the end user.

The system will then send a webhook with an `eventName` of `creditline.transaction.closed` when the funds have successfully been transfered to the user's account.
*note: This could be delayed for up to a couple minutes from the time that the clear api was called to allow funds to settle.*

You can read more about the [Credit Line API](/api-access/api-reference/credit-lines/create-c-baa-s-purchase-hold) in our [API Documentation](/api-access/getting-started).

### Successful Transaction Flow

The Transaction flow is broken down into the individual system actions at each step of the purchase flow. You must complete each step as defined in the flow below before moving on to the next step.

#### The Hold Stage

1. Consumer creates a transaction hold by calling `/v2/credit-line/{credit_line_id}/hold/`
2. The Upward API will immediately return a response containing the new transaction id. This transaction ID is immediately ready to use.
3. Asychronously, the Upward platform will send you a webhook message corresponding to this hold action with an `eventName` of `creditline.transaction.created`
4. The transaction status will be set to `Hold`

#### The Clear Stage

1. Consumer clears the hold and initiates a purchase agains the consumer credit line by calling `/v2/credit-line/{credit_line_id}/transactions/{transaction_id}/clear/`
2. The Upward API will immediately return a response indicating that the clear request was successful, or an error if the request was unable to be processed.
3. The Upward Platform will begin the funds transfer from the consumer's line of credit to their account.
4. The transaction status will be set to `InProgress`
5. When the funds transfer is complete, the transaction status will be set to `Received`
6. Asychronously, the Upward platform will send you a webhook message corresponding to this hold action with an `eventName` of `creditline.transaction.cleared`

#### The Close Stage

Once the transaction is in `Received` state, then it is ready to be closed.

1. Consumer requests to record the closing of the transaction by calling `/v2/credit-line/{credit_line_id}/transactions/{transaction_id}/close/`
2. The Upward API will immediately return a response indicating that the close request was successful, or an error if the request was unable to be processed.
3. The Upward Platform will begin to pay off the transaction balance from the consumer's account.
4. When the funds transfer is complete, the transaction status will be set to `Completed`
5. Asychronously, the Upward platform will send you a webhook message corresponding to this hold action with an `eventName` of `creditline.transaction.closed`

*You can read more about transaction statuses [here](/api-access/reference).*