> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lendpathway.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Books

> Submit documents, check parse status, and retrieve structured output by document type.

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

```mermaid theme={null}
flowchart LR
    new --> processing
    processing --> completed
    processing --> failed
    processing --> cancelled
```

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.

<ParamField body="files" type="file[]" required>
  One or more PDF files. Pathway auto-classifies each file as bank statement, credit report, tax form, or loan application.
</ParamField>

<ParamField body="book_name" type="string" required>
  Name for the book.
</ParamField>

<ParamField body="description" type="string">
  Optional description.
</ParamField>

<ParamField body="webhook_url" type="string">
  If provided, Pathway will POST to this URL when parsing completes. If omitted, poll `GET /books/:id`.
</ParamField>

<CodeGroup>
  ```python Webhook theme={null}
  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"}
  ```

  ```python Polling theme={null}
  import requests, time

  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"}
      )

  book_id = r.json()["book_id"]

  while True:
      r = requests.get(f"{API_BASE}/books/{book_id}", headers=headers)
      status = r.json()["parse_status"]
      if status in ["completed", "failed", "cancelled"]:
          break
      time.sleep(5)
  ```
</CodeGroup>

**Submit response**

```json theme={null}
{
  "book_id": "99cc93e6-1f3f-42b1-9fe4-ba5a95be9c78",
  "status": "processing",
  "message": "Processing started"
}
```

**Webhook payload** (POST to your `webhook_url` when done)

```json theme={null}
{
  "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`.

