Skip to main content

Concepts

A book is a container for one deal one or more documents that get parsed together. Books have a parse_status that progresses through: Documents can be bank statements, credit reports, tax forms, or loan applications. The book API returns different output shapes depending on which document types were parsed.

Submit a book

POST /submit-book
Multipart form upload. Pathway creates the book, uploads the files to S3, and starts parsing in the background. Returns a book_id immediately.
files
file[]
required
One or more PDF files. Pathway auto-classifies each file as bank statement, credit report, tax form, or loan application.
book_name
string
required
Name for the book.
description
string
Optional description.
webhook_url
string
If provided, Pathway will POST to this URL when parsing completes. If omitted, poll GET /books/:id.
import requests

API_BASE = "https://api.lendpathway.com/api"
TOKEN = "pat_your_token_here"
headers = {"Authorization": f"Bearer {TOKEN}"}

with open("statement.pdf", "rb") as f:
    r = requests.post(
        f"{API_BASE}/submit-book",
        headers=headers,
        files={"files": ("statement.pdf", f, "application/pdf")},
        data={
            "book_name": "Q3 Statements",
            "webhook_url": "https://your-server.com/webhook"
        }
    )

print(r.json())
# {"book_id": "...", "status": "processing", "message": "Processing started"}
Submit response
{
  "book_id": "99cc93e6-1f3f-42b1-9fe4-ba5a95be9c78",
  "status": "processing",
  "message": "Processing started"
}
Webhook payload (POST to your webhook_url when done)
{
  "book_id": "99cc93e6-1f3f-42b1-9fe4-ba5a95be9c78",
  "status": "completed",
  "book_url": "https://app.lendpathway.com/books/99cc93e6-1f3f-42b1-9fe4-ba5a95be9c78"
}

Get a book

GET /books/:id
Returns the Book object parse status, name, timestamps, and book_meta.
r = requests.get(f"{API_BASE}/books/{book_id}", headers=headers)
book = r.json()
print(book["parse_status"])           # "completed"
print(book["parse_status_message"])   # "Processed 3 bank_statements"
Book fields
FieldTypeDescription
idstringUUID
parse_statusstringnew, processing, completed, failed, cancelled
parse_status_messagestringHuman-readable status message, e.g. “Processed 4 bank_statements”
namestringBook name
descriptionstring
book_tagstringOptional label/tag for the book
is_starredbool
created_atstringISO timestamp
last_parsed_atstringISO timestamp of last parse
salesforce_opportunity_idstringSet if the book was imported from Salesforce
book_metaobjectRaw parser output (see below)
book_meta keys
KeyPresent whenDescription
parser_v2_mca_resultBank statements parsedRaw HolyMCAResult full account ledgers, transactions, positions, business info
parser_v2_credit_reportCredit report parsedCRMeta bureaus, accounts, FICO scores
parser_v2_tax_formsTax forms parsedRaw tax extraction result
parser_v2_loan_applicationLoan application parsedExtracted loan app fields
excluded_document_idsAlwaysList of document UUIDs excluded from analytics
excluded_account_idsAlwaysList of account IDs excluded from analytics
excluded_position_idsAlwaysList of position IDs excluded from revenue
revenue_exclusion_tagsAlwaysList of tags excluded from true revenue computation
For computed analytics, use /analytics and /tax-analytics rather than reading raw book_meta.

Bank statement analytics

