BanklyzeBanklyze/Developer Docs
Sign In

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.

NameTypeRequiredDescription
weight_revenueintegerRequiredWeight for the Revenue factor — scores average monthly deposit volume relative to the requested advance amount
weight_balance_healthintegerRequiredWeight for the Balance Health factor — scores average daily balance, ending balance, and low-balance frequency
weight_nsf_overdraftintegerRequiredWeight for the NSF & Overdraft factor — scores the frequency and recency of NSF and overdraft fee occurrences
weight_deposit_frequencyintegerRequiredWeight for the Deposit Frequency factor — scores how consistently deposits arrive throughout the month
weight_revenue_trendintegerRequiredWeight for the Revenue Trend factor — scores whether month-over-month deposit volumes are growing, stable, or declining
weight_debt_serviceintegerRequiredWeight for the Debt Service factor — scores estimated debt service capacity based on the ratio of recurring debits to deposits
weight_transaction_screeningintegerRequiredWeight for the Transaction Screening factor — scores the number and severity of flagged transactions relative to total transaction count
weight_health_scoreintegerRequiredWeight for the composite Health Score factor — incorporates the 6-factor health score as a holistic signal
weight_cross_docintegerRequiredWeight 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

NameTypeRequiredDescription
pageintegerDefault: 1Page number (1-indexed)
per_pageintegerDefault: 25Results per page (max 100)

Example

curl
curl -X GET https://api.banklyze.com/v1/rulesets \
  -H "X-API-Key: your_api_key_here"

Response

Response — 200 OK
{
  "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

NameTypeRequiredDescription
namestringRequiredDisplay name for the ruleset (max 200 characters)
descriptionstringOptionalOptional description explaining the intended use of this ruleset (max 1,000 characters)
weight_revenueintegerRequiredWeight for the Revenue factor (0–100)
weight_balance_healthintegerRequiredWeight for the Balance Health factor (0–100)
weight_nsf_overdraftintegerRequiredWeight for the NSF & Overdraft factor (0–100)
weight_deposit_frequencyintegerRequiredWeight for the Deposit Frequency factor (0–100)
weight_revenue_trendintegerRequiredWeight for the Revenue Trend factor (0–100)
weight_debt_serviceintegerRequiredWeight for the Debt Service factor (0–100)
weight_transaction_screeningintegerRequiredWeight for the Transaction Screening factor (0–100)
weight_health_scoreintegerRequiredWeight for the composite Health Score factor (0–100)
weight_cross_docintegerRequiredWeight for the Cross-Document Validation factor (0–100). All 9 weights must sum to exactly 100.
grade_a_minintegerRequiredMinimum weighted score (0–100) required to receive a Grade A
grade_b_minintegerRequiredMinimum weighted score (0–100) required to receive a Grade B
grade_c_minintegerRequiredMinimum weighted score (0–100) required to receive a Grade C
grade_d_minintegerRequiredMinimum weighted score (0–100) required to receive a Grade D. Scores below this threshold receive Grade F.
approve_thresholdintegerRequiredMinimum weighted score required for an automatic approve recommendation. Deals below this score receive a decline recommendation.
max_advance_multipliernumberRequiredMaximum advance size expressed as a fraction of average monthly deposits (e.g. 0.30 = up to 30% of avg monthly deposits)
cfcr_targetnumberRequiredTarget Cash Flow Coverage Ratio. The recommendation will note when the computed CFCR falls below this target.

Example

curl
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

Response — 201 Created
{
  "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

NameTypeRequiredDescription
ruleset_idintegerRequiredThe unique ruleset ID

Example

curl
curl -X GET https://api.banklyze.com/v1/rulesets/3 \
  -H "X-API-Key: your_api_key_here"

Response

Response — 200 OK
{
  "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

NameTypeRequiredDescription
ruleset_idintegerRequiredThe unique ruleset ID

Example

curl
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

Response — 200 OK
{
  "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

NameTypeRequiredDescription
ruleset_idintegerRequiredThe unique ruleset ID. Must not be the current default.

Example

curl
curl -X DELETE https://api.banklyze.com/v1/rulesets/3 \
  -H "X-API-Key: your_api_key_here"

Response

Response — 200 OK
{
  "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

NameTypeRequiredDescription
ruleset_idintegerRequiredThe unique ruleset ID to promote to default

Example

curl
curl -X POST https://api.banklyze.com/v1/rulesets/2/set-default \
  -H "X-API-Key: your_api_key_here"

Response

Response — 200 OK
{
  "id": 2,
  "name": "Conservative",
  "is_default": true,
  "updated_at": "2026-03-04T12:00:00Z"
}