How to Integrate CrewAI for lending with FastAPI for multi-agent systems

By Cyprian AaronsUpdated 2026-04-22
crewai-for-lendingfastapimulti-agent-systems

Combining CrewAI for lending with FastAPI gives you a clean way to expose multi-agent workflows as production APIs. That matters when you want loan origination, credit memo drafting, document review, and risk checks to run as separate agents behind one HTTP interface.

The pattern is simple: FastAPI handles request validation, auth, and response delivery, while CrewAI coordinates the lending agents. That gives you a service boundary you can put behind your bank’s API gateway without turning your agent logic into a monolith.

Prerequisites

  • Python 3.10+
  • fastapi
  • uvicorn
  • crewai
  • An LLM provider configured in your environment
  • A lending use case defined clearly:
    • loan pre-screening
    • document extraction
    • affordability analysis
    • risk summary generation
  • Basic familiarity with:
    • Pydantic models
    • REST APIs
    • async vs sync execution in FastAPI

Install the packages:

pip install fastapi uvicorn crewai pydantic

Set your model credentials before running anything:

export OPENAI_API_KEY="your-key"

Integration Steps

  1. Define the lending agents and tasks

Start by modeling the work as separate agents. In lending, that usually means one agent for intake, one for risk analysis, and one for compliance-style review.

from crewai import Agent, Task, Crew, Process

loan_intake_agent = Agent(
    role="Loan Intake Analyst",
    goal="Extract borrower details and summarize application data",
    backstory="You work on loan origination workflows and prepare clean application summaries.",
    verbose=True,
)

risk_agent = Agent(
    role="Credit Risk Analyst",
    goal="Assess lending risk from borrower data",
    backstory="You analyze income, debt load, and repayment signals for underwriting teams.",
    verbose=True,
)

intake_task = Task(
    description="Summarize this loan application: {application_data}",
    expected_output="A structured summary of borrower details and missing fields.",
    agent=loan_intake_agent,
)

risk_task = Task(
    description="Evaluate credit risk using the summarized application data.",
    expected_output="A risk assessment with key concerns and recommendation.",
    agent=risk_agent,
)
  1. Build the CrewAI workflow for lending

Now group those agents into a crew. For multi-agent systems, this is the orchestration layer that decides how tasks run together.

lending_crew = Crew(
    agents=[loan_intake_agent, risk_agent],
    tasks=[intake_task, risk_task],
    process=Process.sequential,
    verbose=True,
)

For lending workflows, Process.sequential is usually the right default because downstream analysis depends on upstream normalization. If you later split into parallel checks like KYC, fraud screening, and affordability scoring, you can reorganize the crew around those independent branches.

  1. Wrap the crew in a FastAPI service

Expose the workflow through an API endpoint. FastAPI gives you request validation with Pydantic and a stable contract for downstream consumers.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(title="Lending Multi-Agent API")

class LoanApplication(BaseModel):
    applicant_name: str
    income: float
    monthly_debt: float
    requested_amount: float
    employment_status: str

@app.post("/analyze-loan")
def analyze_loan(application: LoanApplication):
    result = lending_crew.kickoff(
        inputs={"application_data": application.model_dump()}
    )
    return {
        "status": "completed",
        "result": str(result),
    }

The key call here is lending_crew.kickoff(...). That is where CrewAI runs the task graph and returns the combined output from your agents.

  1. Add a proper service entrypoint

Run FastAPI with Uvicorn so it behaves like a normal production service. Keep this separate from your app code so deployment stays simple.

# main.py
from fastapi import FastAPI
from pydantic import BaseModel
from crewai import Agent, Task, Crew, Process

app = FastAPI()

class LoanApplication(BaseModel):
    applicant_name: str
    income: float
    monthly_debt: float
    requested_amount: float
    employment_status: str

loan_intake_agent = Agent(
    role="Loan Intake Analyst",
    goal="Extract borrower details and summarize application data",
)

risk_agent = Agent(
    role="Credit Risk Analyst",
    goal="Assess lending risk from borrower data",
)

intake_task = Task(
    description="Summarize this loan application: {application_data}",
    expected_output="Structured summary of borrower details.",
    agent=loan_intake_agent,
)

risk_task = Task(
    description="Evaluate credit risk using the summarized application data.",
    expected_output="Risk assessment and recommendation.",
    agent=risk_agent,
)

lending_crew = Crew(
    agents=[loan_intake_agent, risk_agent],
    tasks=[intake_task, risk_task],
)

@app.post("/analyze-loan")
def analyze_loan(application: LoanApplication):
    output = lending_crew.kickoff(
        inputs={"application_data": application.model_dump()}
    )
    

Then start it:

uvicorn main:app --reload --host 0.0.0.0 --port 8000
  1. Make the API response usable by downstream systems

Don’t return raw agent text if another system needs to consume it. In lending pipelines, you want structured output that can feed underwriting rules or case management.

@app.post("/analyze-loan")
def analyze_loan(application: LoanApplication):
    

A better production pattern is to ask each task for structured fields in its prompt and parse them into JSON before returning them through FastAPI. If you need strict schema enforcement, add a response model and validate the final result before sending it back.

Testing the Integration

Use curl or httpx to verify that FastAPI receives input and CrewAI returns an analysis.

import requests

payload = {
    "applicant_name": "Jane Doe",
    "income": 8500,
       "monthly_debt": 2100,
       "requested_amount": 25000,
       "employment_status": "full-time"
}

response = requests.post("http://localhost:8000/analyze-loan", json=payload)
print(response.status_code)
print(response.json())

Expected output will look like this:

{
  "status": "completed",
  "result": "..."
}

If everything is wired correctly:

  • FastAPI accepts the request body as JSON.
  • Pydantic validates the payload.
  • Crew.kickoff() executes the lending workflow.
  • The API returns a completed analysis response.

Real-World Use Cases

  • Loan pre-screening API

    • Accept applicant data from a portal.
    • Run intake, affordability checks, and basic policy validation through separate agents.
    • Return an approval recommendation or escalation flag.
  • Document-driven underwriting assistant

    • Send extracted fields from payslips, bank statements, and IDs into different agents.
    • Have one agent normalize documents while another summarizes underwriting risks.
    • Expose everything through one FastAPI endpoint for internal systems.
  • Collections or hardship triage

    • Route customer hardship requests to agents that classify severity, repayment options, and next actions.
    • Use FastAPI to integrate with CRM systems or case management tools.
    • Keep human review in the loop for edge cases.

The integration pattern stays stable across use cases. FastAPI owns transport and validation; CrewAI owns orchestration; your lending logic lives in tasks that are easy to test independently.


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