```python theme={null}
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**

| Field                       | Type   | Description                                                        |
| --------------------------- | ------ | ------------------------------------------------------------------ |
| `id`                        | string | UUID                                                               |
| `parse_status`              | string | `new`, `processing`, `completed`, `failed`, `cancelled`            |
| `parse_status_message`      | string | Human-readable status message, e.g. "Processed 4 bank\_statements" |
| `name`                      | string | Book name                                                          |
| `description`               | string |                                                                    |
| `book_tag`                  | string | Optional label/tag for the book                                    |
| `is_starred`                | bool   |                                                                    |
| `created_at`                | string | ISO timestamp                                                      |
| `last_parsed_at`            | string | ISO timestamp of last parse                                        |
| `salesforce_opportunity_id` | string | Set if the book was imported from Salesforce                       |
| `book_meta`                 | object | Raw parser output (see below)                                      |

**`book_meta` keys**

| Key                          | Present when            | Description                                                                      |
| ---------------------------- | ----------------------- | -------------------------------------------------------------------------------- |
| `parser_v2_mca_result`       | Bank statements parsed  | Raw `HolyMCAResult` full account ledgers, transactions, positions, business info |
| `parser_v2_credit_report`    | Credit report parsed    | `CRMeta` bureaus, accounts, FICO scores                                          |
| `parser_v2_tax_forms`        | Tax forms parsed        | Raw tax extraction result                                                        |
| `parser_v2_loan_application` | Loan application parsed | Extracted loan app fields                                                        |
| `excluded_document_ids`      | Always                  | List of document UUIDs excluded from analytics                                   |
| `excluded_account_ids`       | Always                  | List of account IDs excluded from analytics                                      |
| `excluded_position_ids`      | Always                  | List of position IDs excluded from revenue                                       |
| `revenue_exclusion_tags`     | Always                  | List 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.

```python theme={null}
r = requests.get(f"{API_BASE}/books/{book_id}/analytics", headers=headers)
a = r.json()
```

**Top-level fields**

| Field                      | Type  | Description                                                                      |
| -------------------------- | ----- | -------------------------------------------------------------------------------- |
| `total_deposits`           | float | Sum of all credits across all accounts and months                                |
| `total_withdrawals`        | float | Sum of all debits                                                                |
| `true_revenue`             | float | Credits excluding loans, transfers, NSF, owner draws, and other non-revenue tags |
| `average_daily_balance`    | float | Weighted average daily balance across the period                                 |
| `days_negative_balance`    | int   | Total days with a negative ending balance                                        |
| `debt_to_income_ratio`     | float | `(total_loan_payments / true_revenue) × 100`                                     |
| `opening_balance`          | float | Balance at the start of the earliest statement                                   |
| `closing_balance`          | float | Balance at the end of the most recent statement                                  |
| `num_deposits`             | int   | Count of deposit transactions                                                    |
| `num_withdrawals`          | int   | Count of withdrawal transactions                                                 |
| `total_loan_disbursements` | float | Total money in tagged as loan disbursements                                      |
| `total_loan_payments`      | float | Total money out tagged as loan payments                                          |
| `num_mca_positions`        | int   | Number 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:

| Field                   | Type   | Description                                                                   |
| ----------------------- | ------ | ----------------------------------------------------------------------------- |
| `account_id`            | int    | 0 = combined aggregate for this statement; 1+ = individual accounts           |
| `account_name`          | string | Account name from the bank                                                    |
| `starting_balance`      | float  |                                                                               |
| `ending_balance`        | float  |                                                                               |
| `total_deposits`        | float  |                                                                               |
| `total_withdrawals`     | float  |                                                                               |
| `loan_disbursements`    | float  |                                                                               |
| `loan_payments`         | float  |                                                                               |
| `average_daily_balance` | float  |                                                                               |
| `days_negative_balance` | int    |                                                                               |
| `true_revenue`          | float  |                                                                               |
| `debt_to_income_ratio`  | float  |                                                                               |
| `is_reconciled`         | bool   | Whether the parser's transaction sum matches the bank-reported ending balance |
| `discrepancy`           | float  | Difference between computed and bank-reported ending balance                  |

**`loan_summary[]`** loan type rollup

| Field                 | Type   | Description                                                 |
| --------------------- | ------ | ----------------------------------------------------------- |
| `loan_type`           | string | One of the loan tag values                                  |
| `total_disbursements` | float  |                                                             |
| `total_payments`      | float  |                                                             |
| `disbursement_count`  | int    |                                                             |
| `payment_count`       | int    |                                                             |
| `is_excluded`         | bool   | True 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.

| Field                     | Type   | Description                                                                                                                                     |
| ------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `position_id`             | string |                                                                                                                                                 |
| `name`                    | string | Display name (e.g. "ONDECK CAPITAL")                                                                                                            |
| `loan_type`               | string | `merchant_cash_advance`, `bank_loan`, `factoring`, `credit`, `lease`, etc.                                                                      |
| `total_disbursements`     | float  | Money received from this lender                                                                                                                 |
| `total_payments`          | float  | Money paid to this lender                                                                                                                       |
| `disbursement_count`      | int    |                                                                                                                                                 |
| `payment_count`           | int    |                                                                                                                                                 |
| `first_disbursement_date` | string | YYYY-MM-DD                                                                                                                                      |
| `last_payment_date`       | string | YYYY-MM-DD                                                                                                                                      |
| `avg_payment`             | float  | Average payment size                                                                                                                            |
| `is_active`               | bool   | Still making payments at end of statement period                                                                                                |
| `is_excluded`             | bool   | True if excluded from revenue calculation                                                                                                       |
| `returns_count`           | int    | Reversal-tagged credits within this position                                                                                                    |
| `returns_total`           | float  |                                                                                                                                                 |
| `funder_title`            | string | Matched funder name from your org's funder directory                                                                                            |
| `funder_link`             | string | Funder website                                                                                                                                  |
| `funder_contact`          | string |                                                                                                                                                 |
| `funder_email`            | string |                                                                                                                                                 |
| `payment_schedules`       | array  | Detected 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:

| Field              | Type      | Description                                                                                                          |
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------- |
| `transaction_id`   | int       |                                                                                                                      |
| `transaction_date` | string    | YYYY-MM-DD                                                                                                           |
| `description`      | string    | Raw description from the bank                                                                                        |
| `amount`           | float     | Always positive                                                                                                      |
| `transaction_type` | string    | `credit` or `debit`                                                                                                  |
| `ledger_balance`   | float     | Running balance after this transaction                                                                               |
| `tag`              | string\[] | Classification tags see tags reference below                                                                         |
| `position`         | object    | If 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`.