GET /books/:id/analytics
Returns BookAnalytics computed metrics across all bank statements in the book. Applies your org’s exclusion config (excluded documents, excluded accounts, excluded positions, revenue exclusion tags) before computing. This is the primary endpoint for underwriting data.
r = requests.get(f"{API_BASE}/books/{book_id}/analytics", headers=headers)
a = r.json()
Top-level fields
FieldTypeDescription
total_depositsfloatSum of all credits across all accounts and months
total_withdrawalsfloatSum of all debits
true_revenuefloatCredits excluding loans, transfers, NSF, owner draws, and other non-revenue tags
average_daily_balancefloatWeighted average daily balance across the period
days_negative_balanceintTotal days with a negative ending balance
debt_to_income_ratiofloat(total_loan_payments / true_revenue) × 100
opening_balancefloatBalance at the start of the earliest statement
closing_balancefloatBalance at the end of the most recent statement
num_depositsintCount of deposit transactions
num_withdrawalsintCount of withdrawal transactions
total_loan_disbursementsfloatTotal money in tagged as loan disbursements
total_loan_paymentsfloatTotal money out tagged as loan payments
num_mca_positionsintNumber of detected MCA positions
statements[] per-document breakdown All documents appear in this array, including excluded ones. Excluded documents will still show their statement_period and document_name, but their metrics are zeroed. Filter by excluded_document_ids from book_meta if you want to exclude them. Each statement has document_id, document_name, statement_start_date, statement_end_date, statement_period, and an accounts[] array. Each account has:
FieldTypeDescription
account_idint0 = combined aggregate for this statement; 1+ = individual accounts
account_namestringAccount name from the bank
starting_balancefloat
ending_balancefloat
total_depositsfloat
total_withdrawalsfloat
loan_disbursementsfloat
loan_paymentsfloat
average_daily_balancefloat
days_negative_balanceint
true_revenuefloat
debt_to_income_ratiofloat
is_reconciledboolWhether the parser’s transaction sum matches the bank-reported ending balance
discrepancyfloatDifference between computed and bank-reported ending balance
loan_summary[] loan type rollup
FieldTypeDescription
loan_typestringOne of the loan tag values
total_disbursementsfloat
total_paymentsfloat
disbursement_countint
payment_countint
is_excludedboolTrue if this loan type is excluded from revenue computation
average_statement_metrics average row across all statements An AccountStatementMetrics object representing the per-statement average. Same fields as the per-account table above. Used for the Average row in CSV exports. positions[] detected debt positions Each position is a group of transactions the parser identified as belonging to the same loan or MCA.
FieldTypeDescription
position_idstring
namestringDisplay name (e.g. “ONDECK CAPITAL”)
loan_typestringmerchant_cash_advance, bank_loan, factoring, credit, lease, etc.
total_disbursementsfloatMoney received from this lender
total_paymentsfloatMoney paid to this lender
disbursement_countint
payment_countint
first_disbursement_datestringYYYY-MM-DD
last_payment_datestringYYYY-MM-DD
avg_paymentfloatAverage payment size
is_activeboolStill making payments at end of statement period
is_excludedboolTrue if excluded from revenue calculation
returns_countintReversal-tagged credits within this position
returns_totalfloat
funder_titlestringMatched funder name from your org’s funder directory
funder_linkstringFunder website
funder_contactstring
funder_emailstring
payment_schedulesarrayDetected payment schedule objects each has frequency (daily, weekly, monthly, irregular), payment_dates[], and next_expected_date
merged_accounts transaction-level data Keyed by account number. Each account has a transactions[] array. Each transaction:
FieldTypeDescription
transaction_idint
transaction_datestringYYYY-MM-DD
descriptionstringRaw description from the bank
amountfloatAlways positive
transaction_typestringcredit or debit
ledger_balancefloatRunning balance after this transaction
tagstring[]Classification tags see tags reference below
positionobjectIf this transaction belongs to a debt position, contains position_id, position_name, loan_type, funder_title
Transaction tags Tags classify what a transaction represents. Revenue computation excludes all tags in revenue_exclusion_tags.
TagMeaning
true_revenueCounts toward revenue (synthetic tag added post-classification)
merchant_cash_advanceMCA disbursement or payment
bank_loanBank loan
factoringFactoring advance or payback
creditCredit card payment
leaseEquipment/vehicle lease
internal_transferTransfer between accounts owned by the same entity
owner_transactionOwner draw or owner contribution
nsf_overdraftNSF fee or overdraft fee
bank_feeGeneral bank fee
payment_processorPayment processor deposit (Stripe, Square, etc.)
reversalTransaction reversal
untaggedCould not be classified
Tag-based aggregate fields on BookAnalytics:
FieldDescription
nsf_totalTotal NSF fee amount
num_nsfCount
overdraft_totalTotal overdraft fee amount
num_overdraftCount
owner_transaction_totalTotal owner draw/contribution amount
num_owner_transactionCount
internal_transfer_totalTotal internal transfer amount
num_internal_transferCount
bank_fee_totalTotal bank fee amount
num_bank_feeCount
payment_processor_totalTotal payment processor credits
num_payment_processorCount
reversal_totalTotal reversal amount
num_reversalCount
stop_payment_totalTotal stop payments
num_stop_paymentCount
The nsf_overdraft tag is a single tag applied to transactions. The aggregate splits into nsf_total and overdraft_total at the metrics level.

