# Build a Loan Step by Step

Source: https://docs.pitchpointsolutions.com/api/sami_terms/build_a_loan/

**Beta**

This guide builds the loan in [A large loan](https://docs.pitchpointsolutions.com/api/sami_terms/examples/#a-large-loan) one term at a time. Each step adds to the body from the previous step and describes the fields it introduces. The finished body has seventeen terms: four borrowers, the subject property, three participants, a company, and the loan-level terms.

Steps 1 to 5 show the whole request body. From Step 6, each step shows only the terms it adds to the `terms` array. At the end of every step, the array is a complete request for [Stage a Loan](https://docs.pitchpointsolutions.com/api/session/stage_session_sami/). All values are fabricated.

> **Before Starting:** To send a body you need an access token ([Obtaining An Access Token](https://docs.pitchpointsolutions.com/developer_guides/authentication/access_token/)) and a session ([Start a Session](https://docs.pitchpointsolutions.com/api/session/start_session/)). [Sessions and Workflows](https://docs.pitchpointsolutions.com/developer_guides/sessions_and_workflows/index/) walks through the whole flow. Mortgage terms such as REO and LTV are defined in the [Glossary](https://docs.pitchpointsolutions.com/api/sami_terms/glossary/).

### Step 1: Add a borrower

A loan is an object with a single `terms` array. Each element is a term: an object with exactly one key, which names the kind of fact it holds. A borrower is a `person` term.

```json
{
  "terms": [
    {
      "person": {
        "firstName": "Jane",
        "lastName": "Sample",
        "ssn": "000-00-0000",
        "dob": "01/31/1980"
      }
    }
  ]
}
```

| Field       | Type   | Description |
|-------------|--------|-------------|
| `terms`     | array of objects | The loan. Required, and must not be empty. |
| `person`    | object | A borrower or co-borrower. Every `person` term is a borrower. Other parties to the loan are `participant` terms. |
| `firstName` | string | The borrower's first name. |
| `lastName`  | string | The borrower's last name. |
| `ssn`       | string | The borrower's Social Security number. |
| `dob`       | string | The borrower's date of birth, in `mm/dd/yyyy` format. |

Keys are camelCase. `ssn` and `dob` are two of the [six irregular keys](https://docs.pitchpointsolutions.com/api/sami_terms/conventions/#convention-1-key-casing). A date in any other format, such as `1980-01-31`, is accepted but not recorded as sent.

### Step 2: Add contact details

Facts about the borrower go directly on the `person` object.

```json
{
  "terms": [
    {
      "person": {
        "firstName": "Jane",
        "middleName": "Quinn",
        "lastName": "Sample",
        "ssn": "000-00-0000",
        "dob": "01/31/1980",
        "homePhone": "5555550100",
        "email": "jane.sample@example.com"
      }
    }
  ]
}
```

| Field        | Type   | Description |
|--------------|--------|-------------|
| `middleName` | string | The borrower's middle name. |
| `homePhone`  | string | The borrower's home phone number. |
| `email`      | string | The borrower's email address. |

All of these fields are optional. An omitted field is recorded as absent.

### Step 3: Add a residence

A borrower's addresses are in the `residences` array.

```json
{
  "terms": [
    {
      "person": {
        "firstName": "Jane",
        "middleName": "Quinn",
        "lastName": "Sample",
        "ssn": "000-00-0000",
        "dob": "01/31/1980",
        "homePhone": "5555550100",
        "email": "jane.sample@example.com",
        "residences": [
          {
            "currentIndicator": true,
            "address": {
              "addressLine1": "1 Sample Street",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            }
          }
        ]
      }
    }
  ]
}
```

| Field              | Type    | Description |
|--------------------|---------|-------------|
| `residences`       | array of objects | The addresses the borrower has lived at. |
| `currentIndicator` | boolean | `true` for the address the borrower lives at now. |
| `address`          | object  | A postal address: `addressLine1`, `city`, `state` and `postalCode`, plus the optional `addressLine2`, `addressLine3` and `county`. The same object is used on employers, properties and participants. |

Arrays hold their objects directly, with no wrapper object. The order of entries has no meaning. Booleans are JSON booleans, `true` rather than `"true"`.

### Step 4: Add an employer

A borrower's employment is in the `employers` array.

```json
{
  "terms": [
    {
      "person": {
        "firstName": "Jane",
        "middleName": "Quinn",
        "lastName": "Sample",
        "ssn": "000-00-0000",
        "dob": "01/31/1980",
        "homePhone": "5555550100",
        "email": "jane.sample@example.com",
        "residences": [
          {
            "currentIndicator": true,
            "address": {
              "addressLine1": "1 Sample Street",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            }
          }
        ],
        "employers": [
          {
            "name": "Example Manufacturing",
            "phone": "5555550140",
            "ein": "00-0000000",
            "monthlyIncome": "9400.00",
            "yearsOnJob": "6",
            "currentIndicator": true,
            "selfEmployedIndicator": false,
            "address": {
              "addressLine1": "200 Example Parkway",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            }
          }
        ]
      }
    }
  ]
}
```

| Field                   | Type    | Description |
|-------------------------|---------|-------------|
| `employers`             | array of objects | The borrower's employment records. |
| `name`                  | string  | The employer's name. |
| `phone`                 | string  | The employer's phone number. |
| `ein`                   | string  | The employer's Employer Identification Number. |
| `monthlyIncome`         | string  | The borrower's monthly income from this employer, as a decimal string. |
| `yearsOnJob`            | string  | The borrower's tenure with this employer, in years. |
| `currentIndicator`      | boolean | `true` for the borrower's present employer. |
| `selfEmployedIndicator` | boolean | `true` if the borrower works for themselves. |
| `address`               | object  | The employer's address. |

Amounts and counts are strings: `"9400.00"` and `"6"`, not `9400` and `6`. The service ignores keys it doesn't recognize, so a misspelled key such as `employerName` is dropped without an error.

### Step 5: Add a property the borrower owns

Real estate a borrower already owns (REO, real estate owned) is in the `properties` array of that borrower's `person`. The nesting is what records the ownership. No term refers to another term.

This is the first borrower's complete term.

```json
{
  "terms": [
    {
      "person": {
        "firstName": "Jane",
        "middleName": "Quinn",
        "lastName": "Sample",
        "ssn": "000-00-0000",
        "dob": "01/31/1980",
        "homePhone": "5555550100",
        "email": "jane.sample@example.com",
        "residences": [
          {
            "currentIndicator": true,
            "address": {
              "addressLine1": "1 Sample Street",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            }
          }
        ],
        "employers": [
          {
            "name": "Example Manufacturing",
            "phone": "5555550140",
            "ein": "00-0000000",
            "monthlyIncome": "9400.00",
            "yearsOnJob": "6",
            "currentIndicator": true,
            "selfEmployedIndicator": false,
            "address": {
              "addressLine1": "200 Example Parkway",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            }
          }
        ],
        "properties": [
          {
            "propertyPurpose": "RealEstateAsset",
            "propertyUsage": "Investment",
            "propertyType": "Condominium",
            "address": {
              "addressLine1": "480 Specimen Road",
              "city": "Sampleton",
              "state": "NY",
              "postalCode": "00000"
            },
            "numberOfUnits": "1",
            "valuations": [
              {
                "valuationType": "AutomatedValuationModel",
                "valuationAmount": "289000.00"
              }
            ]
          }
        ]
      }
    }
  ]
}
```

| Field             | Type   | Description |
|-------------------|--------|-------------|
| `properties`      | array of objects | Real estate the borrower owns, other than the subject property. |
| `propertyPurpose` | string | The property's role on the loan. `RealEstateAsset` for a property the borrower owns. |
| `propertyUsage`   | string | How the property is occupied. Possible values: `PrimaryResidence`, `SecondHome`, `Investment`, `Other`. |
| `propertyType`    | string | The kind of building. [Possible values](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#propertytype). |
| `numberOfUnits`   | string | The number of units in the property. |
| `valuations`      | array of objects | The property's valuations, one entry per method. |
| `valuationType`   | string | The valuation method. [Possible values](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#valuationtype). |
| `valuationAmount` | string | The value, as a decimal string. |

A value outside a field's possible values is accepted, but it is recorded as `Other` or dropped, depending on the field. See [Value Vocabularies](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#at-a-glance).

### Step 6: Add a co-borrower

A co-borrower is a second `person` term in the same array. Add this term after the first borrower's.

```json
{
  "person": {
    "firstName": "John",
    "lastName": "Sample",
    "ssn": "000-00-0001",
    "dob": "07/04/1979",
    "homePhone": "5555550101",
    "residences": [
      {
        "currentIndicator": true,
        "address": {
          "addressLine1": "1 Sample Street",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ],
    "employers": [
      {
        "name": "Sampleton General Hospital",
        "phone": "5555550141",
        "monthlyIncome": "7250.00",
        "yearsOnJob": "11",
        "currentIndicator": true,
        "selfEmployedIndicator": false,
        "address": {
          "addressLine1": "45 Sampleton Square",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ],
    "properties": [
      {
        "propertyPurpose": "RealEstateAsset",
        "propertyUsage": "SecondHome",
        "propertyType": "PUD",
        "address": {
          "addressLine1": "77 Placeholder Lane",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ]
  }
}
```

Each borrower has their own residences, employers and properties. John lives at the same address as Jane, so his term repeats it. There is no borrower or co-borrower flag, and the order of the terms has no meaning.

### Step 7: Add a prior address and self-employment

Add the third borrower.

```json
{
  "person": {
    "firstName": "Priya",
    "lastName": "Example",
    "ssn": "000-00-0002",
    "dob": "03/22/1981",
    "homePhone": "5555550102",
    "residences": [
      {
        "currentIndicator": true,
        "address": {
          "addressLine1": "12 Example Avenue",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      },
      {
        "currentIndicator": false,
        "address": {
          "addressLine1": "88 Former Street",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ],
    "employers": [
      {
        "name": "Example Logistics",
        "monthlyIncome": "6100.00",
        "monthsOnJob": "18",
        "currentIndicator": true,
        "selfEmployedIndicator": true,
        "address": {
          "addressLine1": "300 Example Industrial Way",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ],
    "properties": [
      {
        "propertyPurpose": "RealEstateAsset",
        "propertyUsage": "Investment",
        "propertyType": "Attached",
        "address": {
          "addressLine1": "15 Example Terrace",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        },
        "numberOfUnits": "2"
      }
    ]
  }
}
```

| Field                   | Type    | Description |
|-------------------------|---------|-------------|
| `currentIndicator`      | boolean | `false` for an address the borrower no longer lives at. |
| `selfEmployedIndicator` | boolean | `true` for a borrower who owns the business. |
| `monthsOnJob`           | string  | The borrower's tenure with this employer, in months. An alternative to `yearsOnJob`. Neither is calculated from the other. |

### Step 8: Add a borrower with fewer details

Add the fourth borrower.

```json
{
  "person": {
    "firstName": "Daniel",
    "lastName": "Example",
    "nameSuffix": "Jr.",
    "ssn": "000-00-0003",
    "dob": "11/09/1976",
    "homePhone": "5555550103",
    "residences": [
      {
        "currentIndicator": true,
        "address": {
          "addressLine1": "12 Example Avenue",
          "city": "Sampleton",
          "state": "NY",
          "postalCode": "00000"
        }
      }
    ]
  }
}
```

| Field        | Type   | Description |
|--------------|--------|-------------|
| `nameSuffix` | string | A generational or professional suffix, such as `Jr.` or `III`. |

> **Warning:** Each product sets how many borrowers it analyzes. Staging doesn't check the count. A loan with more borrowers than the product accepts stages successfully, then fails when the workflow runs. Ask your Pitchpoint Account Representative for your product's limit.

### Step 9: Add the subject property

The subject property is the property the loan is secured by. It is the `property` term, and it is the property that property products, such as FEMA flood, analyze. Add this term.

```json
{
  "property": {
    "propertyUsage": "PrimaryResidence",
    "propertyType": "Detached",
    "address": {
      "addressLine1": "1 Sample Street",
      "city": "Sampleton",
      "state": "NY",
      "postalCode": "00000",
      "county": "Sampleton County"
    },
    "assessorsParcelNumber": "0000-00-000",
    "countyFIPSCode": "36029",
    "numberOfUnits": "1",
    "saleDate": "08/29/2026",
    "saleAmount": "562500.00",
    "assessmentDate": "01/15/2026",
    "assessmentAmount": "540000.00",
    "valuations": [
      {
        "valuationType": "FullAppraisal",
        "valuationAmount": "565000.00"
      }
    ]
  }
}
```

| Field                   | Type   | Description |
|-------------------------|--------|-------------|
| `property`              | object | The loan's property. Recorded as the subject property. |
| `county`                | string | The county name, on `address`. |
| `assessorsParcelNumber` | string | The parcel number recorded by the county assessor. |
| `countyFIPSCode`        | string | The five-digit county FIPS code. |
| `saleDate`              | string | The date of the last sale, in `mm/dd/yyyy` format. |
| `saleAmount`            | string | The price of the last sale. |
| `assessmentDate`        | string | The date of the last assessment, in `mm/dd/yyyy` format. |
| `assessmentAmount`      | string | The assessed value. |

`propertyPurpose` is not needed here: a `property` term is always recorded as the subject property. A loan has at most one `property` term. If you send more than one, the last is kept and the others are discarded, without an error. A borrower's other real estate belongs in that borrower's `properties` ([Step 5](https://docs.pitchpointsolutions.com/api/sami_terms/build_a_loan/#step-5-add-a-property-the-borrower-owns)).

### Step 10: Add the lender

A party to the loan who is not a borrower is a `participant` term. Add the lender.

```json
{
  "participant": {
    "participantType": "Lender",
    "companyName": "Example Lending",
    "address": {
      "addressLine1": "3000 Example Center Drive",
      "city": "Sampleton",
      "state": "NY",
      "postalCode": "00000"
    },
    "contactPoint": {
      "roleType": "Work",
      "type": "Phone",
      "value": "5555550170",
      "preferenceIndicator": true
    },
    "identifiers": [
      {
        "identifierType": "NMLS",
        "identifierValue": "000000"
      }
    ]
  }
}
```

| Field                 | Type    | Description |
|-----------------------|---------|-------------|
| `participant`         | object  | A professional or institutional party to the loan. |
| `participantType`     | string  | The party's role. Matched exactly. A value that doesn't match is recorded as `OtherCompany`, or `OtherIndividual` when there is no `companyName`. [Possible values](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#participanttype). |
| `companyName`         | string  | The name of the organization. |
| `contactPoint`        | object  | A single way to reach the party. |
| `roleType`            | string  | The capacity the contact point applies in. Possible values: `Home`, `Work`, `Mobile`. |
| `type`                | string  | The channel. Possible values: `Phone`, `Email`, `Fax`, `Other`. Any other value discards the contact point. |
| `value`               | string  | The phone number or address. |
| `preferenceIndicator` | boolean | `true` if this is the party's preferred contact point. |
| `identifiers`         | array of objects | The party's government and industry identifiers. |
| `identifierType`      | string  | The kind of identifier. Possible values: `SSN`, `EIN`, `NMLS`. Identifiers of any other type are not recorded. |
| `identifierValue`     | string  | The identifier. |

### Step 11: Add an appraiser and an escrow company

A participant can be an individual, an organization, or an individual at an organization. Add both terms.

```json
{
  "participant": {
    "participantType": "Appraiser",
    "firstName": "Morgan",
    "lastName": "Reed",
    "companyName": "Example Appraisal Group",
    "address": {
      "addressLine1": "18 Example Court",
      "city": "Sampleton",
      "state": "NY",
      "postalCode": "00000"
    },
    "contactPoint": {
      "roleType": "Mobile",
      "type": "Phone",
      "value": "5555550171",
      "preferenceIndicator": true
    },
    "licenses": [
      {
        "licenseNumber": "LIC000000",
        "licenseType": "Appraiser License",
        "licenseState": "NY"
      }
    ]
  }
}
```

```json
{
  "participant": {
    "participantType": "Escrow",
    "companyName": "Example Title & Escrow",
    "address": {
      "addressLine1": "9 Example Plaza",
      "city": "Sampleton",
      "state": "NY",
      "postalCode": "00000"
    },
    "contactPoint": {
      "roleType": "Work",
      "type": "Phone",
      "value": "5555550172",
      "preferenceIndicator": false
    }
  }
}
```

| Field           | Type   | Description |
|-----------------|--------|-------------|
| `firstName`     | string | The individual's first name. Used with `companyName` for an individual at a firm. |
| `lastName`      | string | The individual's last name. |
| `licenses`      | array of objects | The party's professional licenses, one entry per license and state. |
| `licenseNumber` | string | The license number. |
| `licenseType`   | string | The kind of license. |
| `licenseState`  | string | The two-letter code of the issuing state. |

### Step 12: Add a company

A `company` term describes an organization that is itself a subject of the loan. It is used mainly by the bank-account monitoring products. Send one only when your product requires it.

```json
{
  "company": {
    "name": "Example Holdings LLC",
    "address": {
      "addressLine1": "250 Example Boulevard",
      "city": "Sampleton",
      "state": "NY",
      "postalCode": "00000"
    }
  }
}
```

| Field     | Type   | Description |
|-----------|--------|-------------|
| `company` | object | An organization that is a subject of the loan. |
| `name`    | string | The company's name. |

### Step 13: Add the loan-level terms

Facts about the loan have their own branches. Add these five terms.

```json
{ "loanTerms": { "noteAmount": "450000.00", "loanAmount": "450000.00", "noteRatePercent": "6.375", "noteDate": "08/29/2026", "loanPurpose": "Purchase", "mortgageType": "Conventional" } }
```

```json
{ "loanToValue": { "ltvRatioPercent": "80.00", "cltvRatioPercent": "85.00" } }
```

```json
{ "transactionDetail": { "purchasePrice": "562500.00" } }
```

```json
{ "loanDetail": { "loanOriginatorApplicationDate": "07/12/2026", "totalDebtToIncomeRatioPercent": "38.50" } }
```

```json
{ "closing": { "settlementDate": "09/30/2026" } }
```

| Field                           | Type   | Description |
|---------------------------------|--------|-------------|
| `noteAmount`                    | string | The face amount of the note. |
| `loanAmount`                    | string | The loan amount. Recorded separately from `noteAmount`. |
| `noteRatePercent`               | string | The note rate, as a percentage: `"6.375"`, not `"0.06375"`. |
| `noteDate`                      | string | The date of the note, in `mm/dd/yyyy` format. |
| `loanPurpose`                   | string | Possible values: `Purchase`, `Refinance`, `Other`, `Unknown`. |
| `mortgageType`                  | string | The mortgage program. Matched exactly: `Conventional` is recorded, `CONVENTIONAL` is dropped. [Possible values](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#mortgagetype). |
| `ltvRatioPercent`               | string | The loan-to-value ratio, as a percentage. |
| `cltvRatioPercent`              | string | The combined loan-to-value ratio, as a percentage. |
| `purchasePrice`                 | string | The contract purchase price. |
| `loanOriginatorApplicationDate` | string | The application date, in `mm/dd/yyyy` format. |
| `totalDebtToIncomeRatioPercent` | string | The total debt-to-income ratio, as a percentage. |
| `settlementDate`                | string | The closing date, in `mm/dd/yyyy` format. |

Send at most one of each of these branches. If you send more than one, the last replaces the others. A refinance also has a `refinance` term, with `loanPurpose` set to `Refinance`.

### Step 14: Add housing expenses

`housingExpense` is the loan-level branch that repeats, once per expense. Add three terms.

```json
{ "housingExpense": { "housingExpenseType": "FirstMortgagePrincipalAndInterest", "presentHousingExpense": true, "monthlyAmount": "1850.00" } }
```

```json
{ "housingExpense": { "housingExpenseType": "HazardInsurance", "presentHousingExpense": true, "monthlyAmount": "140.00" } }
```

```json
{ "housingExpense": { "housingExpenseType": "RealEstateTax", "presentHousingExpense": true, "monthlyAmount": "410.00" } }
```

| Field                   | Type    | Description |
|-------------------------|---------|-------------|
| `housingExpenseType`    | string  | The kind of expense. Matched exactly. [Possible values](https://docs.pitchpointsolutions.com/api/sami_terms/vocabularies/#housingexpensetype). |
| `presentHousingExpense` | boolean | `true` for an expense the borrowers pay now. Required. |
| `monthlyAmount`         | string  | The monthly amount. |

> **Warning:** Send `"presentHousingExpense": true` on every line. A proposed expense is not recorded, and a line without the flag fails. See [Known Issues](https://docs.pitchpointsolutions.com/api/sami_terms/known_issues/#proposed-housing-expense).

### Step 15: Stage the loan

The body now has seventeen terms. [A large loan](https://docs.pitchpointsolutions.com/api/sami_terms/examples/#a-large-loan) shows it in full. The order of the terms has no meaning.

Send it to [Stage a Loan](https://docs.pitchpointsolutions.com/api/session/stage_session_sami/). Keep your own copy of what you send. The loan is recorded against the field rules and value lists, so what a later read returns can differ from the request.