| Tag                     | Meaning                                                         |
| ----------------------- | --------------------------------------------------------------- |
| `true_revenue`          | Counts toward revenue (synthetic tag added post-classification) |
| `merchant_cash_advance` | MCA disbursement or payment                                     |
| `bank_loan`             | Bank loan                                                       |
| `factoring`             | Factoring advance or payback                                    |
| `credit`                | Credit card payment                                             |
| `lease`                 | Equipment/vehicle lease                                         |
| `internal_transfer`     | Transfer between accounts owned by the same entity              |
| `owner_transaction`     | Owner draw or owner contribution                                |
| `nsf_overdraft`         | NSF fee or overdraft fee                                        |
| `bank_fee`              | General bank fee                                                |
| `payment_processor`     | Payment processor deposit (Stripe, Square, etc.)                |
| `reversal`              | Transaction reversal                                            |
| `untagged`              | Could not be classified                                         |

**Tag-based aggregate fields** on `BookAnalytics`:

| Field                     | Description                          |
| ------------------------- | ------------------------------------ |
| `nsf_total`               | Total NSF fee amount                 |
| `num_nsf`                 | Count                                |
| `overdraft_total`         | Total overdraft fee amount           |
| `num_overdraft`           | Count                                |
| `owner_transaction_total` | Total owner draw/contribution amount |
| `num_owner_transaction`   | Count                                |
| `internal_transfer_total` | Total internal transfer amount       |
| `num_internal_transfer`   | Count                                |
| `bank_fee_total`          | Total bank fee amount                |
| `num_bank_fee`            | Count                                |
| `payment_processor_total` | Total payment processor credits      |
| `num_payment_processor`   | Count                                |
| `reversal_total`          | Total reversal amount                |
| `num_reversal`            | Count                                |
| `stop_payment_total`      | Total stop payments                  |
| `num_stop_payment`        | Count                                |

<Note>
  The `nsf_overdraft` tag is a single tag applied to transactions. The aggregate splits into `nsf_total` and `overdraft_total` at the metrics level.
</Note>

***

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

