Loan Origination Engine
All templates

Loan Origination Engine

Everything you need to intake loan applications, verify identity, pull credit from Experian and Equifax, analyze cash flow via Plaid, and auto-decide — with FCRA, GLBA, and KYC compliance built in.

Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with loan-origination-engine as your template.
Claude OpenAI Codex Cursor VS Code

Copy and paste the prompt in your local coding agent of choice.

Template Details

8 Tables 12 APIs 13 Functions 3 Middleware 1 Tasks

Integrations

Experian Equifax Alloy Persona Plaid Twilio SendGrid
Template Preview
Client app Client app Web · mobile · agent authentication API authentication API auth/login auth/me auth/signup loan_origination API loan_origination API applications applications/{application_id... applications/{application_id... demo/run seed webhooks/bureau webhooks/kyc Business logic Business logic Write audit log Check role Issue glba notice Derive internal signals Run decisioning Run demo scenario Call credit bureau +2 more Data Data applicant application audit_log decision notification_log risk_tier user webhook_event External services External services Experian Equifax Alloy Persona Plaid Twilio SendGrid

Overview

A self-contained Xano template for a consumer-loan origination backend: an applicant applies, the engine scores them and runs a configurable risk-tier waterfall, and produces an auditable approve / conditionally-approve / refer / deny decision with ECOA adverse-action tracking. The whole submit → decision → status flow runs end-to-end on the seed data this repo ships, with no third-party credentials; real bureau, KYC, cash-flow, and notification providers are optional enrichment.

What it provides

Consumer lending has two hard parts a demo usually skips: making a consistent credit decision, and being able to defend it afterward. Hand-coded approval logic drifts between loan officers, and when a regulator asks why an applicant was denied, "the system said no" isn't an answer — ECOA requires a specific adverse-action reason on the record. This template is a working decision engine that does both: a deterministic score feeds a configurable risk-tier waterfall to produce the outcome, every state change is written to an audit log, and every denial carries an ECOA adverse-action id and timestamp. It runs end-to-end on the shipped seed with no credentials, so you can trace the whole decision path before wiring in a real bureau.

Repo layout

backend/
  api/
    authentication/
      auth/
        login_POST.xs
        me_GET.xs
        signup_POST.xs
      authentication.xs
    loan_origination/
      api_group.xs
      applications_post.xs
      applications_status_get.xs
      applications_submit_post.xs
      demo_run_post.xs
      seed_post.xs
      webhooks_bureau_post.xs
      webhooks_kyc_post.xs
  function/
    audit/
      write_audit_log.xs
    auth/
      check_role.xs
    compliance/
      issue_glba_notice.xs
    decisioning/
      derive_internal_signals.xs
      run_decisioning.xs
      run_demo_scenario.xs
    external/
      call_credit_bureau.xs
      call_kyc.xs
      call_plaid.xs
    notifications/
      send_notification.xs
    pii/
      redact_applicant.xs
    validation/
      check_duplicate_applicant.xs
      check_prior_decisions.xs
  middleware/
    audit_trail.xs
    pii_redaction.xs
    role_guard.xs
  table/
    applicant.xs
    application.xs
    audit_log.xs
    decision.xs
    notification_log.xs
    risk_tier.xs
    user.xs
    webhook_event.xs
  task/
    expire_stale_applications.xs
  workflow_test/
    kyc_review_referred.xs
    low_score_denied.xs
    prime_auto_approved.xs
    subprime_conditional.xs
  workspace/
    production_2.xs

How it works

  1. Scoring (function/decisioning/derive_internal_signals) — a deterministic, credential-free score (300–850) from income, debt-to-income, and loan-to-income. A demo heuristic, not a real bureau; a pure function, so it's fully unit-tested.
  2. Waterfall (function/decisioning/run_decisioning) — evaluates score, DTI, loan amount, and KYC status against active risk_tier rows in priority order, picks the first eligible tier, and maps it to an outcome. Denials record an ECOA adverse-action reason.

Four outcomes, driven entirely by the seeded risk_tier rows: approved (auto-decision tier, KYC passing), conditionally_approved (tier not auto-decision-eligible), referred (tier matched, KYC needs review), denied (no tier matched; ECOA reason recorded). Because tiers live in the table, not code, you retune thresholds, rates, and eligibility by editing data — no redeploy.

Quick start

Start with your coding agent. Paste the prompt below into a local MCP-capable coding agent — Claude Code, Cursor, Windsurf, and others. It installs the Xano CLI, connects Xano, and imports this template.

Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with loan-origination-engine as your template.

The agent will walk you through the setup below.

  1. Create a Xano workspace and push backend/:
xano workspace push -w <your-workspace-id> -d backend --force
  1. Load the demo tiers + users (see Seed data).
  2. Open the frontend, or drive it by API (below).

The whole flow runs credential-free on the seed. Demo logins (password Demo1234): broker@demo.test, underwriter@demo.test, applicant@demo.test.

API surface

Auth — api:<auth-group>: POST /auth/signup · POST /auth/login · GET /auth/me

Loan origination — api:loan-origination:

POST /applications                            create a draft application
POST /applications/{application_id}/submit    score + decision (accepts credit_score / kyc_status overrides)
GET  /applications/{application_id}/status     application + decision + PII-masked applicant
POST /demo/run                                 no-auth scenario runner
POST /webhooks/bureau                          feed a real credit-bureau result
POST /webhooks/kyc                             feed a real KYC result

Database Tables

  • user — auth (roles: broker · underwriter · applicant)
  • applicant — identity + financials; PII redacted on read
  • application — the loan request + its lifecycle state
  • risk_tier — the configurable waterfall rules (thresholds, rates, eligibility)
  • decision — the outcome + ECOA adverse-action id/timestamp
  • audit_log — append-only record of every state change
  • notification_log — dispatched notifications
  • webhook_event — inbound provider callbacks

Testing

  • Unit tests (embedded in derive_internal_signals) — verify the scoring bands. xano unit_test run_all -w <id>
  • Workflow tests (backend/workflow_test/) — drive the full decisioning path end-to-end for each of the four outcomes. xano workflow_test run_all -w <id>

Every .xs validates against the XanoScript language server.

Environment variables

The credential-free scorer is the default. To use real providers, set the relevant workspace env vars; results feed in through the webhook endpoints (which overwrite the derived score/KYC before decisioning). All external calls are wrapped, so missing credentials never break the flow.

Experian / Equifax     EXPERIAN_API_URL/KEY, EQUIFAX_API_URL/KEY   → POST /webhooks/bureau
Alloy / Persona (KYC)  ALLOY_API_URL/KEY/SECRET, PERSONA_API_URL/KEY → POST /webhooks/kyc
Plaid (cash flow)      PLAID_BASE_URL, PLAID_CLIENT_ID, PLAID_SECRET → submit with plaid_access_token
Twilio / SendGrid      TWILIO_*, SENDGRID_*                          → sent on decision

Frequently asked questions

It’s built with FCRA-style adverse-action handling in mind: every decision is written to an immutable audit trail you can use to generate adverse-action notices. The template runs self-contained on seed data — wiring real bureau data and issuing formal disclosures is up to you when you connect live providers.
Out of the box it runs self-contained — the credit score is a deterministic demo heuristic derived from income, debt-to-income, and loan-to-income, not a live bureau pull. It’s structured so you can wire a real bureau such as Experian or Equifax through the provided enrichment/webhook points to replace the heuristic.
Yes. Risk tiers — thresholds, rates, maximum loan amount, and auto-decision eligibility — live as rows in the `risk_tier` table. Edit the rows to change the lending rules; no code change or redeploy required.
KYC is an optional enrichment step. When a result is inconclusive, the application is held for manual review instead of being auto-approved, and the decision and its reason are recorded in the audit trail.
Every template runs on any Xano plan, including the free tier. All you need is a Xano account and a coding agent connected to the CLI and Developer MCP.
You can import and run it with your local coding agent — it works against the seed data it ships with. Paste this prompt into your agent: Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with loan-origination-engine as your template. You can also do a manual clone from Github, still using the Xano CLI and Developer MCP to connect to Xano to build and deploy.
Yes — that's the intent. The backend is plain XanoScript that you can read and AI can build on: add or edit tables, endpoints, and logic, or swap integrations. It ships with tests you can extend as you go.
Xano gives you an enterprise-grade backend — database, APIs, and logic — that AI can build and you can visually inspect, edit, and trust. Hosted, scalable, and production-ready from day one. Speed of generation, without the black box.

Get started for free today

Xano gives you everything you need to ship modern applications - fast, securely, and at scale.

Get started