docs.vin

loan

The loan noun — identity, lifecycle, events, and every capability as an anchored section: 19 capabilities, 0 live, 19 sandbox, 0 declared.

loan is one of the estate's 317 automotive nouns — a job a car needs done. It carries 19 capabilities: 0 live, 19 sandbox, 0 declared · doors aggregator.vin.

Identity

Nounloan
PillarServices (facets: 6 data · 9 services · 4 commerce)
Capabilities19 — 0 live · 19 sandbox · 0 declared
EntitiesLoan
Doorsaggregator.vin
SDKVin.loan.* from apis.vin
Address/catalog/loan#{action} — the anchor IS the wire name minus loan.

Lifecycle

LoanLoanFSM: 4 states, 3 transitions — ContractsInTransit · Funded · Serviced · PaidOff. Each transition is a past-tense event on the record.

Events

The vocabulary this noun can append to the record — 14 past-tense, versioned event types, each linked to the capability that emits it:

Discover & read

status

loan.status · GET /loans/status · gate none · sandbox · answers LoanStatus@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.status
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.status({"vin":"1C4RJFBG3LC288648"})
GET /loans/status
curl 'https://apis.vin/loans/status?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.824Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanStatus@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "loan": {
      "id": "LN-34b5017c",
      "standing": "eligible",
      "servicing": "Current"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "loan": {
      "id": "LN-34b5017c",
      "standing": "eligible",
      "servicing": "Current"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Quote & price

terms

loan.terms · GET /loans/terms · gate none · sandbox · answers LoanTerms@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.terms
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.terms({"vin":"1C4RJFBG3LC288648"})
GET /loans/terms
curl 'https://apis.vin/loans/terms?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.824Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanTerms@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "terms": {
      "id": "LN-34b5017c",
      "decision": "approved",
      "rateBand": "best",
      "apr": "4.49",
      "termMonths": 72,
      "stipulations": []
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "terms": {
      "id": "LN-34b5017c",
      "decision": "approved",
      "rateBand": "best",
      "apr": "4.49",
      "termMonths": 72,
      "stipulations": []
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Apply & book

assign

loan.assign · POST /loans/assign · gate offer · sandbox · answers LoanAssign@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.assigned@1.

the SDK — loan.assign
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.assign({"vin":"1C4RJFBG3LC288648"})
POST /loans/assign
curl -X POST https://apis.vin/loans/assign \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.780Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanAssign@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "assignment": {
      "status": "assigned",
      "id": "LN-34b5017c",
      "to": {
        "fsId": "F00SET",
        "name": "Southeast Toyota Finance"
      }
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "assignment": {
      "status": "assigned",
      "id": "LN-34b5017c",
      "to": {
        "fsId": "F00SET",
        "name": "Southeast Toyota Finance"
      }
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

originate

loan.originate · POST /loans/originate · gate offer · sandbox · answers LoanOriginate@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.originated@1.

the SDK — loan.originate
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.originate({"vin":"1C4RJFBG3LC288648"})
POST /loans/originate
curl -X POST https://apis.vin/loans/originate \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.817Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanOriginate@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "origination": {
      "status": "originated",
      "id": "LN-34b5017c",
      "principalCents": 2300000,
      "currency": "USD",
      "apr": "4.49",
      "termMonths": 72,
      "monthlyPaymentCents": 36500
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "origination": {
      "status": "originated",
      "id": "LN-34b5017c",
      "principalCents": 2300000,
      "currency": "USD",
      "apr": "4.49",
      "termMonths": 72,
      "monthlyPaymentCents": 36500
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Pay & settle

pay

loan.pay · POST /loans/pay · gate offer · sandbox · answers LoanPay@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.failed@1 · Loan.paid@1.

the SDK — loan.pay
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.pay({"vin":"1C4RJFBG3LC288648"})
POST /loans/pay
curl -X POST https://apis.vin/loans/pay \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.819Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanPay@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "payment": {
      "status": "posted",
      "id": "PAY-b87fe318",
      "amount": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "dueDate": "2026-08-25T00:00:00.000Z",
      "loanId": "LN-34b5017c"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "payment": {
      "status": "posted",
      "id": "PAY-b87fe318",
      "amount": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "dueDate": "2026-08-25T00:00:00.000Z",
      "loanId": "LN-34b5017c"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

fund

loan.fund · POST /loans/fund · gate offer · sandbox · answers LoanFund@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.failed@1 · Loan.funded@1.

the SDK — loan.fund
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.fund({"vin":"1C4RJFBG3LC288648"})
POST /loans/fund
curl -X POST https://apis.vin/loans/fund \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.816Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanFund@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "funding": {
      "status": "funded",
      "id": "LN-34b5017c",
      "amountCents": 2300000,
      "currency": "USD"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "funding": {
      "status": "funded",
      "id": "LN-34b5017c",
      "amountCents": 2300000,
      "currency": "USD"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

autopay

loan.autopay · POST /loans/autopay · gate offer · sandbox · answers LoanAutopay@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.autopayEnrolled@1 · Loan.failed@1.

the SDK — loan.autopay
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.autopay({"vin":"1C4RJFBG3LC288648"})
POST /loans/autopay
curl -X POST https://apis.vin/loans/autopay \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.787Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanAutopay@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "autopay": {
      "status": "enrolled",
      "id": "LN-34b5017c",
      "drawDay": 15
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "autopay": {
      "status": "enrolled",
      "id": "LN-34b5017c",
      "drawDay": 15
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Fulfill & operate

paymentRemind

loan.paymentRemind · POST /loans/payment-remind · gate key · sandbox · answers LoanPaymentRemind@1

No input — this capability takes no request body.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.paymentReminded@1.

the SDK — loan.paymentRemind
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.paymentRemind()
POST /loans/payment-remind
curl -X POST https://apis.vin/loans/payment-remind \
  -H 'content-type: application/json' \
  -d '{}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-16T14:50:09.914Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanPaymentRemind@1",
  "value": {
    "vin": "1HGCM82633A004352",
    "noun": "loan",
    "asOf": "2026-08-10",
    "reminder": {
      "status": "no-open-loan"
    }
  },
  "evidence": {
    "vin": "1HGCM82633A004352",
    "noun": "loan",
    "asOf": "2026-08-10",
    "reminder": {
      "status": "no-open-loan"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Lifecycle & state

disclose

loan.disclose · POST /loans/disclose · gate offer · sandbox · answers LoanDisclose@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.disclosed@1.

the SDK — loan.disclose
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.disclose({"vin":"1C4RJFBG3LC288648"})
POST /loans/disclose
curl -X POST https://apis.vin/loans/disclose \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.815Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanDisclose@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "disclosure": {
      "id": "LN-34b5017c",
      "apr": "4.49",
      "termMonths": 72,
      "checks": [
        "tila",
        "ecoa"
      ],
      "status": "disclosed"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "disclosure": {
      "id": "LN-34b5017c",
      "apr": "4.49",
      "termMonths": 72,
      "checks": [
        "tila",
        "ecoa"
      ],
      "status": "disclosed"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

More actions

amortize

loan.amortize · GET /loans/amortize · gate key · sandbox · answers LoanAmortize@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.amortize
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.amortize({"vin":"1C4RJFBG3LC288648"})
GET /loans/amortize
curl 'https://apis.vin/loans/amortize?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.772Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanAmortize@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "amortization": {
      "id": "LN-34b5017c",
      "principalCents": 2300000,
      "currency": "USD",
      "apr": "4.49",
      "termMonths": 72,
      "monthlyPaymentCents": 36500,
      "totalOfPaymentsCents": 2628000
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "amortization": {
      "id": "LN-34b5017c",
      "principalCents": 2300000,
      "currency": "USD",
      "apr": "4.49",
      "termMonths": 72,
      "monthlyPaymentCents": 36500,
      "totalOfPaymentsCents": 2628000
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

apr

loan.apr · GET /loans/apr · gate key · sandbox · answers LoanApr@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.apr
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.apr({"vin":"1C4RJFBG3LC288648"})
GET /loans/apr
curl 'https://apis.vin/loans/apr?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.775Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanApr@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "apr": {
      "rate": "4.49",
      "termMonths": 72,
      "tier": "super-prime"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "apr": {
      "rate": "4.49",
      "termMonths": 72,
      "tier": "super-prime"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

balance

loan.balance · GET /loans/balance · gate key · sandbox · answers LoanBalance@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.balance
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.balance({"vin":"1C4RJFBG3LC288648"})
GET /loans/balance
curl 'https://apis.vin/loans/balance?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.801Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanBalance@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "balance": {
      "vin": "1C4RJFBG3LC288648",
      "lienholder": "Huntington National Bank",
      "grossPayOffAmount": {
        "currency": "USD",
        "minorUnits": 2474548
      },
      "netPayOffAmount": {
        "currency": "USD",
        "minorUnits": 2462421
      },
      "perDiem": {
        "currency": "USD",
        "minorUnits": 332
      },
      "allowance": {
        "currency": "USD",
        "minorUnits": 12127
      },
      "goodThrough": "2026-08-20T00:00:00.000Z",
      "nextPaymentAmount": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "nextPaymentDate": "2026-08-25T00:00:00.000Z",
      "freshQuote": true,
      "reference": "poq_1305dc7c"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "balance": {
      "vin": "1C4RJFBG3LC288648",
      "lienholder": "Huntington National Bank",
      "grossPayOffAmount": {
        "currency": "USD",
        "minorUnits": 2474548
      },
      "netPayOffAmount": {
        "currency": "USD",
        "minorUnits": 2462421
      },
      "perDiem": {
        "currency": "USD",
        "minorUnits": 332
      },
      "allowance": {
        "currency": "USD",
        "minorUnits": 12127
      },
      "goodThrough": "2026-08-20T00:00:00.000Z",
      "nextPaymentAmount": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "nextPaymentDate": "2026-08-25T00:00:00.000Z",
      "freshQuote": true,
      "reference": "poq_1305dc7c"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

chargeoff

loan.chargeoff · POST /loans/chargeoff · gate offer · sandbox · answers LoanChargeoff@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.chargedOff@1.

the SDK — loan.chargeoff
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.chargeoff({"vin":"1C4RJFBG3LC288648"})
POST /loans/chargeoff
curl -X POST https://apis.vin/loans/chargeoff \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.807Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanChargeoff@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "chargeoff": {
      "status": "no-grounds",
      "servicing": "Current"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "chargeoff": {
      "status": "no-grounds",
      "servicing": "Current"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

contract

loan.contract · POST /loans/contract · gate offer · sandbox · answers LoanContract@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.contracted@1.

the SDK — loan.contract
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.contract({"vin":"1C4RJFBG3LC288648"})
POST /loans/contract
curl -X POST https://apis.vin/loans/contract \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.815Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanContract@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "contract": {
      "id": "EC-3a524141",
      "position": "Generated",
      "loanId": "LN-34b5017c"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "contract": {
      "id": "EC-3a524141",
      "position": "Generated",
      "loanId": "LN-34b5017c"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

late

loan.late · POST /loans/late · gate offer · sandbox · answers LoanLate@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.failed@1 · Loan.lateAssessed@1.

the SDK — loan.late
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.late({"vin":"1C4RJFBG3LC288648"})
POST /loans/late
curl -X POST https://apis.vin/loans/late \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.816Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanLate@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "late": {
      "late": false,
      "servicing": "Current"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "late": {
      "late": false,
      "servicing": "Current"
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

modify

loan.modify · POST /loans/modify · gate offer · sandbox · answers LoanModify@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.modified@1.

the SDK — loan.modify
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.modify({"vin":"1C4RJFBG3LC288648"})
POST /loans/modify
curl -X POST https://apis.vin/loans/modify \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.817Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanModify@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "modification": {
      "status": "modified",
      "id": "LN-34b5017c",
      "apr": "4.49",
      "termMonths": 72
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "modification": {
      "status": "modified",
      "id": "LN-34b5017c",
      "apr": "4.49",
      "termMonths": 72
    },
    "payer": {
      "name": "Ava Good",
      "castRow": "super-prime",
      "creditTier": "super-prime"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

reage

loan.reage · POST /loans/reage · gate offer · sandbox · answers LoanReage@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.reaged@1.

the SDK — loan.reage
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.reage({"vin":"1C4RJFBG3LC288648"})
POST /loans/reage
curl -X POST https://apis.vin/loans/reage \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.819Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanReage@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "reage": {
      "status": "nothing-past-due",
      "servicing": "Current"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "reage": {
      "status": "nothing-past-due",
      "servicing": "Current"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

satisfy

loan.satisfy · POST /loans/satisfy · gate offer · sandbox · answers LoanSatisfy@1

FieldTypeRequiredNotes
vinstringno

The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

EmitsLoan.satisfied@1.

the SDK — loan.satisfy
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.satisfy({"vin":"1C4RJFBG3LC288648"})
POST /loans/satisfy
curl -X POST https://apis.vin/loans/satisfy \
  -H 'content-type: application/json' \
  -d '{"vin":"1C4RJFBG3LC288648"}'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.819Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanSatisfy@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "satisfaction": {
      "status": "satisfied",
      "id": "LN-34b5017c",
      "lien": {
        "standing": "release-initiated",
        "lienholder": {
          "fsId": "F00SET",
          "name": "Southeast Toyota Finance"
        }
      }
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "satisfaction": {
      "status": "satisfied",
      "id": "LN-34b5017c",
      "lien": {
        "standing": "release-initiated",
        "lienholder": {
          "fsId": "F00SET",
          "name": "Southeast Toyota Finance"
        }
      }
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

statement

loan.statement · GET /loans/statement · gate key · sandbox · answers LoanStatement@1

FieldTypeRequiredNotes
vinstringno

Dooraggregator.vin serves this noun on its two routes: / (the landing) · /1C4RJFBG3LC288648 (the VIN lens).

Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.

the SDK — loan.statement
import { loan } from 'apis.vin'

// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.statement({"vin":"1C4RJFBG3LC288648"})
GET /loans/statement
curl 'https://apis.vin/loans/statement?vin=1C4RJFBG3LC288648'

Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.

receipt · executed 2026-08-17T12:42:13.820Z · HTTP 200
{
  "type": "OK",
  "answers": "LoanStatement@1",
  "value": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "statement": {
      "id": "ST-82da2407",
      "loanId": "LN-34b5017c",
      "balance": {
        "currency": "USD",
        "minorUnits": 2462421
      },
      "nextPayment": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "nextPaymentDate": "2026-08-25T00:00:00.000Z",
      "servicing": "Current"
    }
  },
  "evidence": {
    "vin": "1C4RJFBG3LC288648",
    "noun": "loan",
    "asOf": "2026-08-10",
    "statement": {
      "id": "ST-82da2407",
      "loanId": "LN-34b5017c",
      "balance": {
        "currency": "USD",
        "minorUnits": 2462421
      },
      "nextPayment": {
        "currency": "USD",
        "minorUnits": 48006
      },
      "nextPaymentDate": "2026-08-25T00:00:00.000Z",
      "servicing": "Current"
    }
  },
  "provenance": {
    "simulated": true,
    "environment": "sandbox",
    "source": "risk-money-sandbox"
  },
  "events": [],
  "meter": {
    "charged": "0.00",
    "posted": false
  }
}

Data model

The record shape behind this noun — one entity, each property an evidence field. See the whole estate model on the data model page.

Loan

Schema

PropertyTypeNotes
idid
lenderIdref→Lender
principalmoney
aprdecimal
termint
statusLoanFSMcontracts-in-transit|funded|serviced

Relationships

FromToCardinalityAs
dealloan1:0..1funds
loanlender*:1held-by

Modeled

The noun drawn out — its record shape, its lifecycle, and how it is exercised end to end. 3 diagrams, rendered from the estate model.

Loan · Class model

Loan · State machine

Loan · Sequence


Generated from the catalog. Every capability, answer, gate, and entity on this page is a rendered descriptor — it cannot drift from the wire.