Bank statement detailed view

GET /books/:id/statements
Account-centric view of the same parsed data. Structured as a list of accounts, each with their full statement history. Useful when you need transaction-level data, daily balance maps, or per-lender activity broken down by month. Two key differences from /analytics:
  • Organized by account first, then statements under each account (vs /analytics which groups by document first)
  • Does not apply org-level exclusions — all documents and accounts are included
  • Includes daily_balances (a full {"YYYY-MM-DD": balance} map for every day in the period) and funders[] (per-lender activity within that statement)
r = requests.get(f"{API_BASE}/books/{book_id}/statements", headers=headers)
accounts = r.json()

for account in accounts:
    print(f"\n{account['account_name']} ({account['bank_name']})")
    print(f"  {account['business_name']}")
    for stmt in account["statements"]:
        print(f"  {stmt['statement_start_date']} to {stmt['statement_end_date']}")
        print(f"    Credits: ${stmt['sum_credits']:,.2f}  Debits: ${stmt['sum_debits']:,.2f}")
        print(f"    Revenue: ${stmt['revenue_credits']:,.2f}  DTI: {stmt.get('debt_to_income_ratio', 'N/A')}%")
        print(f"    Transactions: {len(stmt['transactions'])}")
        if stmt["funders"]:
            for f in stmt["funders"]:
                print(f"    Funder: {f['name']} ({f['loan_type']}) "
                      f"in=${f['total_disbursements']:,.2f} out=${f['total_payments']:,.2f} "
                      f"freq={f.get('payment_frequency', 'N/A')}")
SimpleAccount fields
FieldTypeDescription
account_idint
account_namestring
account_numberstring
bank_namestring
routing_numberstring
account_typestringe.g. checking, savings
business_namestringBusiness name extracted from the statement
business_addressobjectstreet_address, city, state_province, postal_code, country
statements[]arrayPer-statement data for this account, sorted by date ascending
SimpleStatement fields
FieldTypeDescription
document_idstring
document_namestring
statement_start_datestringYYYY-MM-DD
statement_end_datestringYYYY-MM-DD
starting_balancefloat
ending_balancefloat
min_balancefloatLowest daily balance in the period
max_balancefloatHighest daily balance in the period
sum_creditsfloatTotal deposits
sum_debitsfloatTotal withdrawals
net_depositsfloatsum_credits - sum_debits
num_depositsint
num_withdrawalsint
average_daily_balancefloat
days_negative_balanceint
days_in_periodint
revenue_creditsfloatTrue revenue for this account in this statement
loan_disbursementsfloatTotal loan disbursements received
total_mca_disbursementsfloatMCA-specific disbursements only
loan_paymentsfloatTotal loan payments made
debt_to_income_ratiofloat
transactions[]arrayAll transactions for this account in this statement period. Each has transaction_id, transaction_date, description, amount, transaction_type, ledger_balance, tag[]
daily_balancesobject{"YYYY-MM-DD": balance} for every calendar day in the period
funders[]arrayPer-lender activity in this statement period (see below)
SimpleFunder fields (inside funders[]) Each entry represents one detected loan or MCA position and its activity within this specific statement month.
FieldTypeDescription
position_idstring
namestring
loan_typestring
funder_titlestringMatched funder from your org’s funder directory
funder_linkstring
funder_contactstring
funder_emailstring
transaction_countintTotal transactions (disbursements + payments) in this month
total_disbursementsfloatMoney received from this lender in this month
total_paymentsfloatMoney paid to this lender in this month
funded_datestringDate of first disbursement in this month
first_payment_datestring
last_payment_datestring
payment_countintNumber of payment transactions
avg_payment_amountfloatAverage payment size
payment_frequencystringdaily, weekly, monthly, irregular. Null if fewer than 3 payments in the period

Credit report data

