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.
ClaudeOpenAI CodexCursorVS 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 appClient appWeb · mobile · agentauthentication APIauthentication APIauth/loginauth/meauth/signuploan_origination APIloan_origination APIapplicationsapplications/{application_id...applications/{application_id...demo/runseedwebhooks/bureauwebhooks/kycBusiness logicBusiness logicWrite audit logCheck roleIssue glba noticeDerive internal signalsRun decisioningRun demo scenarioCall credit bureau+2 moreDataDataapplicantapplicationaudit_logdecisionnotification_logrisk_tieruserwebhook_eventExternal servicesExternal 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

Does this template handle FCRA compliance?
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