Back to top

Forward Financing API

Our Partner API is designed to allow our business partners to submit potential deals automatically from their system to ours and receive information on the statuses of their deals.

How to get support

Questions about integrating with the API, setting up authentication, or anything else in this document? Email us at apisupport@forwardfinancing.com and our team will be happy to help.

Host

This is the base URL for this API: https://api.staging.forwardfinancing.com/

Authentication

The Partner API uses OAuth2 for authentication.

If a request carries no valid credentials, the HTTP status code of the response will be 401 Unauthorized.

OAuth2

New to OAuth2? Don’t worry. OAuth2 is a widely-used industry standard for connecting securely to an API. Instead of attaching a secret key to every request, your software first trades your credentials for a temporary access token, and then uses that token for a short time. Nearly every programming language and integration platform has a ready-made tool that performs these steps for you, so in most cases you (or whoever builds your integration) will not have to assemble the flow by hand. You do not need to be an OAuth2 expert — our support team is happy to walk you through the setup.

What you’ll need (we provide these during onboarding):

Field Value
client_id partner-api (the same value for all partners)
username The email address associated with your partner account
password The secret we issue you during onboarding

How it works. There are two steps:

  1. Send your credentials to our token endpoint and receive a temporary access token in return.

  2. Include that access token on each request you make to the API.

The examples below use curl from a command line purely so you can test the flow and see exactly what each request looks like. In a real integration you would normally let one of the tools listed further down make these requests for you rather than running curl by hand.

Step 1 — Get an access token (test example):

curl -sS https://access.staging.forwardfinancing.com/application/o/token/ \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=password" \
  --data-urlencode "client_id=partner-api" \
  --data-urlencode "username=YOUR_PARTNER_EMAIL" \
  --data-urlencode "password=YOUR_PARTNER_SECRET" \
  --data-urlencode "scope=openid email profile"

This is the standard OAuth2 password grant (also called “resource owner password credentials”), which most OAuth2 libraries support out of the box. grant_type=client_credentials is also accepted and behaves identically, if your tooling prefers it.

The response contains your access token in the access_token field:

{
    "access_token": "eyJ...",
    "token_type": "bearer",
    "expires_in": 600,
    "scope": "openid email profile"
}

Step 2 — Call the API with the token (test example):

curl -sS https://api.staging.forwardfinancing.com/v1/lead \
  -H "Authorization: Bearer eyJ..."

A few things to keep in mind:

  • Access tokens are short-lived (they last 10 minutes). Reuse the same token until it expires, then get a new one by repeating Step 1. You do not need a new token for every request.

  • Use the secret we issued you as your OAuth2 password. If that secret is ever changed, use the new value.

Tools that can do this for you. You don’t have to build the two steps above from scratch. The libraries and platforms below can make these HTTPS requests for you, and many can automatically fetch a fresh token when the old one expires:

If you use an OAuth2 library, choose its password grant (or “resource owner password credentials”) option and configure it with the client_id, username, and password above — no client secret is required. A plain HTTPS POST with any of the HTTP tools above works equally well. Our support team can help you get this wired up.

HTTPS

Since your API requests will contain sensitive personal information about our customers, you must use SSL (HTTPS). To discourage insecure API requests, the response code will be 403 Forbidden for all requests made over HTTP.

Rate Limiting

We impose a rate limit per user of 1 request per second. If you exceed this rate of requests, the response code will be 429 Too Many Requests. If you need to exceed this limit for some reason, please let us know!

Lead Submission API

Submit a New Lead

POST/v1/lead

Submit a new lead directly to our system in the JSON format specified.

A unique reference_id must be submitted in the request and it should represent your internal ID for that submission.

The request body must contain a top-level lead object with the objects described below.

lead.contacts_attributes (array of objects, required) - one or more contacts, typically the business owner(s)

