Skip to content
Docs

HELOC Inquiries integration guide

Every call in a HELOC inquiry, from prefill to hand-off, with request and response payloads.

View as Markdown
On this page· 21 sections

This guide walks through every call in a HELOC inquiry, with the exact payloads for each step. New to inquiries? Start with the overview for the big picture.

You need to be onboarded before using the API. See Partner onboarding to get set up, or contact us if you haven't started yet.

Overview#

The HELOC Inquiries API lets your loan officers prefill an application, show the borrower real offers, and hand them to Figure to finish. You can:

HELOC inquiry flow#

A typical HELOC inquiryRequestResponse or event
Your system
Figure
  1. 2
    The inquiry's appUuid
  2. 3
    Generate offers
  3. 4
    Webhook with the next step
  4. Repeat as neededUntil offers are available
    1. 5
      Resolve what the next step asks for
    2. 6
      Generate offers
    3. 7
      Webhook with the next step
  5. Wholesale partners send suppressCompletion=true to review the agreement package before completing.
  6. 9
    Application details
  7. OptionalWholesale (TPO) partners only
    1. 11
      Attestations and agreement preview
    2. 13
      Application details
  8. 14
    Send the borrower to Figure to finish

For the wholesale (TPO) path, suppressCompletion=true is optional when you select an offer, but you need it if you want to fetch the agreement package and complete the inquiry as separate steps.

Webhooks#

See webhooks for information.

Create an inquiry #

A partner can create an inquiry ( created by a loan officer) to prefill borrower information and potentially test different scenarios before a legal application is started.

Creating an inquiry begins by prefilling some applicant and property information. The system uses this data for further processing before presenting offers to the user.

Optional fields in requests and responses are highlighted in green.

Request This endpoint requires an encrypted payload. The incoming payload should match the following format:

POSThttps://api.test.figure.com/products/heloc/v1/inquiry/start
Payload
{
  "encrypted": string // encrypted PII payload
}

When decrypted, the encrypted field of the payload should match the following format:

Decrypted payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "applicant": {
    "name": {
      "firstName": string,
      "lastName": string,
      "prefix": string,
      "middleName": string,
      "suffix": string  // SuffixType enum
    },
    "dob": string,  // YYYY-MM-DD
    "phone": string,
    "email": string,
    "ssn": string,  // nnn-nn-nnnn format
    "homeAddress": {
      "street1": string,
      "street2": string,  // apt # or other street identifier
      "city": string,
      "state": string,  // 2-letter state code
      "zip": string
    },
    "income": {
      "employmentType": string,  // enum EmploymentType
      "grossAnnualIncome": number,
      "annualRetirementIncome": number,
      "annualInvestmentIncome": number,
      "annualBusinessIncome": number,
      "savingsAmount": number,
      "otherAnnualIncome": number
    }
  },
  "property": {
    "address": {
      "street1": string,
      "street2": string,  // apt # or other street identifier
      "city": string,
      "state": string,  // 2-letter state code
      "zip": string
    },
    "propertyType": string,  // enum PropertyType
    "isListedForSale": boolean,
    "ownershipType": string,  // enum OwnershipType
    "borrowerEstimatedValue": number,
    "liens": [
      {
        "originationDate": string,  // YYYY-MM-DD
        "lenderName": string,
        "originalBalance": number,
        "currentBalance": number,
        "monthlyPayment": number
      }
    ]
  },
  "partnerDataRequest": {
    "externalAppId": string,
    "externalReferenceId": string,
    "externalCustomerId": string,
    "utmParameters": {
      "source": string,
      "medium": string,
      "campaign": string,
      "term": string,
      "content": string
    },
  },
  "testVariantsRequest": {
    "variants": [
      {
        "name": string  // A/B test variant identifier
      }
    ]
  },
  "businessInfo": {
    "entityName": string, 
    "entityType": string,  // enum EntityType
    "ownershipPercentage": number,
    "totalMonthlyRevenue": number,
    "ein": string,
    "stateOfIncorporation": string,  // 2-letter state code
    "address": {
      "street1": string,
      "street2": string,
      "city": string,
      "state": string,  // 2-letter state code
      "zip": string
    }
  }
}
Highlighted lines are optional.

The optional partnerDataRequest block can be used to capture partner-specific data for reference on the Figure application. For example, utmParameters can be utilized for tracking marketing campaigns. These will be aggregated in data reports.

The optional testVariantsRequest block can be used to enable A/B test variants for the inquiry. Contact Figure to obtain valid variant identifiers for your integration.

The optional businessInfo block can be used to provide Small and Medium Business (SMB) entity details for the inquiry. The entityType must be a valid enum value. Note that for certain organizations and property states, additional SMB validation rules may be enforced (e.g., required fields, disallowed entity types).

Response

Payload
{
  "appUuid": string // UUID format
}

The generated inquiry/app UUID will be returned in the contextual data of the response. This UUID will be required when submitting requests to all other endpoints.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Calculate offers #

After creating an inquiry, this supplementary endpoint can be used to retrieve offers related to specific origination fees as well as offers for specific DDP accounts. It is useful when the borrower changes desired draw amount and can also be used to quote a specific origination fee. This endpoint can be called multiple times.

Request

POSThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/calculate-offers
Payload
{
  "amount": number,
  "originationFee": number,
  "liabilityPayoffAmount": number,
  "accountIds": [string],
  "autoPayDiscountEnabled": boolean,
  "cuDiscountEnabled": boolean
}
Highlighted lines are optional.

If originationFee is provided, only offers matching that fee are returned.

For standard calculations, amount is the net draw amount. For Direct Debt Payoff calculations, amount is the total selected amount before subtracting liabilityPayoffAmount.

When omitted, autoPayDiscountEnabled and cuDiscountEnabled default to false.

Response

Payload
{
  "requestUuid": string, // UUID format
  "underwriting": {
    "ofeeMaxThreshold": number, // The maximum origination fee that can be applied to the draw amount for all offers
    "offers": [
      {
        "uuid": string, // UUID format
        "minAmount": number,
        "maxAmount": number,
        "rate": number,
        "primeRate": number,
        "term": number,
        "rateType": string, // enum OfferRateType
        "originationFeePercent": number,
        "appliedOriginationFeeCapAmount": number, // The maximum origination fee that can be applied to this offer
        "discounts": [
          {
            "type": string,
            "rateDiscountAmount": number
          }
        ]
      }
    ],
    "selectedOffer": null
  }
}

Use the returned offers[].uuid with Select an Offer.

Select an offer #

After creating an inquiry, underwriting and other background processes will run. When processing is complete, the borrower must select an offer to proceed with the application.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/select-offer
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
    "async": boolean
  },
  "offer": {
    "offerUuid": string,  // UUID format
    "selectedOfferAmount": number,
    "selectedDiscounts": [
      string
    ], // partner-specific enum
    "selectedAccountsToPayoff": [string]
  },
  "suppressCompletion": boolean  // default false; wholesale (TPO) organizations only
}
Highlighted lines are optional.

The offerUuid must match an offer that was previously supplied by the Inquiry details response, the Calculate Offers response, or an offer that was previously supplied by the Get Direct Debt Payoff Offers response.

The selectedDiscounts must match a provided type from the available offers or will be ignored.

The async field is required to be true when selectedAccountsToPayoff is populated. Please note that this will be removed from all requests in a future release and will no longer an option.

The selectedAccountsToPayoff is a list of accountIds which can be found in the Inquiry details response under the ddpDetails object.

The optional suppressCompletion field (wholesale only), when true, selects the offer without completing the inquiry. This is required for wholesale (TPO) partners that want to review the agreement package before explicitly completing the inquiry. It defaults to false and is rejected with a 400 for non-wholesale organizations. It can be combined with selectedAccountsToPayoff.

