{
  "openapi": "3.0.3",
  "info": {
    "title": "Pioneer Loan Platform API",
    "version": "1.0.0",
    "description": "# Pioneer Public API\n\nThe Pioneer API allows third-party systems to programmatically access loan data,\ndocuments, and related entities.\n\n## URL Structure\n\nAPI requests use environment-specific domains (following existing portal pattern):\n\n```\nProduction:  https://{api-portal}.{bank-domain}/api/public/v1/{resource}\nStaging:     https://{api-portal}.staging.{bank-domain}/api/public/v1/{resource}\n```\n\n- **Production**: `https://api.pioneerft.com/api/public/v1/...` (use `pk_live_*` keys)\n- **Staging**: `https://api.staging.pioneerft.com/api/public/v1/...` (use `pk_test_*` keys)\n\n## Versioning\n\nThe current version is **v1**, served under the `/api/public/v1` path prefix.\nThe legacy unversioned path `/api/public/...` still works but is **deprecated**:\nresponses include `Deprecation: true` and a `Sunset` header. Migrate to\n`/api/public/v1`.\n\n## Authentication\n\nAll API requests require authentication using an API key. Include your API key\nin the `Authorization` header:\n\n```\nAuthorization: Bearer pk_live_your_api_key_here\n```\n\n**Key Types:**\n- `pk_test_*` - Test keys (only work on staging URLs)\n- `pk_live_*` - Live keys (only work on production URLs - no env prefix)\n\nAPI keys can be generated in the Pioneer dashboard under Organization Settings.\nNote: Production keys require explicit approval from Pioneer.\n\n## Rate Limiting\n\nRate limits are applied per API key, with separate budgets for reads and writes:\n\n- **Reads** (GET): **100 requests per minute** per API key.\n- **Writes** (POST/PATCH/DELETE): **30 requests per minute** per API key.\n\nRate limit information is included in response headers:\n\n- `X-RateLimit-Limit`: Maximum requests per window\n- `X-RateLimit-Remaining`: Requests remaining in current window\n- `X-RateLimit-Reset`: Unix timestamp when window resets\n\nWhen rate limited, you'll receive a `429 Too Many Requests` response with\na `Retry-After` header indicating seconds to wait.\n\n**⚠️ Important:** Production API keys (`pk_live_*`) that exceed rate limits\n3 or more times within 24 hours will be automatically revoked, and your\norganization's production API access will be disabled. Contact Pioneer\nsupport to re-enable access.\n\n## Idempotency\n\nWrite requests (POST/PATCH/DELETE) accept an optional `Idempotency-Key` header\n(any opaque string up to 255 chars; a UUID is recommended). Replaying a request\nwith the same key returns the original response instead of repeating the side\neffect.\n\n## Pagination\n\nList endpoints support pagination via query parameters:\n\n- `limit`: Number of items to return (default: 50, max: 100)\n- `offset`: Number of items to skip\n\nResponse includes pagination metadata. Offset-mode responses look like:\n\n```json\n{\n  \"data\": [],\n  \"meta\": {\n    \"mode\": \"offset\",\n    \"limit\": 50,\n    \"offset\": 0,\n    \"hasMore\": true\n  }\n}\n```\n\nCursor-mode responses (returned when a `cursor` query param is supplied) instead\ncontain `{ \"mode\": \"cursor\", \"limit\": 50, \"hasMore\": true, \"nextCursor\": \"<token>\" }`,\nwhere `nextCursor` is an opaque token (null when there are no more results). Pass\nit back as the `cursor` query param to fetch the next page. Offset and cursor are\nmutually exclusive, and cursor mode always orders by creation time.\n\n## Errors\n\nErrors are returned with appropriate HTTP status codes and JSON body:\n\n```json\n{\n  \"code\": \"auth.invalid_key\",\n  \"message\": \"Invalid or expired API key\"\n}\n```\n\nCommon error codes:\n- `auth.invalid_key`: API key is invalid or expired\n- `auth.org_mismatch`: API key does not belong to the organization in the URL\n- `auth.env_mismatch`: API key type does not match URL environment\n- `auth.env_not_available`: Environment not available for this organization\n- `auth.insufficient_permissions`: API key lacks required permission\n- `auth.country_restricted`: Request IP not allowed for this API key\n- `api_key.production_not_allowed`: Organization not approved for production API keys\n- `input.invalid`: Request validation failed\n- `rate_limit.exceeded`: Too many requests\n\n## OpenAPI document\n\nThe spec is published in two OpenAPI versions, both under _Download OpenAPI\ndescription_ and each in YAML and JSON. They are generated from the same routes\nin the same run, describe the identical API, and differ only in schema dialect.\n\n**OpenAPI 3.1.0** is the current one. It uses JSON Schema 2020-12:\n`type: [..., \"null\"]` for nullables and numeric\n`exclusiveMinimum`/`exclusiveMaximum`.\n\n**OpenAPI 3.0.3** is for tooling that does not read 3.1 — the same document with\n`nullable: true` and boolean `exclusive*` instead. It is also what the Postman\ncollection is generated from. 3.0.3 is the last patch of the 3.0 line; a\nconsumer pinned to 3.0.0, 3.0.1 or 3.0.2 reads it without changes, since those\npatches clarify the specification rather than alter the document format.\n\nIf your generator supports both, take 3.1.0.\n\n## API clients\n\nReady-to-import clients are generated from these same routes in the same run, so\nthey never drift from the live API. Both are listed under _Download OpenAPI\ndescription_ above, next to the spec itself.\n\n**Postman.** Import the collection plus the environment for your target\n(Staging or Production), then set `apiKey` to your key — every request inherits\ncollection-level bearer auth. Path parameters such as `:id` appear as editable\nfields under the URL bar, and optional query parameters are pre-filled but\ndisabled, so tick only the ones you need.\n\n**Insomnia.** Imports OpenAPI directly: **Import** -> **File** -> choose the\nOpenAPI 3.0.3 YAML. Set the base environment's `base_url` to the environment you\nare targeting and add your key as a bearer token.\n\nNeed access or a key? [Contact us](https://www.pioneerft.com).",
    "contact": {
      "name": "Pioneer Support",
      "email": "contact@pioneerft.com",
      "url": "https://www.pioneerft.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://pioneerft.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.pioneerft.com/api",
      "description": "Production (pk_live_* keys)"
    },
    {
      "url": "https://api.staging.pioneerft.com/api",
      "description": "Staging (pk_test_* keys)"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Loans",
      "description": "Access and update loan data including details, summaries, status, and entities"
    },
    {
      "name": "Tasks",
      "description": "Read a loan’s workflow approval tasks"
    },
    {
      "name": "Decisions",
      "description": "Read per-product underwriting decisions for a loan"
    },
    {
      "name": "Disbursements",
      "description": "List and manage loan disbursements (amounts in whole cents)"
    },
    {
      "name": "Collateral",
      "description": "List and manage loan collateral (cents for money, basis points for rates)"
    },
    {
      "name": "Debt",
      "description": "Read a loan’s debt schedule (read-only)"
    },
    {
      "name": "Entities",
      "description": "Read, create, and update the businesses and people on a loan. `GET /loans/{id}/entities` lists them; the per-entity GETs add full addresses and contact details. Tax identifiers are masked to the last 4 digits unless the key carries `read:businesses:ein` / `read:people:ssn`."
    },
    {
      "name": "Documents",
      "description": "List, upload, download, update, and delete loan documents"
    },
    {
      "name": "Products",
      "description": "List available loan products"
    },
    {
      "name": "Webhooks",
      "description": "Manage outbound webhook endpoints and inspect delivery attempts"
    }
  ],
  "paths": {
    "/public/v1/loans": {
      "get": {
        "operationId": "listLoans",
        "tags": [
          "Loans"
        ],
        "summary": "List loans",
        "description": "Retrieve a paginated list of loans. Supports filtering by status and product ID. Returns loan summary information without sensitive details.",
        "responses": {
          "200": {
            "description": "Successful response with list of loans",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicLoan"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "type": "number",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "application",
                "active",
                "denied",
                "withdrawn",
                "funded"
              ]
            }
          },
          {
            "in": "query",
            "name": "productId",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sort",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt",
                "centsAmount",
                "status",
                "loanNumber"
              ]
            }
          },
          {
            "in": "query",
            "name": "order",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ]
      }
    },
    "/public/v1/loans/boarding-queue": {
      "get": {
        "operationId": "listBoardingQueue",
        "tags": [
          "Loans"
        ],
        "summary": "List loans ready to board",
        "description": "Loans a banker released to the core and nobody has boarded yet, oldest first. A loan reaches this queue only once a banker releases it — being funded is not enough on its own. Acknowledge a board with `POST /loans/{id}/boarding` and the loan leaves the queue, so a scheduled pull only ever returns work that is still outstanding: a board that failed on your side simply stays. Pass `boarded=true` (optionally with `boardedSince`) to reconcile instead — the loans already boarded.",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "type": "number",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "boarded",
            "schema": {
              "default": "false",
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "in": "query",
            "name": "boardedSince",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Loans ready to board (or already boarded)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/PublicLoan"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "boarding": {
                                "$ref": "#/components/schemas/PublicLoanBoarding"
                              }
                            }
                          }
                        ]
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}": {
      "get": {
        "operationId": "getLoan",
        "tags": [
          "Loans"
        ],
        "summary": "Get loan details",
        "description": "Retrieve detailed information about a specific loan by ID. Returns loan terms, amounts, dates, and status without exposing sensitive internal data.",
        "responses": {
          "200": {
            "description": "Successful response with loan details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicLoan"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "patch": {
        "operationId": "updateLoan",
        "tags": [
          "Loans"
        ],
        "summary": "Update a loan",
        "description": "Update loan fields. Money is in whole cents (`centsAmount: 50000000` is $500,000.00) and rates in basis points (`bpsFixedRate: 525` is 5.25%). Only allowlisted fields can be updated — server-managed fields like status and stage are excluded.",
        "responses": {
          "200": {
            "description": "Loan updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicLoan"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "centsAmount": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "maximum": 9007199254740991,
                    "minimum": 0
                  },
                  "bpsFixedRate": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "bpsSpreadRate": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "bpsPrimeRate": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "rateType": {
                    "type": "string",
                    "enum": [
                      "fixed",
                      "variable"
                    ]
                  },
                  "monthsTerm": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "maximum": 9007199254740991,
                    "minimum": 0
                  },
                  "monthsInterestOnly": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "paymentFrequency": {
                    "type": "string",
                    "enum": [
                      "weekly",
                      "biweekly",
                      "monthly",
                      "quarterly",
                      "semi-annual",
                      "annual",
                      "lump sum",
                      "irregular payments"
                    ]
                  },
                  "purpose": {
                    "type": "string"
                  },
                  "purposeNarrative": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "business",
                      "personal"
                    ]
                  },
                  "loanNumber": {
                    "type": "string"
                  },
                  "productId": {
                    "type": "string"
                  },
                  "applicationDate": {
                    "type": "string",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d))|(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?)$"
                  },
                  "closeDate": {
                    "type": "string",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d))|(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?)$"
                  },
                  "firstPaymentDate": {
                    "type": "string",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d))|(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?)$"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteLoan",
        "tags": [
          "Loans"
        ],
        "summary": "Archive a loan",
        "description": "Soft-delete a loan by setting its deletion timestamp. The loan will no longer appear in list results but can be restored by Pioneer support.",
        "responses": {
          "200": {
            "description": "Loan archived successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Loan archived"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/summary": {
      "get": {
        "operationId": "getLoanSummary",
        "tags": [
          "Loans"
        ],
        "summary": "Get loan summary",
        "description": "Retrieve a summary of a loan including key metrics like total amount, monthly payment, term, and activity status (open tasks, message activity). `hasMessages` reflects non-internal (customer/broker-visible) conversation only — internal banker threads are never exposed.",
        "responses": {
          "200": {
            "description": "Successful response with loan summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "loan": {
                          "$ref": "#/components/schemas/PublicLoan"
                        },
                        "metrics": {
                          "type": "object",
                          "properties": {
                            "centsTotalAmount": {
                              "type": "integer"
                            },
                            "centsMonthlyPayment": {
                              "type": "integer"
                            },
                            "monthsTerm": {
                              "type": "integer"
                            },
                            "hasOpenTasks": {
                              "type": "boolean"
                            },
                            "hasMessages": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/entities": {
      "get": {
        "operationId": "getLoanEntities",
        "tags": [
          "Loans"
        ],
        "summary": "Get loan entities",
        "description": "Retrieve businesses and people associated with a loan. Returns entity names, types, and roles. Sensitive data like full SSN/EIN is excluded (only last 4 digits shown).",
        "responses": {
          "200": {
            "description": "Successful response with loan entities",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "businesses": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "dba": {
                                "type": "string"
                              },
                              "entityType": {
                                "type": "string"
                              },
                              "einLast4": {
                                "type": "string"
                              },
                              "state": {
                                "type": "string"
                              },
                              "role": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "people": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "firstName": {
                                "type": "string"
                              },
                              "lastName": {
                                "type": "string"
                              },
                              "ssnLast4": {
                                "type": "string"
                              },
                              "role": {
                                "type": "string"
                              },
                              "ownershipPercent": {
                                "type": "number"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/search": {
      "post": {
        "operationId": "searchLoans",
        "tags": [
          "Loans"
        ],
        "summary": "Search loans",
        "description": "Advanced loan search with complex filtering capabilities. Supports multiple status filters, date ranges, amount ranges (in whole cents), and custom sorting. Use this endpoint when you need more control than the basic list endpoint.",
        "requestBody": {
          "description": "Search criteria",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "application",
                            "active",
                            "denied",
                            "withdrawn",
                            "funded"
                          ]
                        }
                      },
                      "productIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "centsAmountMin": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "centsAmountMax": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "dateRange": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "pagination": {
                    "type": "object",
                    "properties": {
                      "limit": {
                        "default": 50,
                        "type": "number",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "offset": {
                        "type": "number",
                        "minimum": 0
                      },
                      "cursor": {
                        "type": "string"
                      }
                    }
                  },
                  "sort": {
                    "type": "object",
                    "properties": {
                      "field": {
                        "default": "createdAt",
                        "type": "string",
                        "enum": [
                          "createdAt",
                          "centsAmount",
                          "status",
                          "loanNumber"
                        ]
                      },
                      "order": {
                        "default": "desc",
                        "type": "string",
                        "enum": [
                          "asc",
                          "desc"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful response with search results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicLoan"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/tasks": {
      "get": {
        "operationId": "listLoanTasks",
        "tags": [
          "Tasks"
        ],
        "summary": "List loan tasks",
        "description": "List the workflow tasks (submit / pre-approve / approve / re-submit steps) for a loan, with open/completed status. Read-only: tasks are completed automatically by the loan workflow/decision engine when the corresponding action occurs, not via a direct API write.",
        "responses": {
          "200": {
            "description": "Loan tasks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicTask"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/decisions": {
      "get": {
        "operationId": "listLoanDecisions",
        "tags": [
          "Decisions"
        ],
        "summary": "List underwriting decisions",
        "description": "List the per-product underwriting decisions for a loan. Returns the verdict (approved/declined) and, for declines, the reason. Raw rule internals and applicant data are never exposed.",
        "responses": {
          "200": {
            "description": "Loan underwriting decisions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicDecision"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/status": {
      "get": {
        "operationId": "getLoanStatus",
        "tags": [
          "Loans"
        ],
        "summary": "Get loan status",
        "description": "Get a loan's current status and stage.",
        "responses": {
          "200": {
            "description": "Current loan status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicLoanStatus"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/timeline": {
      "get": {
        "operationId": "getLoanTimeline",
        "tags": [
          "Loans"
        ],
        "summary": "Get loan status timeline",
        "description": "Get the loan's status-transition history (most recent first), sourced from the audit log.",
        "responses": {
          "200": {
            "description": "Loan status timeline",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicTimelineEvent"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/boarding": {
      "get": {
        "operationId": "getLoanBoarding",
        "tags": [
          "Loans"
        ],
        "summary": "Get a loan's boarding state",
        "description": "Whether a banker released the loan to the core, who released it and when, and whether the core has acknowledged the board.",
        "responses": {
          "200": {
            "description": "Boarding state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicLoanBoarding"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "post": {
        "operationId": "acknowledgeLoanBoarding",
        "tags": [
          "Loans"
        ],
        "summary": "Acknowledge a board",
        "description": "Record that the core boarded the loan. The loan leaves the boarding queue and the event is audited. Only a loan a banker released can be acknowledged — a loan that never reached the queue returns 400. Safe to repeat: a second call returns the boarding that already stands rather than overwriting it, so a retry after a lost response cannot rewrite when the core boarded the loan. Send `coreRecordNumber` to store the core’s own identifier for the loan on the Pioneer record.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Boarding recorded (or already recorded)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicLoanBoarding"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The loan was never released to the core, so it is not in the queue",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan_not_released_for_boarding"
                    },
                    "message": {
                      "type": "string",
                      "example": "This loan has not been released to the core yet, so it is not in the boarding queue."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "coreRecordNumber": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/messages": {
      "get": {
        "operationId": "listLoanMessages",
        "tags": [
          "Messages"
        ],
        "summary": "List loan messages",
        "description": "Retrieve messages posted on a loan across its customer/broker-visible chatrooms. Internal banker-only threads are never returned.",
        "responses": {
          "200": {
            "description": "Loan messages (most recent first)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicMessage"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "type": "number",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/public/v1/loans/{id}/disbursements": {
      "get": {
        "operationId": "listLoanDisbursements",
        "tags": [
          "Disbursements"
        ],
        "summary": "List loan disbursements",
        "description": "Retrieve the disbursements recorded against a loan, including amounts (in whole cents), recipients, payment methods, and status.",
        "responses": {
          "200": {
            "description": "Loan disbursements",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicDisbursement"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "post": {
        "operationId": "createDisbursement",
        "tags": [
          "Disbursements"
        ],
        "summary": "Create a disbursement",
        "description": "Create a disbursement on a loan. `centsAmount` is in whole cents — 50000000 is $500,000.00.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Disbursement created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicDisbursement"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "glAccountId": {
                    "description": "Deprecated — accepted for backward compatibility and ignored.",
                    "type": "string"
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "borrower_proceeds",
                      "refinance",
                      "equipment_purchase",
                      "real_estate_purchase",
                      "payroll",
                      "broker_fee",
                      "sba_guarantee_fee",
                      "third_party_payment",
                      "other"
                    ]
                  },
                  "centsAmount": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "maximum": 9007199254740991,
                    "description": "Amount in whole cents. 50000000 = $500,000.00",
                    "minimum": 0
                  },
                  "recipientName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "recipientType": {
                    "type": "string",
                    "enum": [
                      "borrower",
                      "vendor",
                      "broker",
                      "lender",
                      "other"
                    ]
                  },
                  "paymentMethod": {
                    "type": "string",
                    "enum": [
                      "wire",
                      "ach",
                      "check",
                      "internal_transfer"
                    ]
                  },
                  "notes": {
                    "type": "string"
                  }
                },
                "required": [
                  "category",
                  "centsAmount",
                  "recipientName",
                  "recipientType",
                  "paymentMethod"
                ]
              }
            }
          }
        }
      }
    },
    "/public/v1/gl-accounts": {
      "get": {
        "operationId": "listGlAccounts",
        "tags": [
          "Disbursements"
        ],
        "summary": "List GL accounts",
        "description": "List the organization’s general-ledger accounts. Returns active accounts by default.",
        "responses": {
          "200": {
            "description": "GL accounts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicGLAccount"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "type": "number",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "type": "number",
              "minimum": 0
            }
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "query",
            "name": "includeInactive",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ]
      }
    },
    "/public/v1/loans/{loanId}/disbursements/{id}": {
      "patch": {
        "operationId": "updateDisbursement",
        "tags": [
          "Disbursements"
        ],
        "summary": "Update a disbursement",
        "description": "Update an existing disbursement on a loan. Only the fields provided in the request body are changed; `centsAmount` is in whole cents.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "loanId",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Disbursement updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicDisbursement"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "category": {
                    "type": "string",
                    "enum": [
                      "borrower_proceeds",
                      "refinance",
                      "equipment_purchase",
                      "real_estate_purchase",
                      "payroll",
                      "broker_fee",
                      "sba_guarantee_fee",
                      "third_party_payment",
                      "other"
                    ]
                  },
                  "centsAmount": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "maximum": 9007199254740991,
                    "description": "Amount in whole cents. 50000000 = $500,000.00",
                    "minimum": 0
                  },
                  "recipientName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "recipientType": {
                    "type": "string",
                    "enum": [
                      "borrower",
                      "vendor",
                      "broker",
                      "lender",
                      "other"
                    ]
                  },
                  "paymentMethod": {
                    "type": "string",
                    "enum": [
                      "wire",
                      "ach",
                      "check",
                      "internal_transfer"
                    ]
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "approved",
                      "processing",
                      "completed",
                      "failed",
                      "cancelled"
                    ]
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/collateral": {
      "get": {
        "operationId": "listLoanCollateral",
        "tags": [
          "Collateral"
        ],
        "summary": "List loan collateral",
        "description": "Retrieve the collateral items securing a loan, including descriptions, values (in whole cents), advance rate (in basis points), and types.",
        "responses": {
          "200": {
            "description": "Loan collateral",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicCollateral"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "post": {
        "operationId": "createCollateral",
        "tags": [
          "Collateral"
        ],
        "summary": "Add collateral to a loan",
        "description": "Add collateral to a loan. Money is in whole cents and `bpsAdvanceRate` is in basis points (8500 = 85%).",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Collateral created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicCollateral"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  },
                  "centsMarketValue": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991,
                    "description": "Market value in whole cents. 12345600 = $123,456.00"
                  },
                  "bpsAdvanceRate": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10000,
                    "description": "Advance rate in basis points, 0–10000 (8500 = 85%). Not inferred — supply it to drive net-collateral/LTV."
                  },
                  "centsManualPriorLien": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991,
                    "description": "Manually-entered prior lien in whole cents (used in net-collateral/LTV)."
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "person",
                      "business"
                    ]
                  },
                  "ownerId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{loanId}/collateral/{id}": {
      "patch": {
        "operationId": "updateCollateral",
        "tags": [
          "Collateral"
        ],
        "summary": "Update collateral",
        "description": "Update collateral. Money is in whole cents and `bpsAdvanceRate` is in basis points (8500 = 85%).",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "loanId",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Collateral updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicCollateral"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  },
                  "centsMarketValue": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991,
                    "description": "Market value in whole cents. 12345600 = $123,456.00"
                  },
                  "bpsAdvanceRate": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10000,
                    "description": "Advance rate in basis points, 0–10000 (8500 = 85%). Not inferred — supply it to drive net-collateral/LTV."
                  },
                  "centsManualPriorLien": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991,
                    "description": "Manually-entered prior lien in whole cents (used in net-collateral/LTV)."
                  },
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "person",
                      "business"
                    ]
                  },
                  "ownerId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/debt": {
      "get": {
        "operationId": "listLoanDebt",
        "tags": [
          "Debt"
        ],
        "summary": "List loan debt schedule",
        "description": "List a loan's debt schedule (read-only). Debt records are synced from the loan's components/underwriting data and are not editable row-by-row via the API; money is in whole cents and `bpsInterestRate` is in basis points.",
        "responses": {
          "200": {
            "description": "Loan debt schedule",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicDebt"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/businesses/{id}": {
      "get": {
        "operationId": "getBusiness",
        "tags": [
          "Entities"
        ],
        "summary": "Get a business",
        "description": "Retrieve full details for a business, including its addresses. The EIN is returned masked (`einLast4`) unless the API key also holds the `read:businesses:ein` scope, in which case the full value is returned in `ein`. A null `ein` with a non-null `einLast4` means the key lacks that scope; both null means no EIN is on record.",
        "responses": {
          "200": {
            "description": "Successful response with business detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicBusinessDetail"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/people/{id}": {
      "get": {
        "operationId": "getPerson",
        "tags": [
          "Entities"
        ],
        "summary": "Get a person",
        "description": "Retrieve full details for a person, including their addresses. The SSN is returned masked (`ssnLast4`) unless the API key also holds the `read:people:ssn` scope, in which case the full value is returned in `ssn`.",
        "responses": {
          "200": {
            "description": "Successful response with person detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicPersonDetail"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/loans/{id}/businesses": {
      "post": {
        "operationId": "createLoanBusiness",
        "tags": [
          "Entities"
        ],
        "summary": "Create a business on a loan",
        "description": "Create a business and attach it to the loan with the given role (e.g. \"borrower\", \"guarantor\"). Accepts a full EIN; only the last 4 digits are ever returned.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Business created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicBusiness"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid role or input"
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ein": {
                    "type": "string"
                  },
                  "dba": {
                    "type": "string"
                  },
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "C-Corp",
                      "S-Corp",
                      "General Partnership",
                      "Limited Liability Company",
                      "Limited Liability Partnership",
                      "Sole Proprietorship",
                      "Trust"
                    ]
                  },
                  "state": {
                    "type": "string"
                  },
                  "naics": {
                    "type": "string",
                    "maxLength": 6
                  },
                  "role": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Entity-in-loan role name, e.g. \"borrower\" or \"guarantor\" (resolved server-side; unknown names return 400). See the roles echoed by GET /loans/:id/entities."
                  }
                },
                "required": [
                  "name",
                  "role"
                ]
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{loanId}/businesses/{id}": {
      "patch": {
        "operationId": "updateLoanBusiness",
        "tags": [
          "Entities"
        ],
        "summary": "Update a business on a loan",
        "description": "Update the details of a business associated with a loan. Only the fields provided in the request body are changed.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "loanId",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Business updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicBusiness"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ein": {
                    "type": "string"
                  },
                  "dba": {
                    "type": "string"
                  },
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "C-Corp",
                      "S-Corp",
                      "General Partnership",
                      "Limited Liability Company",
                      "Limited Liability Partnership",
                      "Sole Proprietorship",
                      "Trust"
                    ]
                  },
                  "state": {
                    "type": "string"
                  },
                  "naics": {
                    "type": "string",
                    "maxLength": 6
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/people": {
      "post": {
        "operationId": "createLoanPerson",
        "tags": [
          "Entities"
        ],
        "summary": "Create a person on a loan",
        "description": "Create a person and attach them to the loan with the given role. Accepts a full SSN; only the last 4 digits are ever returned.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Person created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicPerson"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid role or input"
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firstName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "lastName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ssn": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "dob": {
                    "type": "string",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d))|(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?)$"
                  },
                  "role": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Entity-in-loan role name, e.g. \"borrower\" or \"guarantor\" (resolved server-side; unknown names return 400). See the roles echoed by GET /loans/:id/entities."
                  }
                },
                "required": [
                  "firstName",
                  "lastName",
                  "role"
                ]
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{loanId}/people/{id}": {
      "patch": {
        "operationId": "updateLoanPerson",
        "tags": [
          "Entities"
        ],
        "summary": "Update a person on a loan",
        "description": "Update the details of a person associated with a loan. Only the fields provided in the request body are changed.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "loanId",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Person updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicPerson"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firstName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "lastName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ssn": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "dob": {
                    "type": "string",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d))|(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?)$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/loans/{id}/documents": {
      "get": {
        "operationId": "listLoanDocuments",
        "tags": [
          "Documents"
        ],
        "summary": "List loan documents",
        "description": "Retrieve every document on a loan: files uploaded against a document requirement (the rows on the loan's Documents tab, whether the requirement targets the loan, a person, or a business) plus loan-level artifacts the platform generates, such as term sheets and adverse-action notices. Each entry carries the `requirement` it satisfies — including its review `status` and its `id`, which is what you pass as `requirementID` when uploading. `requirement` is null for generated artifacts. Use the download endpoint to get a presigned URL for the file itself.",
        "responses": {
          "200": {
            "description": "Successful response with document list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicDocument"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "post": {
        "operationId": "uploadDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Upload a document",
        "description": "Step 1 of 2. Creates the document record and returns a presigned upload URL; PUT the file content to that URL, then call `POST /documents/{id}/confirm` — the confirm step is what verifies the bytes landed and attaches the file to its requirement. A document that is never confirmed stays invisible to the bank.\n\nPass `requirementID` (a requirement `id` from `GET /loans/{id}/documents`) so the upload satisfies that requirement and appears on the banker's Documents tab for review. Omit it only for a loan-level attachment that answers no requirement — those are not surfaced for review.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this upload safely retryable. A replay with the same key returns the original response instead of creating a duplicate record."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Document record created with presigned upload URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "uploadUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "type": {
                    "type": "string",
                    "minLength": 1
                  },
                  "size": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "maximum": 9007199254740991,
                    "minimum": 0
                  },
                  "requirementID": {
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "type",
                  "size"
                ]
              }
            }
          }
        }
      }
    },
    "/public/v1/documents/{id}/download": {
      "get": {
        "operationId": "getDocumentDownloadUrl",
        "tags": [
          "Documents"
        ],
        "summary": "Get document download URL",
        "description": "Get a presigned download URL for a document. The URL is valid for 5 minutes. Use this URL to download the actual document file directly.",
        "responses": {
          "200": {
            "description": "Successful response with download URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "size": {
                          "type": "integer"
                        },
                        "category": {
                          "type": "string"
                        },
                        "uploadedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "downloadUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/products": {
      "get": {
        "operationId": "listProducts",
        "tags": [
          "Products"
        ],
        "summary": "List products",
        "description": "Retrieve a list of available loan products. Returns product details including name, description, terms, and rate types.",
        "responses": {
          "200": {
            "description": "Successful response with product list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicProduct"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/products/{id}": {
      "get": {
        "operationId": "getProduct",
        "tags": [
          "Products"
        ],
        "summary": "Get product details",
        "description": "Retrieve detailed information about a specific loan product by ID. Returns product name, description, terms, amortization period, rate type, and payment frequency.",
        "responses": {
          "200": {
            "description": "Successful response with product details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicProduct"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/documents/{id}/confirm": {
      "post": {
        "operationId": "confirmDocumentUpload",
        "tags": [
          "Documents"
        ],
        "summary": "Confirm a document upload",
        "description": "Step 2 of 2. Call after PUTting the file content to the presigned URL. Verifies the blob actually arrived (and is within the size cap) and, for a requirement-backed upload, attaches it to that requirement so it appears on the banker's Documents tab as `PENDING` review.\n\nUntil this is called the record exists but the bank cannot see the document.\n\n**Pass `period` when the requirement collects more than one** (three years of tax returns, say) — those 400 with `period_key_required` otherwise, since nothing can infer which year the file answers. Use the `period` value from `GET /loans/{id}/documents`.\n\nRetrying is safe in the sense that it never corrupts anything, but it is NOT a no-op: re-confirming an already-attached file adds another version to the same requirement, matching how a re-upload behaves in the UI. Retry after a *failed* confirm, not after a successful one.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Upload confirmed and attached",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicDocument"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Blob missing, oversized, or the requirement cannot accept an upload"
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "period": {
                    "type": "string",
                    "description": "Which period this document answers, e.g. `2024`. REQUIRED when the requirement collects more than one period (three years of tax returns, say); those 400 with `period_key_required` if it is omitted, rather than guessing a year. Use the `period` value from `GET /loans/{id}/documents`. Omit only for a single-period requirement."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/documents/{id}": {
      "patch": {
        "operationId": "updateDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Update document metadata",
        "description": "Update document metadata. Currently only the document name can be updated.",
        "responses": {
          "200": {
            "description": "Document updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicDocument"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Delete a document",
        "description": "Soft-delete a document by setting its deletion timestamp. The document will no longer appear in list results. If it satisfied a requirement it is also detached from it, and any requirement period left with no remaining file returns to `AWAITING_UPLOAD`.",
        "responses": {
          "200": {
            "description": "Document deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Document deleted"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/webhook-endpoints": {
      "post": {
        "operationId": "createWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Register a webhook endpoint",
        "description": "Register an HTTPS endpoint to receive event deliveries. The signing secret is returned ONCE in this response and never again — store it securely. Private/loopback URLs are rejected.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          }
        ],
        "responses": {
          "201": {
            "description": "Endpoint created (includes the one-time signing secret)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicWebhookEndpointWithSecret"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL (non-https / private host) or input"
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "url": {
                    "type": "string",
                    "format": "starts_with",
                    "pattern": "^https:\\/\\/.*",
                    "description": "HTTPS URL; private/loopback/metadata hosts are rejected."
                  },
                  "subscribedEvents": {
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "loan.created",
                        "loan.status_changed",
                        "loan.funded",
                        "document.uploaded",
                        "document.signed"
                      ]
                    }
                  }
                },
                "required": [
                  "name",
                  "url",
                  "subscribedEvents"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listWebhookEndpoints",
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "description": "List your organization's webhook endpoints. The signing secret is never returned.",
        "responses": {
          "200": {
            "description": "Webhook endpoints",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicWebhookEndpoint"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/webhook-endpoints/{id}": {
      "get": {
        "operationId": "getWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Get a webhook endpoint",
        "description": "Retrieve a single webhook endpoint by ID, including its target URL, subscribed event types, and status.",
        "responses": {
          "200": {
            "description": "Webhook endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicWebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      },
      "patch": {
        "operationId": "updateWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Update a webhook endpoint",
        "description": "Update a webhook endpoint — change its target URL, subscribed event types, or status. Only the fields provided in the request body are changed.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook endpoint updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PublicWebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or input"
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "url": {
                    "type": "string",
                    "format": "starts_with",
                    "pattern": "^https:\\/\\/.*",
                    "description": "HTTPS URL; private/loopback/metadata hosts are rejected."
                  },
                  "subscribedEvents": {
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "loan.created",
                        "loan.status_changed",
                        "loan.funded",
                        "document.uploaded",
                        "document.signed"
                      ]
                    }
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused",
                      "disabled"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook endpoint",
        "description": "Soft-delete (disable) a webhook endpoint. Delivery history is retained.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoint deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Webhook endpoint deleted"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/webhook-endpoints/{id}/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate a webhook signing secret",
        "description": "Generate a new signing secret. It is returned ONCE in this response and never again.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Optional opaque key (e.g. a UUID) to make this write safely retryable. A replay with the same key returns the original response instead of repeating the side effect."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "New signing secret (shown once)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "secret": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public/v1/webhook-endpoints/{id}/test": {
      "post": {
        "operationId": "testWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event",
        "description": "Synchronously deliver a `test.ping` event to the endpoint and return the result. Does not count toward auto-disable, and is intentionally NOT idempotency-keyed (safe to repeat).",
        "responses": {
          "200": {
            "description": "Test delivery result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean"
                        },
                        "statusCode": {
                          "type": "integer"
                        },
                        "error": {
                          "type": "string"
                        },
                        "responseTimeMs": {
                          "type": "integer"
                        },
                        "eventId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ]
      }
    },
    "/public/v1/webhook-endpoints/{id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "tags": [
          "Webhooks"
        ],
        "summary": "List delivery attempts for an endpoint",
        "description": "Retrieve recent delivery attempts for a webhook endpoint, including status, response codes, and timestamps, to help debug your integration.",
        "responses": {
          "200": {
            "description": "Delivery attempts (most recent first)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublicWebhookDelivery"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "error": {
                      "type": "array",
                      "items": {}
                    },
                    "data": {}
                  },
                  "required": [
                    "success",
                    "error",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Requested resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "loan.not_found"
                    },
                    "message": {
                      "type": "string",
                      "example": "Loan not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "type": "number",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "number",
              "minimum": 0
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed",
                "retrying"
              ]
            }
          }
        ]
      }
    },
    "/public/v1/webhook-events": {
      "get": {
        "operationId": "listWebhookEventTypes",
        "tags": [
          "Webhooks"
        ],
        "summary": "List supported webhook event types",
        "description": "List the webhook event types you can subscribe an endpoint to, with a short description of each.",
        "responses": {
          "200": {
            "description": "Supported event types",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - Invalid or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.invalid_key"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invalid or expired API key"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "auth.insufficient_permissions"
                    },
                    "message": {
                      "type": "string",
                      "example": "Missing required permission"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded - Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "example": "rate_limit.exceeded"
                    },
                    "message": {
                      "type": "string",
                      "example": "Too many requests"
                    },
                    "retryAfter": {
                      "type": "integer",
                      "example": 45
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "API key obtained from Pioneer dashboard. Format: pk_live_xxx or pk_test_xxx"
      }
    },
    "schemas": {
      "PublicLoan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanNumber": {
            "nullable": true,
            "type": "string"
          },
          "status": {
            "nullable": true,
            "type": "string"
          },
          "type": {
            "nullable": true,
            "type": "string",
            "enum": [
              "business",
              "personal"
            ]
          },
          "centsAmount": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "centsMonthlyPayment": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "monthsTerm": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "monthsInterestOnly": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "paymentFrequency": {
            "nullable": true,
            "type": "string",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "quarterly",
              "semi-annual",
              "annual",
              "lump sum",
              "irregular payments"
            ]
          },
          "rateType": {
            "nullable": true,
            "type": "string",
            "enum": [
              "fixed",
              "variable"
            ]
          },
          "bpsRate": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "purpose": {
            "nullable": true,
            "type": "string"
          },
          "purposeNarrative": {
            "nullable": true,
            "type": "string"
          },
          "applicationDate": {
            "nullable": true,
            "type": "string"
          },
          "closeDate": {
            "nullable": true,
            "type": "string"
          },
          "maturityDate": {
            "nullable": true,
            "type": "string"
          },
          "firstPaymentDate": {
            "nullable": true,
            "type": "string"
          },
          "product": {
            "nullable": true,
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "stage": {
            "nullable": true,
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "loanNumber",
          "status",
          "type",
          "centsAmount",
          "centsMonthlyPayment",
          "monthsTerm",
          "monthsInterestOnly",
          "paymentFrequency",
          "rateType",
          "bpsRate",
          "purpose",
          "purposeNarrative",
          "applicationDate",
          "closeDate",
          "maturityDate",
          "firstPaymentDate",
          "product",
          "stage",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "PaginationMeta": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "offset"
                ]
              },
              "limit": {
                "type": "number"
              },
              "offset": {
                "type": "number"
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "mode",
              "limit",
              "offset",
              "hasMore"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "cursor"
                ]
              },
              "limit": {
                "type": "number"
              },
              "hasMore": {
                "type": "boolean"
              },
              "nextCursor": {
                "nullable": true,
                "type": "string"
              }
            },
            "required": [
              "mode",
              "limit",
              "hasMore",
              "nextCursor"
            ],
            "additionalProperties": false
          }
        ]
      },
      "PublicProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "nullable": true,
            "type": "string"
          },
          "monthsTerm": {
            "type": "number"
          },
          "monthsAmortization": {
            "type": "number"
          },
          "rateType": {
            "type": "string",
            "enum": [
              "fixed",
              "variable"
            ]
          },
          "paymentFrequency": {
            "type": "string",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "quarterly",
              "semi-annual",
              "annual",
              "lump sum",
              "irregular payments"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "monthsTerm",
          "monthsAmortization",
          "rateType",
          "paymentFrequency"
        ],
        "additionalProperties": false
      },
      "PublicBusiness": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "dba": {
            "nullable": true,
            "type": "string"
          },
          "entityType": {
            "nullable": true,
            "type": "string"
          },
          "einLast4": {
            "nullable": true,
            "type": "string"
          },
          "state": {
            "nullable": true,
            "type": "string"
          },
          "naics": {
            "nullable": true,
            "type": "string",
            "maxLength": 6
          },
          "role": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "dba",
          "entityType",
          "einLast4",
          "state",
          "naics",
          "role"
        ],
        "additionalProperties": false
      },
      "PublicBusinessDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "dba": {
            "nullable": true,
            "type": "string"
          },
          "entityType": {
            "nullable": true,
            "type": "string"
          },
          "einLast4": {
            "nullable": true,
            "type": "string"
          },
          "state": {
            "nullable": true,
            "type": "string"
          },
          "naics": {
            "nullable": true,
            "type": "string",
            "maxLength": 6
          },
          "role": {
            "nullable": true,
            "type": "string"
          },
          "ein": {
            "nullable": true,
            "type": "string"
          },
          "tinType": {
            "nullable": true,
            "type": "string"
          },
          "incorporationDate": {
            "nullable": true,
            "type": "string"
          },
          "phone": {
            "nullable": true,
            "type": "string"
          },
          "email": {
            "nullable": true,
            "type": "string"
          },
          "url": {
            "nullable": true,
            "type": "string"
          },
          "numberOfEmployees": {
            "nullable": true,
            "type": "number"
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "address2": {
                  "nullable": true,
                  "type": "string"
                },
                "city": {
                  "nullable": true,
                  "type": "string"
                },
                "state": {
                  "nullable": true,
                  "type": "string"
                },
                "zipCode": {
                  "nullable": true,
                  "type": "string"
                }
              },
              "required": [
                "id",
                "address",
                "address2",
                "city",
                "state",
                "zipCode"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "id",
          "name",
          "dba",
          "entityType",
          "einLast4",
          "state",
          "naics",
          "role",
          "ein",
          "tinType",
          "incorporationDate",
          "phone",
          "email",
          "url",
          "numberOfEmployees",
          "locations"
        ],
        "additionalProperties": false
      },
      "PublicPerson": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "ssnLast4": {
            "nullable": true,
            "type": "string"
          },
          "role": {
            "nullable": true,
            "type": "string"
          },
          "ownershipPercent": {
            "nullable": true,
            "type": "number"
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName",
          "ssnLast4",
          "role",
          "ownershipPercent"
        ],
        "additionalProperties": false
      },
      "PublicPersonDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "ssnLast4": {
            "nullable": true,
            "type": "string"
          },
          "role": {
            "nullable": true,
            "type": "string"
          },
          "ownershipPercent": {
            "nullable": true,
            "type": "number"
          },
          "middleName": {
            "nullable": true,
            "type": "string"
          },
          "suffix": {
            "nullable": true,
            "type": "string"
          },
          "ssn": {
            "nullable": true,
            "type": "string"
          },
          "email": {
            "nullable": true,
            "type": "string"
          },
          "phone": {
            "nullable": true,
            "type": "string"
          },
          "dob": {
            "nullable": true,
            "type": "string"
          },
          "citizenship": {
            "nullable": true,
            "type": "string"
          },
          "maritalStatus": {
            "nullable": true,
            "type": "string"
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "address2": {
                  "nullable": true,
                  "type": "string"
                },
                "city": {
                  "nullable": true,
                  "type": "string"
                },
                "state": {
                  "nullable": true,
                  "type": "string"
                },
                "zipCode": {
                  "nullable": true,
                  "type": "string"
                }
              },
              "required": [
                "id",
                "address",
                "address2",
                "city",
                "state",
                "zipCode"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName",
          "ssnLast4",
          "role",
          "ownershipPercent",
          "middleName",
          "suffix",
          "ssn",
          "email",
          "phone",
          "dob",
          "citizenship",
          "maritalStatus",
          "locations"
        ],
        "additionalProperties": false
      },
      "PublicDocument": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "size": {
            "type": "number"
          },
          "category": {
            "nullable": true,
            "type": "string"
          },
          "uploadedAt": {
            "type": "string"
          },
          "requirement": {
            "nullable": true,
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "status": {
                "nullable": true,
                "type": "string"
              },
              "module": {
                "nullable": true,
                "type": "string"
              },
              "entityType": {
                "type": "string",
                "enum": [
                  "loan",
                  "person",
                  "business"
                ]
              },
              "entityID": {
                "type": "string"
              },
              "period": {
                "nullable": true,
                "type": "string"
              }
            },
            "required": [
              "id",
              "name",
              "status",
              "module",
              "entityType",
              "entityID",
              "period"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "size",
          "category",
          "uploadedAt",
          "requirement"
        ],
        "additionalProperties": false
      },
      "PublicTask": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "componentId": {
            "nullable": true,
            "type": "string"
          },
          "action": {
            "type": "string"
          },
          "triggerAction": {
            "nullable": true,
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "completed"
            ]
          },
          "completedAt": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "loanId",
          "componentId",
          "action",
          "triggerAction",
          "status",
          "completedAt"
        ],
        "additionalProperties": false
      },
      "PublicDecision": {
        "type": "object",
        "properties": {
          "productId": {
            "type": "string"
          },
          "productName": {
            "type": "string"
          },
          "verdict": {
            "type": "string",
            "enum": [
              "approved",
              "declined"
            ]
          },
          "reason": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "productId",
          "productName",
          "verdict",
          "reason"
        ],
        "additionalProperties": false
      },
      "PublicLoanStatus": {
        "type": "object",
        "properties": {
          "status": {
            "nullable": true,
            "type": "string"
          },
          "stage": {
            "nullable": true,
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "status",
          "stage"
        ],
        "additionalProperties": false
      },
      "PublicTimelineEvent": {
        "type": "object",
        "properties": {
          "timestamp": {
            "nullable": true,
            "type": "string"
          },
          "status": {
            "nullable": true,
            "type": "string"
          },
          "changedBy": {
            "nullable": true,
            "type": "string"
          },
          "note": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "timestamp",
          "status",
          "changedBy",
          "note"
        ],
        "additionalProperties": false
      },
      "PublicLoanBoarding": {
        "type": "object",
        "properties": {
          "loanId": {
            "type": "string"
          },
          "status": {
            "nullable": true,
            "type": "string"
          },
          "releasable": {
            "type": "boolean"
          },
          "released": {
            "type": "boolean"
          },
          "releasedAt": {
            "nullable": true,
            "type": "string"
          },
          "releasedBy": {
            "nullable": true,
            "type": "string"
          },
          "boarded": {
            "type": "boolean"
          },
          "boardedAt": {
            "nullable": true,
            "type": "string"
          },
          "coreRecordNumber": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "loanId",
          "status",
          "releasable",
          "released",
          "releasedAt",
          "releasedBy",
          "boarded",
          "boardedAt",
          "coreRecordNumber"
        ],
        "additionalProperties": false
      },
      "PublicMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "authorId": {
            "nullable": true,
            "type": "string"
          },
          "authorName": {
            "nullable": true,
            "type": "string"
          },
          "parentMessageId": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "content",
          "authorId",
          "authorName",
          "parentMessageId",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "PublicDisbursement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "category": {
            "nullable": true,
            "type": "string"
          },
          "centsAmount": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "recipientName": {
            "nullable": true,
            "type": "string"
          },
          "recipientType": {
            "nullable": true,
            "type": "string"
          },
          "paymentMethod": {
            "nullable": true,
            "type": "string"
          },
          "status": {
            "nullable": true,
            "type": "string"
          },
          "notes": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "loanId",
          "category",
          "centsAmount",
          "recipientName",
          "recipientType",
          "paymentMethod",
          "status",
          "notes",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "PublicGLAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "accountNumber": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "mainCategory": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "subcategory": {
            "nullable": true,
            "type": "string"
          },
          "accountType": {
            "type": "string"
          },
          "isActive": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "accountNumber",
          "name",
          "mainCategory",
          "category",
          "subcategory",
          "accountType",
          "isActive"
        ],
        "additionalProperties": false
      },
      "PublicCollateral": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "description": {
            "nullable": true,
            "type": "string"
          },
          "category": {
            "nullable": true,
            "type": "string"
          },
          "centsMarketValue": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "bpsAdvanceRate": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "centsPriorLienAmount": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "centsManualPriorLien": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "ownerType": {
            "nullable": true,
            "type": "string"
          },
          "ownerId": {
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "loanId",
          "description",
          "category",
          "centsMarketValue",
          "bpsAdvanceRate",
          "centsPriorLienAmount",
          "centsManualPriorLien",
          "ownerType",
          "ownerId"
        ],
        "additionalProperties": false
      },
      "PublicDebt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "creditorName": {
            "type": "string"
          },
          "debtType": {
            "nullable": true,
            "type": "string"
          },
          "centsOutstandingBalance": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "centsPaymentAmount": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "paymentFrequency": {
            "nullable": true,
            "type": "string"
          },
          "bpsInterestRate": {
            "nullable": true,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "isRefinanced": {
            "type": "boolean"
          },
          "isSecuredByCollateral": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "loanId",
          "creditorName",
          "debtType",
          "centsOutstandingBalance",
          "centsPaymentAmount",
          "paymentFrequency",
          "bpsInterestRate",
          "isRefinanced",
          "isSecuredByCollateral"
        ],
        "additionalProperties": false
      },
      "PublicWebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "environment": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "subscribedEvents": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consecutiveFailures": {
            "type": "number"
          },
          "lastSuccessAt": {
            "nullable": true,
            "type": "string"
          },
          "lastFailureAt": {
            "nullable": true,
            "type": "string"
          },
          "lastFailureReason": {
            "nullable": true,
            "type": "string"
          },
          "autoDisabledAt": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "environment",
          "status",
          "subscribedEvents",
          "consecutiveFailures",
          "lastSuccessAt",
          "lastFailureAt",
          "lastFailureReason",
          "autoDisabledAt",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "PublicWebhookEndpointWithSecret": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "environment": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "subscribedEvents": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consecutiveFailures": {
            "type": "number"
          },
          "lastSuccessAt": {
            "nullable": true,
            "type": "string"
          },
          "lastFailureAt": {
            "nullable": true,
            "type": "string"
          },
          "lastFailureReason": {
            "nullable": true,
            "type": "string"
          },
          "autoDisabledAt": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "environment",
          "status",
          "subscribedEvents",
          "consecutiveFailures",
          "lastSuccessAt",
          "lastFailureAt",
          "lastFailureReason",
          "autoDisabledAt",
          "createdAt",
          "secret"
        ],
        "additionalProperties": false
      },
      "PublicWebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "eventId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "attempts": {
            "type": "number"
          },
          "maxAttempts": {
            "type": "number"
          },
          "responseStatus": {
            "nullable": true,
            "type": "number"
          },
          "responseTimeMs": {
            "nullable": true,
            "type": "number"
          },
          "nextRetryAt": {
            "nullable": true,
            "type": "string"
          },
          "deliveredAt": {
            "nullable": true,
            "type": "string"
          },
          "failedAt": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "event",
          "eventId",
          "status",
          "attempts",
          "maxAttempts",
          "responseStatus",
          "responseTimeMs",
          "nextRetryAt",
          "deliveredAt",
          "failedAt",
          "createdAt"
        ],
        "additionalProperties": false
      }
    }
  }
}