How to Integrate Next.js for lending with Vercel AI SDK for production AI

By Cyprian AaronsUpdated 2026-04-21
next-js-for-lendingvercel-ai-sdkproduction-ainextjs-for-lending

Combining Next.js for lending with Vercel AI SDK gives you a clean path from borrower-facing UI to production AI orchestration. In practice, that means you can embed underwriting assistants, document Q&A, and loan status copilots directly into your lending workflows without building a separate agent platform from scratch.

The useful part is the split of responsibilities: Next.js handles the web app and API routes, while Vercel AI SDK handles model streaming, tool calling, and structured responses. That keeps your lending product fast to ship and easier to operate under real production constraints.

Prerequisites

  • Python 3.10+
  • Node.js 18+ for the Next.js app
  • A running Next.js for lending project with API routes enabled
  • A Vercel account with an AI SDK-enabled project
  • OPENAI_API_KEY or another supported model provider key
  • pip install requests pydantic
  • A basic lending backend endpoint for:
    • applicant lookup
    • loan decision retrieval
    • document status checks

Integration Steps

  1. Expose your lending workflow through a Next.js API route

    In a production setup, your lending app should expose stable endpoints that the AI layer can call. Keep them narrow: one endpoint for applicant data, one for loan status, one for document verification.

    import requests
    
    NEXTJS_BASE_URL = "https://your-nextjs-lending-app.vercel.app"
    
    def get_applicant_profile(applicant_id: str) -> dict:
        response = requests.get(
            f"{NEXTJS_BASE_URL}/api/applicants/{applicant_id}",
            timeout=10,
        )
        response.raise_for_status()
        return response.json()
    
    def get_loan_status(loan_id: str) -> dict:
        response = requests.get(
            f"{NEXTJS_BASE_URL}/api/loans/{loan_id}/status",
            timeout=10,
        )
        response.raise_for_status()
        return response.json()
    
  2. Create a Vercel AI SDK route that calls your lending APIs as tools

    The Vercel AI SDK supports tool calling through generateText and streamText. In this pattern, the model decides when to fetch borrower data from your Next.js backend.

    import os
    import json
    import requests
    
    VERCEL_AI_ENDPOINT = "https://your-vercel-ai-route.vercel.app/api/chat"
    OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
    
    def ask_lending_agent(message: str, applicant_id: str) -> dict:
        payload = {
            "message": message,
            "context": {
                "applicantId": applicant_id,
            },
        }
    
        response = requests.post(
            VERCEL_AI_ENDPOINT,
            headers={
                "Authorization": f"Bearer {OPENAI_API_KEY}",
                "Content-Type": "application/json",
            },
            data=json.dumps(payload),
            timeout=30,
        )
        response.raise_for_status()
        return response.json()
    
  3. Wire tool execution to Next.js lending APIs

    Your agent should not guess on financial facts. It should call your lending system of record through explicit tools, then feed the result back into the model.

    import requests
    
    NEXTJS_BASE_URL = "https://your-nextjs-lending-app.vercel.app"
    
    def fetch_underwriting_data(applicant_id: str) -> dict:
        profile = requests.get(
            f"{NEXTJS_BASE_URL}/api/applicants/{applicant_id}",
            timeout=10,
        ).json()
    
        credit = requests.get(
            f"{NEXTJS_BASE_URL}/api/applicants/{applicant_id}/credit",
            timeout=10,
        ).json()
    
        documents = requests.get(
            f"{NEXTJS_BASE_URL}/api/applicants/{applicant_id}/documents",
            timeout=10,
        ).json()
    
        return {
            "profile": profile,
            "credit": credit,
            "documents": documents,
        }
    
  4. Use structured outputs for loan decisions

    For production AI in lending, plain text is not enough. Use structured JSON output so downstream systems can validate fields like decision, reasons, and required conditions.

    from pydantic import BaseModel, Field
    from typing import List, Literal
    
    class LoanDecision(BaseModel):
        decision: Literal["approve", "decline", "review"]
        risk_band: Literal["low", "medium", "high"]
        reasons: List[str] = Field(default_factory=list)
        next_action: str
    
    def normalize_decision(raw: dict) -> LoanDecision:
        return LoanDecision.model_validate(raw)
    
    sample_raw = {
        "decision": "review",
        "risk_band": "medium",
        "reasons": [
            "Income verification incomplete",
            "Debt-to-income ratio above target"
        ],
        "next_action": "Request latest payslips and rerun underwriting"
    }
    
    decision = normalize_decision(sample_raw)
    print(decision.model_dump())
    
  5. Stream responses back to the borrower portal

    Vercel AI SDK’s streamText is useful when you want progressive rendering in the UI. For example, a borrower asking “Why is my application pending?” should see an immediate answer instead of waiting for a full backend round trip.

    import time
    
    def stream_lending_explanation(applicant_data: dict) -> None:
      chunks = [
          f"Application status: {applicant_data['profile']['status']}\n",
          f"Credit band: {applicant_data['credit']['band']}\n",
          f"Missing documents: {', '.join(applicant_data['documents']['missing'])}\n",
      ]
    
      for chunk in chunks:
          print(chunk, end="", flush=True)
          time.sleep(0.5)
    

Testing the Integration

Use a known applicant ID and verify that the agent can retrieve data from Next.js and return a structured result through your Vercel AI layer.

def test_integration():
    applicant_id = "app_12345"

    underwriting_data = fetch_underwriting_data(applicant_id)
    print("Fetched:", underwriting_data["profile"]["name"])

    result = ask_lending_agent(
        message="Summarize why this application is pending and what we need next.",
        applicant_id=applicant_id,
    )

    print("Agent response:", result)

if __name__ == "__main__":
    test_integration()

Expected output:

Fetched: Jane Doe
Agent response: {
  "decision": "review",
  "risk_band": "medium",
  "reasons": [
    "Income verification incomplete",
    "One required document is missing"
  ],
  "next_action": "Request bank statements and latest payslips"
}

Real-World Use Cases

  • Borrower support copilot

    • Answer application-status questions using live data from your Next.js lending backend.
    • Reduce manual support tickets without exposing raw internal systems.
  • Underwriting assistant

    • Pull applicant profile, credit metadata, and document completeness into a structured AI review.
    • Route borderline cases to human underwriters with clear reasons attached.
  • Collections or servicing agent

    • Generate compliant payment reminders based on account state.
    • Surface next-best actions like repayment plan offers or document follow-ups.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides