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
| Noun | loan |
| Pillar | Services (facets: 6 data · 9 services · 4 commerce) |
| Capabilities | 19 — 0 live · 19 sandbox · 0 declared |
| Entities | Loan |
| Doors | aggregator.vin |
| SDK | Vin.loan.* from apis.vin |
| Address | /catalog/loan#{action} — the anchor IS the wire name minus loan. |
Lifecycle
Loan — LoanFSM: 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:
Loan.assigned@1— emitted byassignLoan.autopayEnrolled@1— emitted byautopayLoan.chargedOff@1— emitted bychargeoffLoan.contracted@1— emitted bycontractLoan.disclosed@1— emitted bydiscloseLoan.failed@1— emitted byautopay·fund·late·payLoan.funded@1— emitted byfundLoan.lateAssessed@1— emitted bylateLoan.modified@1— emitted bymodifyLoan.originated@1— emitted byoriginateLoan.paid@1— emitted bypayLoan.paymentReminded@1— emitted bypaymentRemindLoan.reaged@1— emitted byreageLoan.satisfied@1— emitted bysatisfy
Discover & read
status
loan.status · GET /loans/status · gate none · sandbox · answers LoanStatus@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.assigned@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.originated@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.failed@1 · Loan.paid@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.failed@1 · Loan.funded@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.autopayEnrolled@1 · Loan.failed@1.
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"})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.
{
"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.
Door — aggregator.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.
Emits — Loan.paymentReminded@1.
import { loan } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await loan.paymentRemind()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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.disclosed@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.chargedOff@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.contracted@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.failed@1 · Loan.lateAssessed@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.modified@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.reaged@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
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.
Door — aggregator.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.
Emits — Loan.satisfied@1.
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"})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.
{
"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
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.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.
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"})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.
{
"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
| Property | Type | Notes |
|---|---|---|
id | id | — |
lenderId | ref→Lender | — |
principal | money | — |
apr | decimal | — |
term | int | — |
status | LoanFSM | contracts-in-transit|funded|serviced |
Relationships
| From | To | Cardinality | As |
|---|---|---|---|
deal | loan | 1:0..1 | funds |
loan | lender | *:1 | held-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.