GET /books/:id
Credit report data lives in book_meta from GET /books/:id. Access it at book["book_meta"]["parser_v2_credit_report"].
r = requests.get(f"{API_BASE}/books/{book_id}", headers=headers)
book = r.json()
cr = book["book_meta"]["parser_v2_credit_report"]  # CRMeta shape
CRMeta shape (inside book_meta.parser_v2_credit_report):
{
  "primary_entity": {
    "full_name": "John Smith",
    "date_of_birth": "1985-03-14",
    "address": [
      {
        "address_line_1": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip_code": "10001",
        "is_primary": true
      }
    ]
  },
  "credit_report_body": [
    {
      "credit_bureau": { "name": "experian", "display_name": "Experian" },
      "fico_score": { "score": 720, "date_of_score": "2025-06-01" },
      "underwritten_accounts": [
        {
          "account_name": "CHASE SAPPHIRE",
          "account_number": "xxxx1234",
          "is_open": true,
          "account_type_normalized": "revolving",
          "account_status_normalized": "current",
          "collateral_type": null,
          "recent_balance": 2400.00,
          "credit_limit": 15000.00,
          "monthly_payment": 45.00,
          "date_opened": "2018-04-01"
        }
      ]
    }
  ]
}
Account status values: current, delinquent, charged_off, collection, bankruptcy, foreclosure, repossession, settled, closed, unknown Account type values: revolving, installment, mortgage, charge, other Collateral type values: unsecured, real_estate, vehicle, cash_deposit, education

Tax form analytics

GET /books/:id/tax-analytics
Returns TaxCashFlowAnalysis Fannie Mae 1084-style qualifying income computation from parsed 1040, Schedule C, 1065, and 1120S forms.
r = requests.get(f"{API_BASE}/books/{book_id}/tax-analytics", headers=headers)
tax = r.json()

for year in tax["years"]:
    print(f"{year['tax_year']}: ${year['total_qualifying_income']:,.2f}")
TaxCashFlowAnalysis fields
FieldTypeDescription
years[]arrayOne entry per tax year
most_recent_yearint
avg_qualifying_incomefloatAverage qualifying income across all years
TaxYearAnalysis per year
FieldTypeDescription
tax_yearint
total_qualifying_incomefloatSum of all income sources for this year
total_wagesfloatW-2 wages
total_schedule_cfloatSelf-employment income
total_partnershipfloatPartnership K-1 income
total_s_corpfloatS-corp K-1 income
total_depreciation_addbackfloatDepreciation added back to income
reported_agifloatAGI from line 11 of 1040
wage_sources[]arrayPer W-2 income source detail
schedule_c_sources[]arrayPer Schedule C income source detail
partnership_sources[]arrayPer K-1 (partnership) income source
s_corp_sources[]arrayPer K-1 (S-corp) income source
warnings[]arrayReconciliation warnings (missing K-1, missing return, income mismatch)

Export as CSV

GET /books/:id/csv-export
Downloads the bank statement UW table as a CSV. Applies org-level exclusions (same as /analytics).
table_format
string
default:"month_as_row"
month_as_row one row per statement period per account (default).
month_as_col metrics as rows, months as columns (pivoted). Uses the combined account (account_id=0) per statement.
# Default
curl "https://api.lendpathway.com/api/books/{book_id}/csv-export" \
  -H "Authorization: Bearer pat_xxx" \
  -o uw.csv

# Pivoted
curl "https://api.lendpathway.com/api/books/{book_id}/csv-export?table_format=month_as_col" \
  -H "Authorization: Bearer pat_xxx" \
  -o uw_pivoted.csv
Columns: Period, Document, Account, Starting Balance, Deposits, Deposit Count, Withdrawals, Withdrawal Count, Ending Balance, Loan In, Loan Out, Avg Daily Balance, Days Negative, True Revenue, DTI % Includes NET and Average summary rows.

Export as Excel

GET /books/:id/spreadsheet-export?sheet_type=mca
Returns an .xlsx file using your org’s configured spreadsheet template.
sheet_type
string
required
mca bank statements. vlad credit reports. tax tax forms.
curl "https://api.lendpathway.com/api/books/{book_id}/spreadsheet-export?sheet_type=mca" \
  -H "Authorization: Bearer pat_xxx" \
  -o statements.xlsx