While an offer selection is being recalculated (for example, when selectedAccountsToPayoff is supplied), the inquiry's NextInquiryStepType is OFFER_SELECTION_PENDING. A webhook is not sent when this step begins, so poll Inquiry details until it changes. Do not fetch the agreement package or complete the inquiry in this state; those calls return a 400 ("still processing"). If the recalculation fails, the step reverts to OFFERS_AVAILABLE.

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Fetch agreement package #

Available to wholesale (TPO) organizations only.

After an offer has been selected, retrieve the attestations the loan officer must acknowledge and a preview of the broker agreement.

Request

GEThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/agreement-package

Response

Payload
{
  "messages": [  // optional
    {
      "level": string,
      "message": string
    }
  ],
  "definitions": [
    {
      "type": string,  // enum AttestationDefinitionType
      "description": string,
      "documents": [
        {
          "documentUuid": string,  // UUID format
          "fileName": string,
          "docType": string,
          "contentType": string
        }
      ]
    }
  ]
}
Highlighted lines are optional.

The request returns a 400 when:

  • No offer has been selected (An offer must be selected before the agreement package can be retrieved.).
  • The application has no property state.
  • The organization is not a wholesale organization.
  • The inquiry is still processing a previous request, such as a pending offer selection (This inquiry is still processing a previous request. Try again shortly.).

A 404 is returned if no inquiry exists for the appUuid.

Complete inquiry #

Available to wholesale (TPO) organizations only.

Completes an inquiry that was left open by selecting an offer with suppressCompletion=true (wholesale only). This call is idempotent: if the inquiry is already complete, the current details are returned.

Request

POSThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/complete-inquiry

The request body is required.

Payload
{
  "request": {
    "loanOriginatorUuid": string  // UUID format
  },
  "authorizedSignatory": {
    "authorizedSignatoryName": string,
    "authorizedSignatoryDate": string  // YYYY-MM-DD format
  }
}
Highlighted lines are optional.
  • request.loanOriginatorUuid is required.
  • authorizedSignatory is optional. Within it, authorizedSignatoryName and authorizedSignatoryDate are each independently optional.

Notes:

  • Authorized signatory information is optional. Decide whether to send it based on your own broker agreements.
  • When omitted, the signature defaults to the loan originator's full name and the date defaults to today's date. When provided, your values override these defaults.
  • If the inquiry is already complete, any signatory values sent on the repeat call are ignored (not overwritten).
  • The stored values are returned as appData.authorizedSignatory in appDetails of the response below, and in the inquiry details response.

Response

Payload
{
  "messages": [  // optional
    {
      "level": string,
      "message": string
    }
  ],
  "appDetails": object  // same shape as Fetch App/Inquiry Details; optional
}

The request returns a 400 when:

  • An offer has not been selected (An offer must be selected before the inquiry can be completed.).
  • The organization is not a wholesale organization.
  • An offer selection is still being processed (NextInquiryStepType=OFFER_SELECTION_PENDING).
  • The request body is missing or does not include request.loanOriginatorUuid.

Cancel inquiry #

If a borrower chooses not to proceed with the HELOC after reviewing the offers or if their financial situation changes, you may want to cancel the inquiry. Please note that once the inquiry has been converted into a full application, it can not be canceled. In such cases, the borrower will need to contact Figure support directly for assistance.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/cancel
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  }
}

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Set attributions #

Marketing and other external attributions can be set at any time in the flow.

All fields in the attributions request are optional; any fields not specified will remain unchanged from prior values. To un-set an existing attribution, simply provide the key to update set as null.

The API does not require this endpoint to be used; partners may use any of this information to link data with their own systems.

Request

PATCHhttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/attributions
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "attributions": {
    "utmParameters": {
      "source": string,
      "medium": string,
      "campaign": string,
      "term": string,
      "content": string,
    },
    "externalReferenceData": {
      "externalApplicationId": string,
      "externalReferenceId": string,
    }
  }
}
Highlighted lines are optional.

Response No contextual data in the response.

Reassign lead #

A HELOC lead can be reassigned to a different loan originator within the same organization. This is useful when a lead needs to be transferred to another loan officer for handling.

Request

PATCHhttps://api.test.figure.com/products/heloc/v1/lead/{appUuid}/reassign
Payload
{
  "newLoanOriginatorUuid": string  // UUID format (loan originator to reassign to)
}

The newLoanOriginatorUuid should be the UUID of the loan originator you want to reassign the lead to. This loan originator must belong to the same organization and broker company if applicable.

A list of loan originator uuids for your company is available via the Loan Originator API.

Response No contextual data in the response.

Fetch app/inquiry details #

See HELOC Details for information.

Get direct debt payoff offers #

When selecting an offer, a borrower may be presented with Direct Debt Payoff options (if enabled) to directly pay off their liabilities through our flow.

This generates offers given liabilities that want to be paid off are passed in.

You can find the accountIds associated with these liabilities in the Inquiry details response.

If liabilities were marked for payoff during asset depletion and different liabilities want to be selected after receiving offers, there is an opportunity that no offers may be returned in the response. If this occurs, either use one of the existing offers or select different accounts to get off offers for.

Request

GEThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/direct-debt-payoff-offers?accountId={accountIds}

Examples of what listOfAccountIds could look like:

accountId=acc_YpHcFjTpkbArL,acc_8K4YWpeP4qypX
accountId=acc_YpHcFjTpkbArL

Response

Payload
{
  "data": {
    "organization": string,
    "appUuid": string, // UUID format
    "offers": [
      {
        "uuid": string, // UUID format
        "minAmount": number,
        "maxAmount": number,
        "rate": number,
        "primeRate": number,
        "term": number,
        "rateType": string,  // enum OfferRateType
        "originationFeePercent": number,
        "discounts": [
          {
            "type": string,  // partner-specific enum
            "rateDiscountAmount": number
          }
        ]
      }
    ]
  }
}

Handling unhappy paths #

There are several possible roadblocks that an inquiry may encounter before being able to generate offers. The following endpoints can be used when indicated to manually resolve various issues.

Multiple properties #

This unhappy path will be indicated by a NextInquiryStepType=SELECT_PROPERTY.

There are situations where an inquiry was started with an address that was not specific enough. For example, an address for a condo did not include the unit number. The following two endpoints provide a resolution opportunity for when this occurs.

Fetch matched properties #

When the next step is SELECT_PROPERTY, use this endpoint to retrieve the list of candidate properties that match the submitted address. If the address is too ambiguous (e.g. a large multi-unit building without a unit number), the service may be unable to return matches and will respond with an error. In that case, restart the inquiry with a more specific address.

Request

GEThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/properties

Response

Payload
{
  "properties": [
    {
      "id": string, // This is an opaque id used later to select the applicable property
      "address": {
        "street1": string,
        "street2": string,
        "city": string,
        "state": string,  // 2-letter state code
        "zip": string
      },
      "apn": string,
      "longitude": number,
      "latitude": number
    }
    ...
  ],
  "messages": [
    {
      "level": string,
      "message": string
    }
  ]
}
Highlighted lines are optional.

Note

street1 will include the unit number when applicable. Although part of the API spec object, street2 will not be populated by this API.

Select property#

After determining which property should be used for the inquiry from Fetch Matched Properties, the select property api should be called with the selected property id.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/select-property
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "property": {
    "propertyId": string,
  }
}

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Submit SSN #

In the initial inquiry creation request, submitting the borrower’s SSN is optional.

However, if we are unable to make a soft credit match to an individual, we may ask for the SSN to help resolve the match. No hard credit pull will be applied at this time.

