{
  "openapi": "3.1.0",
  "info": {
    "title": "LenderList Public API",
    "version": "1.2.0",
    "description": "Free registration for email-verified ISOs and brokers. The API provides explainable MCA lender discovery and deal matching with source freshness."
  },
  "servers": [{ "url": "https://lender-list.com", "description": "Production" }],
  "security": [{ "BearerAuth": [] }],
  "tags": [
    { "name": "System", "description": "Availability and index freshness" },
    { "name": "Lenders", "description": "Search and inspect public lender profiles" },
    { "name": "Matching", "description": "Compare deal facts with sourced lender criteria" }
  ],
  "paths": {
    "/api/v1/status": {
      "get": {
        "security": [],
        "tags": ["System"],
        "summary": "Get API and index status",
        "operationId": "getStatus",
        "responses": {
          "200": { "description": "Operational status and freshness", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StatusResponse" } } } },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/lenders": {
      "get": {
        "tags": ["Lenders"],
        "summary": "List and filter lenders",
        "operationId": "listLenders",
        "parameters": [
          { "name": "q", "in": "query", "description": "Search lender name, slug, website, or paper description", "schema": { "type": "string", "maxLength": 100 } },
          { "name": "scope", "in": "query", "description": "Search the complete lender index or only lenders saved by the authenticated ISO account", "schema": { "type": "string", "enum": ["all", "favorites"], "default": "all" } },
          { "name": "paper", "in": "query", "description": "Filter by MCA paper grade", "schema": { "type": "string", "enum": ["A", "B", "C", "D"] } },
          { "name": "criteriaOnly", "in": "query", "description": "Return only profiles with structured criteria", "schema": { "type": "boolean", "default": false } },
          { "name": "limit", "in": "query", "description": "Page size", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
          { "name": "cursor", "in": "query", "description": "Opaque cursor returned by the previous page", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "A cursor-paginated lender page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LenderListResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/lenders/{slug}": {
      "get": {
        "tags": ["Lenders"],
        "summary": "Get one lender profile",
        "operationId": "getLender",
        "parameters": [{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" }, "example": "mulligan-funding" }],
        "responses": {
          "200": { "description": "A complete public lender profile", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LenderDetailResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/matches": {
      "post": {
        "tags": ["Matching"],
        "summary": "Rank lenders for a deal",
        "description": "Matches supplied deal facts against sourced lender thresholds and restrictions. Missing facts remain unknown; no values are guessed.",
        "operationId": "matchDeal",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MatchRequest" } } } },
        "responses": {
          "200": { "description": "Ranked, explainable lender matches", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MatchResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "LenderList API key",
        "description": "Free key issued after creating an ISO account and verifying its email address."
      }
    },
    "responses": {
      "Unauthorized": { "description": "A valid API key was not supplied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "Forbidden": { "description": "The API account is not authorized for this request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "InvalidRequest": { "description": "The request could not be validated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "NotFound": { "description": "The lender profile was not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "RateLimited": { "description": "The free per-key request limit was reached", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
    },
    "schemas": {
      "Freshness": {
        "type": "object",
        "required": ["criteriaRefreshedAt", "source", "lendersIndexed", "criteriaProfiles"],
        "properties": {
          "criteriaRefreshedAt": { "type": ["string", "null"], "format": "date-time" },
          "discoveryRefreshedAt": { "type": ["string", "null"], "format": "date-time" },
          "source": { "type": "string" },
          "lendersIndexed": { "type": "integer" },
          "criteriaProfiles": { "type": "integer" }
        }
      },
      "Deal": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": false,
        "properties": {
          "amount": { "type": "number", "minimum": 0, "maximum": 100000000 },
          "revenue": { "type": "number", "minimum": 0, "maximum": 100000000 },
          "credit": { "type": "number", "minimum": 300, "maximum": 850 },
          "tibMonths": { "type": "number", "minimum": 0, "maximum": 1200 },
          "adb": { "type": "number", "minimum": 0, "maximum": 100000000 },
          "depositCount": { "type": "number", "minimum": 0, "maximum": 10000 },
          "nsfs": { "type": "number", "minimum": 0, "maximum": 100 },
          "position": { "type": "number", "minimum": 1, "maximum": 10 },
          "ownership": { "type": "number", "minimum": 0, "maximum": 100 },
          "termMonths": { "type": "number", "minimum": 1, "maximum": 120 },
          "state": { "type": "string", "maxLength": 60 },
          "industry": { "type": "string", "maxLength": 120 }
        }
      },
      "MatchFilters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "scope": { "type": "string", "enum": ["all", "favorites"], "default": "all", "description": "Evaluate every indexed lender or only the authenticated ISO account's saved lenders" },
          "paperGrades": { "type": "array", "maxItems": 4, "uniqueItems": true, "items": { "type": "string", "enum": ["A", "B", "C", "D"] } },
          "criteriaOnly": { "type": "boolean", "default": false },
          "includeSlugs": { "type": "array", "maxItems": 50, "uniqueItems": true, "items": { "type": "string" } },
          "excludeSlugs": { "type": "array", "maxItems": 50, "uniqueItems": true, "items": { "type": "string" } }
        }
      },
      "MatchOptions": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 },
          "includeOutside": { "type": "boolean", "default": true },
          "includeChecks": { "type": "boolean", "default": true },
          "includeCriteria": { "type": "boolean", "default": true }
        }
      },
      "MatchRequest": {
        "type": "object",
        "required": ["deal"],
        "additionalProperties": false,
        "properties": {
          "deal": { "$ref": "#/components/schemas/Deal" },
          "filters": { "$ref": "#/components/schemas/MatchFilters" },
          "options": { "$ref": "#/components/schemas/MatchOptions" }
        }
      },
      "LenderSummary": {
        "type": "object",
        "required": ["id", "name", "slug", "profileUrl", "paperGrades", "criteriaCount"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "slug": { "type": "string" },
          "profileUrl": { "type": "string", "format": "uri" },
          "website": { "type": ["string", "null"], "format": "uri" },
          "logoUrl": { "type": ["string", "null"], "format": "uri" },
          "paperGrades": { "type": "array", "items": { "type": "string" } },
          "paperBasis": { "type": ["string", "null"], "enum": ["reported", "criteria-inferred", null] },
          "paperConfidence": { "type": ["string", "null"], "enum": ["low", "medium", "high", null] },
          "paperLabel": { "type": ["string", "null"] },
          "criteriaCount": { "type": "integer" },
          "criteriaStatus": { "type": "string" },
          "criteriaUpdatedAt": { "type": ["string", "null"], "format": "date-time" }
        }
      },
      "Criteria": {
        "type": "object",
        "additionalProperties": { "type": ["string", "number", "array", "null"] }
      },
      "Check": {
        "type": "object",
        "required": ["label", "result", "detail"],
        "properties": {
          "label": { "type": "string" },
          "result": { "type": "string", "enum": ["pass", "fail", "unknown"] },
          "detail": { "type": "string" },
          "actual": { "type": "string" },
          "threshold": { "type": "string" }
        }
      },
      "Match": {
        "type": "object",
        "required": ["lender", "status", "score", "reason", "summary"],
        "properties": {
          "lender": { "$ref": "#/components/schemas/LenderSummary" },
          "status": { "type": "string", "enum": ["fit", "review", "limited", "outside"] },
          "score": { "type": "integer", "minimum": 0, "maximum": 100 },
          "reason": { "type": "string" },
          "summary": { "type": "object", "properties": { "passed": { "type": "integer" }, "failed": { "type": "integer" }, "unknown": { "type": "integer" } } },
          "criteria": { "$ref": "#/components/schemas/Criteria" },
          "checks": { "type": "array", "items": { "$ref": "#/components/schemas/Check" } }
        }
      },
      "MatchResponse": {
        "type": "object",
        "required": ["apiVersion", "requestId", "generatedAt", "dataFreshness", "summary", "matches"],
        "properties": {
          "apiVersion": { "type": "string" },
          "requestId": { "type": "string", "format": "uuid" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "methodology": { "type": "string" },
          "dataFreshness": { "$ref": "#/components/schemas/Freshness" },
          "query": { "type": "object" },
          "applied": { "type": "object" },
          "count": { "type": "integer" },
          "summary": { "type": "object" },
          "notice": { "type": "string" },
          "matches": { "type": "array", "items": { "$ref": "#/components/schemas/Match" } }
        }
      },
      "LenderListResponse": {
        "type": "object",
        "required": ["apiVersion", "requestId", "generatedAt", "dataFreshness", "pagination", "lenders"],
        "properties": {
          "apiVersion": { "type": "string" },
          "requestId": { "type": "string", "format": "uuid" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "dataFreshness": { "$ref": "#/components/schemas/Freshness" },
          "scope": { "type": "string", "enum": ["all", "favorites"] },
          "pagination": { "type": "object" },
          "lenders": { "type": "array", "items": { "allOf": [{ "$ref": "#/components/schemas/LenderSummary" }, { "type": "object", "properties": { "criteria": { "$ref": "#/components/schemas/Criteria" } } }] } }
        }
      },
      "LenderDetailResponse": {
        "type": "object",
        "properties": {
          "apiVersion": { "type": "string" },
          "requestId": { "type": "string", "format": "uuid" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "dataFreshness": { "$ref": "#/components/schemas/Freshness" },
          "lender": { "allOf": [{ "$ref": "#/components/schemas/LenderSummary" }, { "type": "object", "properties": { "criteria": { "$ref": "#/components/schemas/Criteria" }, "classifications": { "type": "array", "items": { "type": "string" } }, "sources": { "type": "array", "items": { "type": "object" } } } }] }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "apiVersion": { "type": "string" },
          "requestId": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "const": "operational" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "dataFreshness": { "$ref": "#/components/schemas/Freshness" },
          "limits": { "type": "object" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["apiVersion", "requestId", "error"],
        "properties": {
          "apiVersion": { "type": "string" },
          "requestId": { "type": "string", "format": "uuid" },
          "error": { "type": "object", "required": ["code", "message"], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "fields": { "type": "object", "additionalProperties": { "type": "string" } } } }
        }
      }
    }
  }
}