```python theme={null}
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**

| Field              | Type   | Description                                                          |
| ------------------ | ------ | -------------------------------------------------------------------- |
| `account_id`       | int    |                                                                      |
| `account_name`     | string |                                                                      |
| `account_number`   | string |                                                                      |
| `bank_name`        | string |                                                                      |
| `routing_number`   | string |                                                                      |
| `account_type`     | string | e.g. `checking`, `savings`                                           |
| `business_name`    | string | Business name extracted from the statement                           |
| `business_address` | object | `street_address`, `city`, `state_province`, `postal_code`, `country` |
| `statements[]`     | array  | Per-statement data for this account, sorted by date ascending        |

**`SimpleStatement` fields**

| Field                     | Type   | Description                                                                                                                                                                       |
| ------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `document_id`             | string |                                                                                                                                                                                   |
| `document_name`           | string |                                                                                                                                                                                   |
| `statement_start_date`    | string | YYYY-MM-DD                                                                                                                                                                        |
| `statement_end_date`      | string | YYYY-MM-DD                                                                                                                                                                        |
| `starting_balance`        | float  |                                                                                                                                                                                   |
| `ending_balance`          | float  |                                                                                                                                                                                   |
| `min_balance`             | float  | Lowest daily balance in the period                                                                                                                                                |
| `max_balance`             | float  | Highest daily balance in the period                                                                                                                                               |
| `sum_credits`             | float  | Total deposits                                                                                                                                                                    |
| `sum_debits`              | float  | Total withdrawals                                                                                                                                                                 |
| `net_deposits`            | float  | `sum_credits - sum_debits`                                                                                                                                                        |
| `num_deposits`            | int    |                                                                                                                                                                                   |
| `num_withdrawals`         | int    |                                                                                                                                                                                   |
| `average_daily_balance`   | float  |                                                                                                                                                                                   |
| `days_negative_balance`   | int    |                                                                                                                                                                                   |
| `days_in_period`          | int    |                                                                                                                                                                                   |
| `revenue_credits`         | float  | True revenue for this account in this statement                                                                                                                                   |
| `loan_disbursements`      | float  | Total loan disbursements received                                                                                                                                                 |
| `total_mca_disbursements` | float  | MCA-specific disbursements only                                                                                                                                                   |
| `loan_payments`           | float  | Total loan payments made                                                                                                                                                          |
| `debt_to_income_ratio`    | float  |                                                                                                                                                                                   |
| `transactions[]`          | array  | All transactions for this account in this statement period. Each has `transaction_id`, `transaction_date`, `description`, `amount`, `transaction_type`, `ledger_balance`, `tag[]` |
| `daily_balances`          | object | `{"YYYY-MM-DD": balance}` for every calendar day in the period                                                                                                                    |
| `funders[]`               | array  | Per-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.

| Field                 | Type   | Description                                                                            |
| --------------------- | ------ | -------------------------------------------------------------------------------------- |
| `position_id`         | string |                                                                                        |
| `name`                | string |                                                                                        |
| `loan_type`           | string |                                                                                        |
| `funder_title`        | string | Matched funder from your org's funder directory                                        |
| `funder_link`         | string |                                                                                        |
| `funder_contact`      | string |                                                                                        |
| `funder_email`        | string |                                                                                        |
| `transaction_count`   | int    | Total transactions (disbursements + payments) in this month                            |
| `total_disbursements` | float  | Money received from this lender in this month                                          |
| `total_payments`      | float  | Money paid to this lender in this month                                                |
| `funded_date`         | string | Date of first disbursement in this month                                               |
| `first_payment_date`  | string |                                                                                        |
| `last_payment_date`   | string |                                                                                        |
| `payment_count`       | int    | Number of payment transactions                                                         |
| `avg_payment_amount`  | float  | Average payment size                                                                   |
| `payment_frequency`   | string | `daily`, `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"]`.

```python theme={null}
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`):

```json theme={null}
{
  "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.

```python theme={null}
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**

| Field                   | Type  | Description                                |
| ----------------------- | ----- | ------------------------------------------ |
| `years[]`               | array | One entry per tax year                     |
| `most_recent_year`      | int   |                                            |
| `avg_qualifying_income` | float | Average qualifying income across all years |

**`TaxYearAnalysis` per year**

| Field                        | Type  | Description                                                            |
| ---------------------------- | ----- | ---------------------------------------------------------------------- |
| `tax_year`                   | int   |                                                                        |
| `total_qualifying_income`    | float | Sum of all income sources for this year                                |
| `total_wages`                | float | W-2 wages                                                              |
| `total_schedule_c`           | float | Self-employment income                                                 |
| `total_partnership`          | float | Partnership K-1 income                                                 |
| `total_s_corp`               | float | S-corp K-1 income                                                      |
| `total_depreciation_addback` | float | Depreciation added back to income                                      |
| `reported_agi`               | float | AGI from line 11 of 1040                                               |
| `wage_sources[]`             | array | Per W-2 income source detail                                           |
| `schedule_c_sources[]`       | array | Per Schedule C income source detail                                    |
| `partnership_sources[]`      | array | Per K-1 (partnership) income source                                    |
| `s_corp_sources[]`           | array | Per K-1 (S-corp) income source                                         |
| `warnings[]`                 | array | Reconciliation 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`).

<ParamField query="table_format" type="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.
</ParamField>

```bash theme={null}
# 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.

<ParamField query="sheet_type" type="string" required>
  `mca` bank statements. `vlad` credit reports. `tax` tax forms.
</ParamField>

```bash theme={null}
curl "https://api.lendpathway.com/api/books/{book_id}/spreadsheet-export?sheet_type=mca" \
  -H "Authorization: Bearer pat_xxx" \
  -o statements.xlsx
```
