Rulesets
Rulesets define how Banklyze computes underwriting scores and recommendations. Each ruleset specifies the weight assigned to each of the 9 scoring factors, the minimum scores required for each letter grade, the approval threshold score, the maximum advance size as a fraction of average monthly deposits, and the target Cash Flow Coverage Ratio (CFCR).
Every organization has exactly one default ruleset used when generating underwriting recommendations via the deal report and GET /deals/{deal_id}/recommendation endpoint. Additional rulesets can be created for scenario analysis and evaluated on demand via POST /deals/{deal_id}/evaluate. The 9 factor weights in a ruleset must sum to exactly 100 — the API rejects rulesets where the weights do not sum to 100.
Weight Fields
The following 9 fields define the percentage weight assigned to each scoring factor. All values are integers and must sum to exactly 100.
| Name | Type | Required | Description |
|---|---|---|---|
| weight_revenue | integer | Required | Weight for the Revenue factor — scores average monthly deposit volume relative to the requested advance amount |
| weight_balance_health | integer | Required | Weight for the Balance Health factor — scores average daily balance, ending balance, and low-balance frequency |
| weight_nsf_overdraft | integer | Required | Weight for the NSF & Overdraft factor — scores the frequency and recency of NSF and overdraft fee occurrences |
| weight_deposit_frequency | integer | Required | Weight for the Deposit Frequency factor — scores how consistently deposits arrive throughout the month |
| weight_revenue_trend | integer | Required | Weight for the Revenue Trend factor — scores whether month-over-month deposit volumes are growing, stable, or declining |
| weight_debt_service | integer | Required | Weight for the Debt Service factor — scores estimated debt service capacity based on the ratio of recurring debits to deposits |
| weight_transaction_screening | integer | Required | Weight for the Transaction Screening factor — scores the number and severity of flagged transactions relative to total transaction count |
| weight_health_score | integer | Required | Weight for the composite Health Score factor — incorporates the 6-factor health score as a holistic signal |
| weight_cross_doc | integer | Required | Weight for the Cross-Document Validation factor — scores consistency between multiple bank statements covering overlapping periods |
Retrieve all rulesets configured for your organization. The default ruleset is indicated by is_default: true. Results are ordered by created_at ascending.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | Default: 1 | Page number (1-indexed) |
| per_page | integer | Default: 25 | Results per page (max 100) |
Example
curl -X GET https://api.banklyze.com/v1/rulesets \
-H "X-API-Key: your_api_key_here"Response
{
"data": [
{
"id": 1,
"name": "Default MCA",
"description": "Standard MCA underwriting weights used across all deal types.",
"is_default": true,
"weight_revenue": 15,
"weight_balance_health": 15,
"weight_nsf_overdraft": 15,
"weight_deposit_frequency": 10,
"weight_revenue_trend": 10,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 10,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 70,
"max_advance_multiplier": 0.30,
"cfcr_target": 1.25,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
},
{
"id": 2,
"name": "Conservative",
"description": "Higher bar for approval — used for large advance requests above $100K.",
"is_default": false,
"weight_revenue": 20,
"weight_balance_health": 20,
"weight_nsf_overdraft": 15,
"weight_deposit_frequency": 10,
"weight_revenue_trend": 10,
"weight_debt_service": 10,
"weight_transaction_screening": 5,
"weight_health_score": 5,
"weight_cross_doc": 5,
"grade_a_min": 90,
"grade_b_min": 78,
"grade_c_min": 62,
"grade_d_min": 50,
"approve_threshold": 78,
"max_advance_multiplier": 0.25,
"cfcr_target": 1.40,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-02-01T09:30:00Z"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 2,
"total_pages": 1
}
}Create a new underwriting ruleset. All 9 weight fields are required and must sum to exactly 100. Grade threshold fields (grade_a_min, grade_b_min, grade_c_min, grade_d_min) define the minimum score required to achieve each letter grade. Newly created rulesets are not set as default — use POST /rulesets/{ruleset_id}/set-default to promote one.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | Display name for the ruleset (max 200 characters) |
| description | string | Optional | Optional description explaining the intended use of this ruleset (max 1,000 characters) |
| weight_revenue | integer | Required | Weight for the Revenue factor (0–100) |
| weight_balance_health | integer | Required | Weight for the Balance Health factor (0–100) |
| weight_nsf_overdraft | integer | Required | Weight for the NSF & Overdraft factor (0–100) |
| weight_deposit_frequency | integer | Required | Weight for the Deposit Frequency factor (0–100) |
| weight_revenue_trend | integer | Required | Weight for the Revenue Trend factor (0–100) |
| weight_debt_service | integer | Required | Weight for the Debt Service factor (0–100) |
| weight_transaction_screening | integer | Required | Weight for the Transaction Screening factor (0–100) |
| weight_health_score | integer | Required | Weight for the composite Health Score factor (0–100) |
| weight_cross_doc | integer | Required | Weight for the Cross-Document Validation factor (0–100). All 9 weights must sum to exactly 100. |
| grade_a_min | integer | Required | Minimum weighted score (0–100) required to receive a Grade A |
| grade_b_min | integer | Required | Minimum weighted score (0–100) required to receive a Grade B |
| grade_c_min | integer | Required | Minimum weighted score (0–100) required to receive a Grade C |
| grade_d_min | integer | Required | Minimum weighted score (0–100) required to receive a Grade D. Scores below this threshold receive Grade F. |
| approve_threshold | integer | Required | Minimum weighted score required for an automatic approve recommendation. Deals below this score receive a decline recommendation. |
| max_advance_multiplier | number | Required | Maximum advance size expressed as a fraction of average monthly deposits (e.g. 0.30 = up to 30% of avg monthly deposits) |
| cfcr_target | number | Required | Target Cash Flow Coverage Ratio. The recommendation will note when the computed CFCR falls below this target. |
Example
curl -X POST https://api.banklyze.com/v1/rulesets \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Restaurant Vertical",
"description": "Adjusted weights for food and beverage merchants with seasonal revenue patterns.",
"weight_revenue": 18,
"weight_balance_health": 12,
"weight_nsf_overdraft": 12,
"weight_deposit_frequency": 12,
"weight_revenue_trend": 12,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 9,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 68,
"max_advance_multiplier": 0.28,
"cfcr_target": 1.30
}'Response
{
"id": 3,
"name": "Restaurant Vertical",
"description": "Adjusted weights for food and beverage merchants with seasonal revenue patterns.",
"is_default": false,
"weight_revenue": 18,
"weight_balance_health": 12,
"weight_nsf_overdraft": 12,
"weight_deposit_frequency": 12,
"weight_revenue_trend": 12,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 9,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 68,
"max_advance_multiplier": 0.28,
"cfcr_target": 1.30,
"created_at": "2026-03-04T11:00:00Z",
"updated_at": "2026-03-04T11:00:00Z"
}Retrieve a single ruleset by ID with all weight fields, grade thresholds, and scoring parameters.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ruleset_id | integer | Required | The unique ruleset ID |
Example
curl -X GET https://api.banklyze.com/v1/rulesets/3 \
-H "X-API-Key: your_api_key_here"Response
{
"id": 3,
"name": "Restaurant Vertical",
"description": "Adjusted weights for food and beverage merchants with seasonal revenue patterns.",
"is_default": false,
"weight_revenue": 18,
"weight_balance_health": 12,
"weight_nsf_overdraft": 12,
"weight_deposit_frequency": 12,
"weight_revenue_trend": 12,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 9,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 68,
"max_advance_multiplier": 0.28,
"cfcr_target": 1.30,
"created_at": "2026-03-04T11:00:00Z",
"updated_at": "2026-03-04T11:00:00Z"
}Fully replace a ruleset. All fields from the create request body are required. The updated weights must still sum to exactly 100. Updating a ruleset does not retroactively change existing underwriting recommendations — each recommendation stores a snapshot of the ruleset weights at the time it was generated.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ruleset_id | integer | Required | The unique ruleset ID |
Example
curl -X PUT https://api.banklyze.com/v1/rulesets/3 \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Restaurant Vertical",
"description": "Adjusted weights for food and beverage merchants with seasonal revenue patterns.",
"weight_revenue": 20,
"weight_balance_health": 12,
"weight_nsf_overdraft": 10,
"weight_deposit_frequency": 12,
"weight_revenue_trend": 12,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 9,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 68,
"max_advance_multiplier": 0.28,
"cfcr_target": 1.30
}'Response
{
"id": 3,
"name": "Restaurant Vertical",
"description": "Adjusted weights for food and beverage merchants with seasonal revenue patterns.",
"is_default": false,
"weight_revenue": 20,
"weight_balance_health": 12,
"weight_nsf_overdraft": 10,
"weight_deposit_frequency": 12,
"weight_revenue_trend": 12,
"weight_debt_service": 10,
"weight_transaction_screening": 10,
"weight_health_score": 9,
"weight_cross_doc": 5,
"grade_a_min": 85,
"grade_b_min": 70,
"grade_c_min": 55,
"grade_d_min": 40,
"approve_threshold": 68,
"max_advance_multiplier": 0.28,
"cfcr_target": 1.30,
"created_at": "2026-03-04T11:00:00Z",
"updated_at": "2026-03-04T11:45:00Z"
}Delete a ruleset. The default ruleset cannot be deleted — attempting to delete it returns 409 Conflict. Promote a different ruleset to default first with POST /rulesets/{ruleset_id}/set-default, then delete the original. Deleting a ruleset does not affect existing recommendations that were generated using it — the weight snapshot is preserved on the recommendation record.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ruleset_id | integer | Required | The unique ruleset ID. Must not be the current default. |
Example
curl -X DELETE https://api.banklyze.com/v1/rulesets/3 \
-H "X-API-Key: your_api_key_here"Response
{
"status": "ok",
"message": "Ruleset deleted successfully"
}Promote a ruleset to be the organization default. The previous default ruleset is automatically demoted. The new default is used immediately for all subsequent underwriting recommendation generation. Existing cached recommendations are not affected.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ruleset_id | integer | Required | The unique ruleset ID to promote to default |
Example
curl -X POST https://api.banklyze.com/v1/rulesets/2/set-default \
-H "X-API-Key: your_api_key_here"Response
{
"id": 2,
"name": "Conservative",
"is_default": true,
"updated_at": "2026-03-04T12:00:00Z"
}