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

# Working with credit reports

> Access parsed credit report data: FICO scores, account history, and inquiries by bureau.

## Where the data lives

Credit report data lives in `book_meta` from `GET /books/:id`. Read 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"]
```

`parser_v2_credit_report` is `null` if the book has no parsed credit report.

***

## Subject entity

```python theme={null}
entity = cr["primary_entity"]
print(f"Name:  {entity['full_name']}")
print(f"DOB:   {entity.get('date_of_birth', 'N/A')}")

for addr in entity.get("address", []):
    if addr.get("is_primary"):
        print(f"Address: {addr['address_line_1']}, {addr['city']}, {addr['state']} {addr['zip_code']}")
```

***

## FICO scores by bureau

The report can contain data from up to three bureaus: Experian, Equifax, TransUnion.

```python theme={null}
for bureau_data in cr["credit_report_body"]:
    bureau = bureau_data["credit_bureau"]["display_name"]
    fico = bureau_data.get("fico_score") or {}
    score = fico.get("score")
    date = fico.get("date_of_score")
    print(f"{bureau}: FICO {score} (as of {date})")
```

***

## Accounts by bureau

Each bureau has an `underwritten_accounts[]` list.

```python theme={null}
for bureau_data in cr["credit_report_body"]:
    bureau = bureau_data["credit_bureau"]["display_name"]
    accounts = bureau_data["underwritten_accounts"]

    print(f"\n{bureau} ({len(accounts)} accounts)")

    for acct in accounts:
        status = acct.get("account_status_normalized", "unknown")
        acct_type = acct.get("account_type_normalized", "")
        balance = acct.get("recent_balance")
        limit = acct.get("credit_limit")

        print(f"  {acct['account_name']} ({acct_type}) {status}")
        if balance is not None:
            print(f"    Balance: ${balance:,.2f}"
                  + (f" / ${limit:,.2f} limit" if limit else ""))
        if acct.get("monthly_payment"):
            print(f"    Monthly payment: ${acct['monthly_payment']:,.2f}")
```

**Account status values**: `current`, `delinquent`, `charged_off`, `collection`, `bankruptcy`, `foreclosure`, `repossession`, `settled`, `closed`, `unknown`

**Account type values**: `revolving`, `installment`, `mortgage`, `charge`, `other`

***

## Derogatory accounts

```python theme={null}
derogatory_statuses = {"delinquent", "charged_off", "collection", "bankruptcy",
                        "foreclosure", "repossession", "settled"}

for bureau_data in cr["credit_report_body"]:
    bureau = bureau_data["credit_bureau"]["display_name"]
    derogatories = [
        a for a in bureau_data["underwritten_accounts"]
        if a.get("account_status_normalized") in derogatory_statuses
    ]
    if derogatories:
        print(f"\n{bureau} derogatory accounts:")
        for acct in derogatories:
            print(f"  {acct['account_name']}: {acct['account_status_normalized']}")
```

***

## Hard inquiries

```python theme={null}
for bureau_data in cr["credit_report_body"]:
    bureau = bureau_data["credit_bureau"]["display_name"]
    inquiries = bureau_data["credit_bureau"].get("inquiries") or []
    print(f"\n{bureau} inquiries ({len(inquiries)}):")
    for inq in inquiries:
        print(f"  {inq['inquiry_date']}  {inq.get('creditor_name', 'Unknown')}")
```

***

## Total monthly debt obligations

Use a dedup set to avoid counting the same account twice across bureaus.

```python theme={null}
total_monthly = 0
seen = set()

for bureau_data in cr["credit_report_body"]:
    for acct in bureau_data["underwritten_accounts"]:
        key = (acct.get("account_name", ""), acct.get("account_number", ""))
        if key not in seen and acct.get("is_open") and acct.get("monthly_payment"):
            seen.add(key)
            total_monthly += acct["monthly_payment"]

print(f"Total monthly obligations: ${total_monthly:,.2f}")
```

***

## Self-reported and authorized user accounts

Pathway flags these so you can exclude them from underwriting.

```python theme={null}
for bureau_data in cr["credit_report_body"]:
    for acct in bureau_data["underwritten_accounts"]:
        if acct.get("is_authorized_user"):
            print(f"AU account: {acct['account_name']}")
        if acct.get("is_self_reported"):
            print(f"Self-reported: {acct['account_name']}")
```

***

## Full credit summary

```python theme={null}
def credit_summary(cr):
    all_accounts = [
        acct
        for bureau_data in cr["credit_report_body"]
        for acct in bureau_data["underwritten_accounts"]
        if not acct.get("is_authorized_user")
        and not acct.get("is_self_reported")
    ]

    derogatory = {"delinquent", "charged_off", "collection", "bankruptcy",
                  "foreclosure", "repossession", "settled"}

    fico_scores = [
        bureau_data["fico_score"]["score"]
        for bureau_data in cr["credit_report_body"]
        if bureau_data.get("fico_score") and bureau_data["fico_score"].get("score")
    ]

    return {
        "entity": cr["primary_entity"]["full_name"],
        "fico_scores": fico_scores,
        "median_fico": sorted(fico_scores)[len(fico_scores) // 2] if fico_scores else None,
        "open_accounts": sum(1 for a in all_accounts if a.get("is_open")),
        "derogatory_accounts": sum(1 for a in all_accounts if a.get("account_status_normalized") in derogatory),
        "total_revolving_balance": sum(
            (a.get("recent_balance") or 0)
            for a in all_accounts
            if a.get("account_type_normalized") == "revolving" and a.get("is_open")
        ),
        "total_monthly_obligations": sum(
            (a.get("monthly_payment") or 0)
            for a in all_accounts
            if a.get("is_open")
        ),
    }
```