Field Type Required Description
first_name string Yes Contact’s legal first name
last_name string Yes Contact’s legal last name
email string No
title string No Contact’s title or role at the business
born_on string No Date in ISO8601 format, ex: 2015-12-31
home_phone string No
cell_phone string No
ssn string Yes Social Security Number, digits only
ownership_date string No Date in ISO8601 format, ex: 2015-12-31
current_address_attributes object Yes Contact’s home address, see address fields below

Address fields (used by current_address_attributes on both contacts and the account)

Field Type Required Description
street1 string Yes First line of the street address
street2 string No Second line (suite, floor, unit)
city string No
state string Yes Two-letter US state or territory code, one of: AK, AL, AR, AS, AZ, CA, CO, CT, DC, DE, FM, FL, GA, GU, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MH, MI, MN, MO, MP, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, PR, PW, RI, SC, SD, TN, TX, UT, VA, VI, VT, WA, WI, WV, WY
zip string Yes

lead.account_attributes (object, required) - the business applying for funding

Field Type Required Description
entity_type string Yes One of: Sole Proprietor, Limited Liability Company (LLC), Corporation, Limited Partnership (LP), Limited Liability Partnership (LLP), General Partnership
name string Yes Business trading name (DBA)
started_on string Yes Date in ISO8601 format in Eastern Time, ex: 2015-12-31
legal_name string No Registered legal name, if different from the trading name
phone string Yes
email string No
website string No
fein string No Federal Employer Identification Number, 9 digits
monthly_revenue string No One of: Less than $5,000, $5,000 - $10,000, $10,000 - $20,000, $20,000 - $50,000, $50,000 - $100,000, Greater than $100,000
industry_name string Yes One of: Accounting & Tax Services, Automotive Services, Consulting, Convenience Stores, Markets & Delis/Bakeries, Education / Schools / Daycare, Electricians, Plumbing & HVAC, Farming & Agriculture, Furniture & Home Furnishings, Gas Stations & Fuel Services, General Contractor, Gyms/Fitness, Home-healthcare / Senior Care, Hotels / Motels / Hospitality, Janitorial & Cleaning Services, Jewelry, Landscaping & Lawn Services, Law firms, Manufacturing, Medical Professionals, Other Business Services, Other Consumer, Pharmacies, Real Estate / Insurance Brokers, Recycling, Restaurants & Bars, Retail Businesses, Salons & Spas, Security Guard Services, Staffing agencies, Subcontractor, Ticket / Concert Venues, Travel Agencies, Trucking & Transportation, Wholesale & Distribution, Wine & Liquor Stores
current_address_attributes object No Business address, see address fields above

lead.loan_attributes (object, optional) - details of any existing advance or loan

Field Type Required Description
company_name string No Name of the existing lender
daily_payment_amount number No Integer
balance number No Integer

lead.application_attributes (object, required)

Field Type Required Description
has_current_loan boolean No
applicant_is_owner boolean No
loan_use string No One of: Inventory, Marketing, Taxes, Payroll, Debt Refinancing, Business Expansion, New Location, Renovation, Equipment Purchase, Equipment Repair, Hiring Employees, Other, Misc. Business Expenses, Materials, Working Capital
capital_needed string No
owner_1_percent_ownership number No Integer
owner_2_percent_ownership number No Integer
reference_id string Yes Your unique internal ID for this submission. Must be unique across all of your submissions; a duplicate value returns 422
notes string No

lead.meta (object, optional) - additional metadata to associate with the submission

Field Type Required Description
custom_field string No
campaign_id string No

Example URI

POST /v1/lead
Request  Successful
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "lead": {
    "contacts_attributes": [
      {
        "first_name": "Erlich",
        "last_name": "Bachman",
        "email": "erlich@piedpiper.com",
        "title": "COO and Spiritual Advisor",
        "born_on": "2015-01-01",
        "home_phone": "6176781000",
        "cell_phone": "6176781000",
        "ssn": "234345566",
        "ownership_date": "2015-01-01",
        "current_address_attributes": {
          "street1": "36 Bromfield St",
          "street2": "Second Floor",
          "city": "Boston",
          "state": "MA",
          "zip": "00112"
        }
      }
    ],
    "account_attributes": {
      "entity_type": "Limited Liability Company (LLC)",
      "name": "Pied Piper",
      "started_on": "2015-01-01",
      "legal_name": "Pied Piper LLC",
      "phone": "6176781000",
      "email": "support@piedpiper.com",
      "website": "https://www.piedpiper.com/",
      "fein": "000000000",
      "monthly_revenue": "Less than $5,000",
      "industry_name": "Other Business Services",
      "current_address_attributes": {
        "street1": "36 Bromfield St",
        "street2": "Second Floor",
        "city": "Boston",
        "state": "MA",
        "zip": "00112"
      }
    },
    "loan_attributes": {
      "company_name": "Wells Fargo",
      "daily_payment_amount": 25,
      "balance": 15000.23
    },
    "application_attributes": {
      "has_current_loan": true,
      "applicant_is_owner": true,
      "loan_use": "Debt Refinancing",
      "capital_needed": "50000",
      "owner_1_percent_ownership": 56,
      "owner_2_percent_ownership": 9,
      "reference_id": "ANYTHING_YOUWANT_AS_A_STRING",
      "notes": "We think this is a great deal!"
    },
    "meta": {
      "custom_field": "custom data",
      "campaign_id": "CAMP-2026-Q2"
    }
  }
}
Response  201
HideShow

If your request is successful, you will receive HTTP status code 201 Created. The response body will contain a success message, and an ID for your submission, which will be used later for submitting attachments. For example

Headers
Content-Type: application/json
Body
{
  "message": "Your lead was successfully created.",
  "id": "YOUR_LEAD_ID_HERE"
}
Request  Missing Info
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "lead": {
    "contacts_attributes": [
      {
        "first_name": "Erlich",
        "last_name": "Bachman",
        "email": "erlich@piedpiper.com",
        "title": "COO and Spiritual Advisor",
        "born_on": "2015-01-01",
        "home_phone": "6176781000",
        "cell_phone": "6176781000",
        "ssn": "234345566",
        "ownership_date": "2015-01-01"
      }
    ],
    "account_attributes": {
      "entity_type": "Limited Liability Company (LLC)",
      "name": "Pied Piper",
      "started_on": "2015-01-01",
      "legal_name": "Pied Piper LLC",
      "phone": "6176781000",
      "email": "support@piedpiper.com",
      "website": "https://www.piedpiper.com/",
      "fein": "000000000",
      "monthly_revenue": "Less than $5,000",
      "industry_name": "Other Business Services",
      "current_address_attributes": {
        "street1": "36 Bromfield St",
        "street2": "Second Floor",
        "city": "Boston",
        "state": "MA",
        "zip": "00112"
      }
    },
    "loan_attributes": {
      "company_name": "Wells Fargo",
      "daily_payment_amount": 25,
      "balance": 15000.23
    },
    "application_attributes": {
      "has_current_loan": true,
      "applicant_is_owner": true,
      "loan_use": "Debt Refinancing",
      "capital_needed": "50000",
      "owner_1_percent_ownership": 56,
      "owner_2_percent_ownership": 9,
      "reference_id": "ANYTHING_YOUWANT_AS_A_STRING",
      "notes": "We think this is a great deal!"
    }
  }
}
Response  422
HideShow

If your request is unsuccessful, for example if the JSON is invalid or certain required attributes are missing, you will receive HTTP status code 422 Unprocessable Entity. The response body may contain information about what part of your request was invalid in JSON format, for example:

Headers
Content-Type: application/json
Body
{
  "errors": {
    "contacts_attributes": [
      "Must provide address"
    ]
  }
}
Request  Non-Unique Reference ID
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "lead": {
    "contacts_attributes": [
      {
        "first_name": "Erlich",
        "last_name": "Bachman",
        "email": "erlich@piedpiper.com",
        "title": "COO and Spiritual Advisor",
        "born_on": "2015-01-01",
        "home_phone": "6176781000",
        "cell_phone": "6176781000",
        "ssn": "234345566",
        "ownership_date": "2015-01-01"
      }
    ],
    "account_attributes": {
      "entity_type": "Limited Liability Company (LLC)",
      "name": "Pied Piper",
      "started_on": "2015-01-01",
      "legal_name": "Pied Piper LLC",
      "phone": "6176781000",
      "email": "support@piedpiper.com",
      "website": "https://www.piedpiper.com/",
      "fein": "000000000",
      "monthly_revenue": "Less than $5,000",
      "industry_name": "Other Business Services",
      "current_address_attributes": {
        "street1": "36 Bromfield St",
        "street2": "Second Floor",
        "city": "Boston",
        "state": "MA",
        "zip": "00112"
      }
    },
    "loan_attributes": {
      "company_name": "Wells Fargo",
      "daily_payment_amount": 25,
      "balance": 15000.23
    },
    "application_attributes": {
      "has_current_loan": true,
      "applicant_is_owner": true,
      "loan_use": "Debt Refinancing",
      "capital_needed": "50000",
      "owner_1_percent_ownership": 56,
      "owner_2_percent_ownership": 9,
      "reference_id": "THIS_ISNT_UNIQUE",
      "notes": "We think this is a great deal!"
    }
  }
}
Response  422
HideShow

You may also receive an HTTP status code of 422 Unprocessable Entity if you have submitted a reference_id that you have used in the past. In that case you will see a similar JSON response, like:

Headers
Content-Type: application/json
Body
{
  "message": "Reference ID is not unique."
}

Submit an Attachment File

POST/v1/attachment?filename={filename}&lead_id={lead_id}&encoded={encoded}

This endpoint is for uploading documents associated with your recently created lead.

Send your attachment file as a raw binary.

The request body should contain the binary of the file you want to upload. In most languages, you can accomplish this by reading the file contents into memory and then outputting them into your request body as binary or a string.

You may only submit one attachment per request. To submit more than one attachment, send each attachment in its own request.

If for some reason your system does not allow you to send a binary request body, you can Base 64 encode the binary into a string. If you choose this option, you must indicate that the body is encoded by passing encoded=true in the URL parameters. Be sure to use strict Base 64 encoding, which encodes new line (\n) characters.

Example URI

POST /v1/attachment?filename=filename&lead_id=lead_id&encoded=encoded
URI Parameters
HideShow
filename
string (required) 

The desired filename in our system for the attachment you are uploading. For example “bank_statement.pdf”

lead_id
string (required) 

Which of your previously submitted leads the attachment is associated with. The lead id can be found in the response to the leads endpoint.

encoded
boolean (optional) 

If for some reason, your system does not allow you to send a binary request body, you can Base 64 encode the binary into a string. If you choose this option, you must indicate the body is encoded by passing encoded=true in the URL parameters. Be sure to use strict Base 64 encoding, which encodes new line (\n) characters.

Request
HideShow
Headers
Authorization: Bearer <access_token>
Body
Binary of your file
Response  202
HideShow
Body
{
  "message": "Your attachment was received and is being processed"
}

Submit an Attachment From a URL

POST/v1/attachment

The same endpoint can be used to submit the URL of an attachment rather than the raw binary.

If your attachments can be found at a public URL, you can submit the URL. If it is not a public URL, we will not be able to access your file.

You may only submit one attachment per request. To submit more than one attachments, send each attachment in its own request.

Field Type Required Description
attachment_url string Yes The URL where the file is publicly accessible
filename string Yes Name of the file with extension
lead_id string Yes The ID received when you initially submitted your lead

Example URI

POST /v1/attachment
Request
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "attachment_url": "https://yourwebsite.com/files/some_attachment.pdf",
  "filename": "bank_statement.pdf",
  "lead_id": "QTEQ.YJNyDzbMP0YX0D7qQr7PZcn7CU2E.TIIvFdZlr._ps.FDvDvwqGzI-c5FQ"
}
Response  202
HideShow
Body
{
  "message": "Your attachment was received and is being processed"
}

Upload a Closing Attachment File

POST/v1/submissions/{lead_id}/closing_attachment?filename={filename}&document_tags[]=&document_tags[]=&encoded={encoded}

This endpoint allows you to upload a stipulation, or any document related to the Closing Department, for a deal you have already submitted.

Send your attachment file as a raw binary in the request body. You may only submit one attachment per request. To upload more than one document, send each attachment in its own request.

If for some reason your system does not allow you to send a binary request body, you can Base 64 encode the binary into a string. If you choose this option, you must indicate that the body is encoded by passing encoded=true in the URL parameters. Be sure to use strict Base 64 encoding, which encodes new line (\n) characters.

Alternatively, if your file is available at a public URL, you can pass an attachment_url parameter instead of a request body and we will download the file for you. If it is not a public URL, we will not be able to access your file.

Use the document_tags[] parameter to categorize the document. It can be included multiple times to assign several tags to one document. The available stipulation tags are:

  • account_must_be_positive_before_funding

  • accounts_receivable_report_invoices

  • balance_sheet_income_statement

  • balance_sheet

  • bank_statement

  • confirm_current_or_past_funding

  • drivers_license

  • information_on_additional_owner

  • month_to_date

  • payback_months

  • proof_of_ownership

  • signed_contracts

  • tax_return

  • twelve_month_bank_verification

  • ucc_information

  • voided_check

You may omit document_tags[] if your document does not match any of the defined tags, or if you are unsure which tag to use.

Note: Avoid the other tag. Uploading an attachment with the other tag returns a “description cannot be blank” error, because there is not yet a way to submit a description through the API. No description is required for any of the tags listed above.

Example URI

POST /v1/submissions/lead_id/closing_attachment?filename=filename&document_tags[]=&document_tags[]=&encoded=encoded
URI Parameters
HideShow
lead_id
string (required) 

The ID received when you initially submitted your lead (the same id returned by the lead submission endpoint).

filename
string (required) 

The desired filename in our system for the attachment you are uploading, including the extension. For example “closing_package.pdf”.

document_tags
array[string] (optional) 

Tags used to categorize the document. This parameter can be included multiple times. You may omit it if your document does not match any of the defined tags, or if you are unsure which tag to use.

encoded
boolean (optional) 

Set to true if the request body is Base 64 encoded. Be sure to use strict Base 64 encoding, which encodes new line (\n) characters.

Request
HideShow
Headers
Content-Type: application/pdf
Authorization: Bearer <access_token>
Body
Binary of your file
Response  202
HideShow
Headers
Content-Type: application/json
Body
{
  "message": "Your attachment was received and is being processed"
}
Response  400
HideShow

You will receive a 400 Bad Request if a required field is missing or invalid, or the file could not be retrieved — for example, a missing or blank filename, a blank lead id, an empty request body, or an attachment_url we are unable to access. The message varies with the cause (for example URL is not permitted for a non-public URL, or Failed to download attachment).

Headers
Content-Type: application/json
Body
{
  "message": "You must provide a filename"
}
Response  413
HideShow

Attachments larger than 100MB are rejected.

Headers
Content-Type: application/json
Body
{
  "message": "Attachment Too Large"
}

Submit Multiple Attachments

POST/v1/attachments

This endpoint is for uploading multiple documents associated with your recently created lead.

Upload one or more documents to an existing lead, submission, or stip opportunity in a single request. Each attachment must be referenced by URL, S3 location, or base64-encoded data.

Notes:

  • Attachment Limit - 100MB

  • At least 1 attachment must be present. These is a max of 25 attachments

  • One and only one of (uuid, lead_id, stip_opportunity_uuid) must be present

The request body is a JSON object with the following fields:

Field Type Required Description
uuid string Conditional Submission UUID. Provide exactly one of uuid, lead_id, or stip_opportunity_uuid
lead_id string Conditional Encrypted lead ID returned by /v1/lead. Provide exactly one of uuid, lead_id, or stip_opportunity_uuid
stip_opportunity_uuid string Conditional Stip opportunity UUID. Provide exactly one of uuid, lead_id, or stip_opportunity_uuid
attachments array of objects Yes One to 25 attachment objects (see below); at least one is required