This unhappy path will be indicated by a NextInquiryStepType=CREDIT_MATCH_REQUIRED.

Request This endpoint requires an encrypted payload. The incoming payload should match the following format:

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/add-ssn
Payload
{
  "encrypted": string // encrypted PII payload
}

When decrypted, the encrypted field of the payload should match the following format:

Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "applicant": {
    "ssn": string // nnn-nn-nnnn format
  }
}

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Credit frozen #

After submitting the initial inquiry creation request, the applicant's credit may be inaccessible due to frozen credit.

This unhappy path will be indicated by a NextInquiryStepType=UNFREEZE_CREDIT.

Request

POSThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/repull-credit
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  }
}

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Verify outstanding liens #

After submitting the initial inquiry creation request, underwriting may not be able to proceed before resolving potential liens on the property.

Existing liens detected by our system are available from the common Inquiry details request.

This unhappy path will be indicated by a NextInquiryStepType=LIEN_MATCHING_REQUIRED.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/verify-liens
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "liens": [
    {
      "originationDate": string,  // YYYY-MM-DD
      "originalBalance": number,
      "lienUuid": string,  // UUID format
      "lenderName": string,
      "currentBalance": number,
      "monthlyPayment": number
    }
  ]
}
Highlighted lines are optional.

The lienUuid field, if supplied, should match a lien that was previously supplied by a Figure response. Liens manually added do not need to supply a lienUuid.

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Add more income assets #

This is deprecated, please see the new Asset Depletion section below.

A borrower may not be given offers based on income assets submitted with the initial inquiry creation request.

Previously entered income details are available from the common Inquiry details request, if not stored on the partner system.

This unhappy path will be indicated by a NextInquiryStepType=MORE_ASSETS_REQUIRED.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/add-income
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "income": {
    "employmentType": string, // enum EmploymentType
    "grossAnnualIncome": number,
    "annualRetirementIncome": number,
    "annualInvestmentIncome": number,
    "annualBusinessIncome": number,
    "savingsAmount": number,
    "otherAnnualIncome": number
  }
}
Highlighted lines are optional.

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Asset depletion #

A borrower may not be given offers based on income assets submitted with the initial inquiry creation request.

Selecting one or many of the current liabilities to pay off with the Heloc may also help qualify for offers.

Previously entered income details are available from the common Inquiry details request, if not stored on the partner system.

This api resolves unhappy paths indicated by NextInquiryStepType=MORE_ASSETS_REQUIRED and NextInquiryStepType=PAYOFF_REQUIRED.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/asset-depletion
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "income": {
    "employmentType": string, // enum EmploymentType
    "grossAnnualIncome": number,
    "annualRetirementIncome": number,
    "annualInvestmentIncome": number,
    "annualBusinessIncome": number,
    "savingsAmount": number,
    "otherAnnualIncome": number
  },
  "liabilityPayoff": {
    "selectedAccountsToPayoff": [string]
  },
}
Highlighted lines are optional.

The selectedAccountsToPayoff is a list of accountIds which can be found in the Inquiry details response under the ddpDetails object.

There is an opportunity to update the selectedAccountsToPayoff again when selecting an offer.

Response No contextual data in the response. At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).

Set estimated property value #

A borrower may not be given offers with the initial inquiry creation request if a BPO is required without providing an estimated property value.

This unhappy path will be indicated by a NextInquiryStepType=PROPERTY_VALUE_REQUIRED.

Request

PUThttps://api.test.figure.com/products/heloc/v1/inquiry/{appUuid}/add-property-estimate
Payload
{
  "request": {
    "loanOriginatorUuid": string,  // UUID format
  },
  "propertyEstimate": {
    "borrowerEstimatedValue": number
  }
}

Response No contextual data in the response.

At this point, background processing will have started. When the inquiry processing has completed and the next step is ready, the partner will be notified via a webhook (if configured).