{
  "openapi": "3.1.0",
  "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": 0,
                    "maximum": 9007199254740991
                  },
                  "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": 0,
                    "maximum": 9007199254740991
                  },
                  "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": 0,
                    "maximum": 9007199254740991,
                    "description": "Amount in whole cents. 50000000 = $500,000.00"
                  },
                  "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": 0,
                    "maximum": 9007199254740991,
                    "description": "Amount in whole cents. 50000000 = $500,000.00"
                  },
                  "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": 0,
                    "maximum": 9007199254740991
                  },
                  "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "business",
                  "personal"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "centsAmount": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "centsMonthlyPayment": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "monthsTerm": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "monthsInterestOnly": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "paymentFrequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "weekly",
                  "biweekly",
                  "monthly",
                  "quarterly",
                  "semi-annual",
                  "annual",
                  "lump sum",
                  "irregular payments"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "rateType": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "fixed",
                  "variable"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "bpsRate": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "purpose": {
            "type": [
              "string",
              "null"
            ]
          },
          "purposeNarrative": {
            "type": [
              "string",
              "null"
            ]
          },
          "applicationDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "closeDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "maturityDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "firstPaymentDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "product": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "stage": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "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",
                "const": "offset"
              },
              "limit": {
                "type": "number"
              },
              "offset": {
                "type": "number"
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "mode",
              "limit",
              "offset",
              "hasMore"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "const": "cursor"
              },
              "limit": {
                "type": "number"
              },
              "hasMore": {
                "type": "boolean"
              },
              "nextCursor": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "mode",
              "limit",
              "hasMore",
              "nextCursor"
            ],
            "additionalProperties": false
          }
        ]
      },
      "PublicProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "entityType": {
            "type": [
              "string",
              "null"
            ]
          },
          "einLast4": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "naics": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 6
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "dba",
          "entityType",
          "einLast4",
          "state",
          "naics",
          "role"
        ],
        "additionalProperties": false
      },
      "PublicBusinessDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "dba": {
            "type": [
              "string",
              "null"
            ]
          },
          "entityType": {
            "type": [
              "string",
              "null"
            ]
          },
          "einLast4": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "naics": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 6
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "ein": {
            "type": [
              "string",
              "null"
            ]
          },
          "tinType": {
            "type": [
              "string",
              "null"
            ]
          },
          "incorporationDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "numberOfEmployees": {
            "type": [
              "number",
              "null"
            ]
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "address2": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "city": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "state": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "zipCode": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownershipPercent": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName",
          "ssnLast4",
          "role",
          "ownershipPercent"
        ],
        "additionalProperties": false
      },
      "PublicPersonDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "ssnLast4": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownershipPercent": {
            "type": [
              "number",
              "null"
            ]
          },
          "middleName": {
            "type": [
              "string",
              "null"
            ]
          },
          "suffix": {
            "type": [
              "string",
              "null"
            ]
          },
          "ssn": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "dob": {
            "type": [
              "string",
              "null"
            ]
          },
          "citizenship": {
            "type": [
              "string",
              "null"
            ]
          },
          "maritalStatus": {
            "type": [
              "string",
              "null"
            ]
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "address2": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "city": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "state": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "zipCode": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "uploadedAt": {
            "type": "string"
          },
          "requirement": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "module": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "loan",
                      "person",
                      "business"
                    ]
                  },
                  "entityID": {
                    "type": "string"
                  },
                  "period": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "id",
                  "name",
                  "status",
                  "module",
                  "entityType",
                  "entityID",
                  "period"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "size",
          "category",
          "uploadedAt",
          "requirement"
        ],
        "additionalProperties": false
      },
      "PublicTask": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "componentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "action": {
            "type": "string"
          },
          "triggerAction": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "completed"
            ]
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "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": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "productId",
          "productName",
          "verdict",
          "reason"
        ],
        "additionalProperties": false
      },
      "PublicLoanStatus": {
        "type": "object",
        "properties": {
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "stage": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "status",
          "stage"
        ],
        "additionalProperties": false
      },
      "PublicTimelineEvent": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "changedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "timestamp",
          "status",
          "changedBy",
          "note"
        ],
        "additionalProperties": false
      },
      "PublicLoanBoarding": {
        "type": "object",
        "properties": {
          "loanId": {
            "type": "string"
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "releasable": {
            "type": "boolean"
          },
          "released": {
            "type": "boolean"
          },
          "releasedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "releasedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "boarded": {
            "type": "boolean"
          },
          "boardedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "coreRecordNumber": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "loanId",
          "status",
          "releasable",
          "released",
          "releasedAt",
          "releasedBy",
          "boarded",
          "boardedAt",
          "coreRecordNumber"
        ],
        "additionalProperties": false
      },
      "PublicMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "authorId": {
            "type": [
              "string",
              "null"
            ]
          },
          "authorName": {
            "type": [
              "string",
              "null"
            ]
          },
          "parentMessageId": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "content",
          "authorId",
          "authorName",
          "parentMessageId",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "PublicDisbursement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "loanId": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "centsAmount": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "recipientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientType": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentMethod": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "centsMarketValue": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "bpsAdvanceRate": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "centsPriorLienAmount": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "centsManualPriorLien": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "ownerType": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownerId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "centsOutstandingBalance": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "centsPaymentAmount": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "paymentFrequency": {
            "type": [
              "string",
              "null"
            ]
          },
          "bpsInterestRate": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFailureAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFailureReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "autoDisabledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "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": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFailureAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFailureReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "autoDisabledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "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": {
            "type": [
              "number",
              "null"
            ]
          },
          "responseTimeMs": {
            "type": [
              "number",
              "null"
            ]
          },
          "nextRetryAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "deliveredAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "failedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "event",
          "eventId",
          "status",
          "attempts",
          "maxAttempts",
          "responseStatus",
          "responseTimeMs",
          "nextRetryAt",
          "deliveredAt",
          "failedAt",
          "createdAt"
        ],
        "additionalProperties": false
      }
    }
  }
}