Overview
The lender search workflow is two-step:
- Trigger a search (
POST) — initiates the AI matching process for a deal - Get results (
GET) — retrieves the ranked results once the search is complete
If a recent search already exists for the deal, the trigger endpoint returns cached results immediately.
Workflow Shape
Use lender search as a workflow, not just an endpoint:
- Read the deal and any available financial context.
- Trigger or reuse lender search for that deal.
- Summarize the ranked result set with the deal context that likely drove the ranking.
- Hand the shortlist to a human or the next workflow step, such as placement creation or term-sheet review.
Trigger Search
/api/external/v2/deals/{deal_id}/actions/search-lendersTrigger an AI-powered lender search for a deal
The request body should be an empty JSON object {}.
Response (200):
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"search_id": "abc123",
"status": "completed",
"deal_id": 101,
"message": "Search completed with 25 results"
}
}| Status | Meaning |
|---|---|
completed | Results are ready |
pending | Search is queued — poll the GET endpoint |
running | Search is actively processing — poll the GET endpoint |
partial | Some results are available but ranking is still in progress |
failed | Search failed |
unauthorizedAuthentication required— Missing or invalid Authorization header
not_foundDeal not found— The deal_id doesn't exist or isn't accessible to the authenticated user
Get Results
/api/external/v2/deals/{deal_id}/build/lender-searchGet lender search results for a deal
Response (200):
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"search_id": "abc123",
"status": "completed",
"deal_id": 101,
"results": [
{
"org_id": 500,
"organization_name": "First National Bank",
"ai_score": 92,
"ai_rank_status": "completed",
"ai_match_insights": "Strong fit based on asset type and geography",
"is_connected_lender": true,
"programs": [
{
"id": 10,
"title": "CRE Bridge Lending",
"loan_types": ["bridge"],
"capital_source_type": "balance_sheet",
"min_loan_amount": 1000000,
"max_loan_amount": 50000000,
"asset_types": ["multifamily", "office"],
"states": ["NY", "NJ", "CT"]
}
]
}
],
"pagination": {
"total": 25,
"limit": 50,
"offset": 0,
"has_more": false
}
}
}Each result in the results array contains:
| Field | Type | Description |
|---|---|---|
org_id | integer|null | Organization ID |
organization_name | string|null | Lender name |
ai_score | integer|null | AI match score |
ai_rank_status | string|null | AI ranking process status for this result (pending, running, completed, failed, partial) |
ai_match_insights | string|null | AI-generated match reasoning |
is_connected_lender | boolean|null | Whether the lender is in your CRM |
programs | array|null | Matching lending programs |
Each program in the programs array contains:
| Field | Type | Description |
|---|---|---|
id | integer | Program ID |
title | string|null | Program name |
loan_types | string[]|null | Supported loan types |
capital_source_type | string|null | Capital source type |
min_loan_amount | number|null | Minimum loan amount |
max_loan_amount | number|null | Maximum loan amount |
asset_types | string[]|null | Supported asset types |
states | string[]|null | Geographic coverage |
Returns 404 if no search has been run for this deal.
unauthorizedAuthentication required— Missing or invalid Authorization header
not_foundDeal not found— The deal_id doesn't exist or no search has been run for this deal
Implementation Notes
- Trigger first, then poll with intention. Do not create aggressive retry loops.
- Cache the latest
search_idand status in your own workflow state when you are orchestrating multiple steps. - Treat lender search as recommendation input. Keep the final outreach and placement decisions reviewable by a human.