MLA Lookup

Overview

The Military Lending Act (MLA) prohibits lenders from offering certain financial products to active-duty servicemembers and their dependents above a 36% Military Annual Percentage Rate. Before extending credit (e.g. a float advance), FloatMe checks whether a user is a covered borrower under the MLA.

The lookup is performed via Experian’s MLA covered borrower service. Results are saved to DynamoDB for audit and compliance purposes.

API

POST /{user_id}/user/mla-lookup

Request

All fields are required. Values are sanitized before being sent to Experian: whitespace is trimmed, hyphens are replaced with spaces, and non-alphanumeric characters (except spaces) are removed.

{
  "first_name":    "John",
  "last_name":     "Smith",
  "ssn":           "123456789",
  "date_of_birth": "01011990",
  "address_line1": "123 Main St",
  "city":          "San Antonio",
  "state":         "TX",
  "zip_code":      "78245"
}

Field Format Requirements

Field Format Notes

ssn

9 digits, no dashes

Must match ^\d{9}$ after sanitization

date_of_birth

MMDDYYYY (8 digits)

Must match ^\d{8}$ after sanitization

state

2-letter postal code

Must match ^[A-Za-z]{2}$

zip_code

5–9 digits

Must match ^\d{5,9}$

first_name, last_name, address_line1, city

Non-empty string

Trimmed and sanitized; must not be empty after sanitization

Response 200 OK

Both covered and non-covered results return 200 OK. Check is_military to determine the outcome.

{
  "message_number": "1203",
  "message_text":   "MLA COVERED BORROWER",
  "is_military":    true
}

Flow

POST /{user_id}/user/mla-lookup
     │
     ▼
Decode and validate request ──invalid──► 400 VALIDATION_ERROR
     │
     ▼
Sanitize all fields
     │
     ▼
Send lookup request to Experian
  *ExperianError (application rejection)?
    ──► Save error record to DynamoDB
           Save failure? ──► log + metric (non-fatal, response unchanged)
           │
           ▼
         User-attributed code (010, 018, 213)? ──► 403 BLOCKED
         Auth/infra code (2000)?               ──► 502 SERVICE_UNAVAILABLE
         Unknown code?                         ──► 500 UNEXPECTED_ERROR
  ErrMLALookup (infrastructure/network failure)? ──► 502 SERVICE_UNAVAILABLE
  Unrecognized error? ──► 500 UNEXPECTED_ERROR (no save)
     │
     ▼
Save result to DynamoDB (MLALookupRecord)
  Save failure (covered borrower)? ──► 500 UNEXPECTED_ERROR
  Save failure (non-covered)?      ──► log + metric (non-fatal)
     │
     ▼
Map Experian message number to response:
  MessageNumberCoveredBorrower      ──► 200, is_military: true
  MessageNumberNoRecordFound        ──► 200, is_military: false
  MessageNumberMissingRequiredData  ──► 400 VALIDATION_ERROR
  MessageNumberLookupTableUnavailable ──► 502 SERVICE_UNAVAILABLE
  MessageNumberSearchNotAllowed     ──► 502 SEARCH_NOT_ALLOWED (alert engineering)
  Unexpected message number         ──► 500 UNEXPECTED_ERROR

Experian Response Codes

Message Number is_military Meaning

Covered Borrower (e.g. 1203)

true

User is an active-duty servicemember or dependent — MLA restrictions apply

No Record Found

false

User is not a covered borrower — no MLA restrictions

Missing Required Data

Experian rejected the request due to missing or invalid fields — returned as 400

Lookup Table Unavailable

Experian’s MLA database is temporarily unavailable — returned as 502

Search Not Allowed

FloatMe’s Experian account is not permitted to perform this search — returned as 502. Requires engineering investigation.

Application Error — User Attributed (e.g. 010, 018, 213)

Experian rejected the request due to a user-level attribute: 010 = consumer is a minor, 018 = fraud reported by consumer, 213 = Vermont consumer block. Returned as 403 BLOCKED. No retry.

Application Error — Auth/Infrastructure (e.g. 2000)

Experian rejected the request due to an account-level configuration issue: 2000 = product not assigned. Returned as 502 SERVICE_UNAVAILABLE. Requires engineering investigation.

Error Format

{
  "message":    "invalid request: ssn - must be 9 digits with no dashes",
  "status_code": 400,
  "error_code": "VALIDATION_ERROR"
}
error_code Meaning

VALIDATION_ERROR

Request failed format validation before reaching Experian

BLOCKED

User is not eligible due to a user-attributed Experian block (minor, fraud, state-level block) — no retry

SERVICE_UNAVAILABLE

Experian service is unavailable, or an auth/infrastructure error occurred on our account

SEARCH_NOT_ALLOWED

Experian rejected the search at the account level — requires engineering action

UNEXPECTED_ERROR

An unhandled error occurred

Data Storage

Every Experian response — successful lookups and application-level errors (*ExperianError) — is saved to the prod-user-service-users DynamoDB table as an MLALookupRecord. Infrastructure failures (ErrMLALookup) and unrecognized errors are not persisted. See Users & Data Model: MLA Lookup Record for the full schema.

The record includes the Experian transaction ID, enabling audit trail and reconciliation with Experian’s own records. Application errors store an empty transaction ID as none is returned by Experian on non-2xx responses.

Metrics

Metric Description

user.mla.lookup

Emitted on every completed lookup, tagged with message_number

user.mla.lookup.save_failure

Emitted when any DynamoDB write fails — after a successful Experian response or after an Experian application error (*ExperianError)