Each object in attachments must reference its file in exactly one of three ways — a public URL (attachment_url), an S3 location (bucket + key), or inline Base 64 data (encoded + data):

Field Type Required Description
filename string Yes Desired filename in our system, including the extension
attachment_url string Conditional Public URL where the file can be downloaded
bucket string Conditional S3 bucket name (used together with key)
key string Conditional S3 object key (used together with bucket)
encoded boolean Conditional Set to true when supplying Base 64 data in data
data string Conditional Base 64-encoded file contents (used together with encoded)
tags array of strings No Document tags, e.g. bank_statement, tax_return, voided_check

Example URI

POST /v1/attachments
Request
HideShow
Headers
Authorization: Bearer <access_token>
Body
{
  "lead_id": "<encrypted-lead-id>",
  "attachments": [
    {
      "filename": "bank_statement_jan.pdf",
      "attachment_url": "https://example.com/files/bank_jan.pdf",
      "tags": [
        "bank_statement"
      ]
    },
    {
      "filename": "tax_return.pdf",
      "bucket": "partner-uploads",
      "key": "docs/tax_return.pdf",
      "tags": [
        "tax_return"
      ]
    },
    {
      "filename": "voided_check.png",
      "encoded": true,
      "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlE...",
      "tags": [
        "voided_check"
      ]
    }
  ]
}
Response  202
HideShow
Body
{
  "message": "All attachments were received and are being processed",
  "total": 3,
  "accepted": 3,
  "results": [
    {
      "filename": "bank_statement_jan.pdf",
      "status": "accepted"
    },
    {
      "filename": "bank_statement_feb.pdf",
      "status": "accepted"
    },
    {
      "filename": "signed_application.pdf",
      "status": "accepted"
    }
  ]
}
Response  207
HideShow
Body
{
  "message": "Some attachments could not be processed",
  "total": 3,
  "accepted": 2,
  "failed": 1,
  "results": [
    {
      "filename": "bank_statement_jan.pdf",
      "status": "accepted"
    },
    {
      "filename": "bank_statement_feb.pdf",
      "status": "accepted"
    },
    {
      "filename": "invalid_url.pdf",
      "status": "failed",
      "error": "Failed to download attachment"
    }
  ]
}
Response  400
HideShow
Body
Missing required fields, or attachments array is empty.
Response  413
HideShow
Body
The total request payload exceeded the size limit.

Retrieve the Status of an API Lead

GET/v1/deal_status/{lead_id}

After you’ve sucessfully submitted a Lead and its attachments you can use this endpoint to retrieve the status of that submission in our funding process.

The response fields will vary depending on the status of the given deal.

Deals in Processing will just have stage in the response.

Approved deals will have stage, max_approval, max_payments, offer_link, required_stipulations, notes, and offer_variants.

Declined deals will have stage, decline_drivers, and decline_notes.

If we are Missing Information needed to make a decision, the response will contain the stage and missing_info fields.

  • stage - the current state of your submitted deal in our process

  • max_approval - the maximum advance amount approved for this merchant

  • max_payments - the maximum number of payments approved for this merchant (term in days)

  • offer_link - link to our offer calculator where you can select terms and request contracts

  • decline_drivers - reasons why this deal was declined

  • decline_notes - additional explanation for why this deal was declined

  • missing_info - additional information that is needed for a decision to be made on this deal

  • required_stipulations - list of required documents or information necessary to review before funding. Each object in this list contains the key type that describes what kind of document is requested.

  • notes - external ISO notes

  • offer_variants - list of available offer types for this approved deal (e.g. base and buyout). Each offer variant object contains:

    • id - unique identifier
    • variant_type - offer type (e.g. base, buyout)
    • max_approval_amount - maximum approved advance amount
    • max_term - maximum term (in months)
    • max_term_buy_rate - maximum term buy rate
    • maximum_buyout_amount - maximum amount approved to go towards a buyout
    • net_funded_amount - total amount expected to be deposited into the customer’s account
    • position - Forward’s position
    • existing_financing_companies_to_buyout - financing companies paid off as a part of a buyout
    • required_stipulations - list of required documents or information necessary to review before funding. Each object in this list contains the key type that describes what kind of document is requested.

Example URI

GET /v1/deal_status/lead_id
URI Parameters
HideShow
lead_id
string (required) 

which of your previously submitted leads the attachment is associated with. The lead id can be found in the response to the leads endpoint.

Request
HideShow
Headers
Authorization: Bearer <access_token>
Response  200
HideShow
Body
{
  "stage": "Approval Sent",
  "max_approval": 30000,
  "max_payments": 7,
  "offer_link": "offer.com",
  "required_stipulations": [
    {
      "type": "Voided Check"
    }
  ],
  "notes": "Strong application with consistent revenue.",
  "offer_variants": [
    {
      "id": "variant-uuid-1",
      "variant_type": "base",
      "max_approval_amount": 30000,
      "max_term": 7,
      "max_term_buy_rate": 1.34,
      "maximum_buyout_amount": null,
      "existing_financing_companies_to_buyout": null,
      "position": 1,
      "net_funded_amount": 28500,
      "required_stipulations": [
        {
          "type": "Voided Check"
        }
      ]
    },
    {
      "id": "variant-uuid-2",
      "variant_type": "buyout",
      "max_approval_amount": 40000,
      "max_term": 9,
      "max_term_buy_rate": 1.38,
      "maximum_buyout_amount": 10000,
      "existing_financing_companies_to_buyout": [
        "Lender Co"
      ],
      "position": 2,
      "net_funded_amount": 19105,
      "required_stipulations": [
        {
          "type": "Voided Check"
        }
      ]
    }
  ]
}
Response  200
HideShow
Body
{
  "stage": "Declined",
  "decline_drivers": "Default history;Excessive liens or judgements",
  "decline_notes": "This merchant does not look credible"
}
Response  200
HideShow
Body
{
  "stage": "File Missing Info",
  "missing_info": "We're going to need more recent bank statements please!"
}
Response  200
HideShow
Body
{
  "stage": "Working"
}

Webhooks

Webhook Notifications

Whenever a deal reaches any of the stages given below, your callback endpoint will receive a POST Request notifying you of the lead_id and event_type that changed. This webhook leads to increased efficiency with real-time updates, along with limiting need to poll Forward Financing servers to get the status.

Stages which trigger webhook callback:

  • Approved

  • Declined

  • Waiting on ISO

Whenever this webhook callback is triggered, it is expected that your system will hit the deal status endpoint to gather more information about the event change.

POST Sample response

{ lead_id: lead id of the deal, event_type: event which caused this webhook callback }

Register Webhook URL

Resource

POST/v1/webhook

Webhooks allow your application to register callback endpoints which can listen for realtime updates to your deals.

Webhook URL provided must start with http:// or https://

Example URI

POST /v1/webhook
Request
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "webhook_url": "https://yourwebsite.com/some-path"
}
Response  200
HideShow
Body
{
  "success": true
}
Response  422
HideShow
Body
{
  "errors": {
    "webhook_url": [
      "is not a valid URL"
    ]
  }
}

Resource

POST/v1/trigger_webhook

To be able to test your integration and callback response, we have added an endpoint which triggers the webhook.

Example URI

POST /v1/trigger_webhook
Request
HideShow
Headers
Content-Type: application/json
Authorization: Bearer <access_token>
Body
{
  "webhook_url": "https://yourwebsite.com/some-path",
  "lead_id": "Lead Id for the deal",
  "event_type": "Event for which you want to force webhook trigger"
}
Response  200
HideShow
Body
{
  "message": "Webhook trigger successful"
}
Response  400
HideShow
Body
{
  "message": "Please provide lead_id, webhook_url and event_type"
}

Generated by aglio on 14 Jul 2026