{
  "openapi": "3.1.0",
  "info": {
    "title": "CU Wire Data Access API",
    "version": "1.0.0",
    "description": "Read-only licensed API surface for CU Wire Data Access customers. The v1 API provides quarterly feed metadata, short-lived data-feed download broker links, a current system summary endpoint, and institution lookup endpoints."
  },
  "servers": [
    {
      "url": "https://cuwiredata.com"
    }
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "paths": {
    "/api/data-feed": {
      "get": {
        "summary": "Return quarterly data-feed metadata or issue a short-lived download broker link",
        "description": "Without a file parameter, returns the deployable manifest for a licensed quarterly feed. With file=archive or a package filename, returns a 302 redirect to a short-lived broker URL when backing storage is configured.",
        "operationId": "getDataFeed",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-Q[1-4]$",
              "example": "2026-Q1"
            },
            "description": "Quarterly package period. Defaults to the current promoted period when omitted."
          },
          {
            "name": "file",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "archive"
            },
            "description": "Use archive for the full package, or a manifest file path such as institutions.csv when per-file delivery is configured."
          }
        ],
        "responses": {
          "200": {
            "description": "Manifest metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataFeedManifestResponse"
                }
              }
            }
          },
          "302": {
            "description": "Short-lived broker link issued for a requested file"
          },
          "400": {
            "description": "Query-string API key rejected"
          },
          "401": {
            "description": "Missing bearer API key"
          },
          "403": {
            "description": "Invalid, revoked, or non-data_access key"
          },
          "404": {
            "description": "Requested period or file was not found"
          },
          "429": {
            "description": "Rate limit exceeded"
          },
          "503": {
            "description": "Download storage or signing is not configured"
          }
        }
      }
    },
    "/api/data-feed-download": {
      "get": {
        "summary": "Redeem a short-lived data-feed broker token",
        "description": "This endpoint is normally reached through the Location header returned by /api/data-feed when a file is requested. Tokens are scoped to the data_feed product and expire quickly.",
        "operationId": "redeemDataFeedDownload",
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Short-lived broker token issued by /api/data-feed."
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to backing feed storage"
          },
          "401": {
            "description": "Invalid token"
          },
          "403": {
            "description": "Associated API key prefix is no longer authorized"
          },
          "410": {
            "description": "Expired token"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/cuwiredata-cu-summary": {
      "get": {
        "summary": "Return current CU system summary",
        "description": "Returns current promoted-period aggregate counts and balances from the CU Wire Data NCUA Call Report dataset.",
        "operationId": "getCuWireDataSummary",
        "responses": {
          "200": {
            "description": "Current system summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SummaryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Query-string API key rejected"
          },
          "401": {
            "description": "Missing bearer API key"
          },
          "403": {
            "description": "Invalid, revoked, or non-data_access key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/cuwiredata-institutions": {
      "get": {
        "summary": "Return a paginated institution list",
        "description": "Returns a bounded, filterable list of federally insured credit unions from the current promoted CU Wire Data dataset. Results use readable field names rather than internal compact codes.",
        "operationId": "listCuWireDataInstitutions",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "example": "state employees" },
            "description": "Search charter, name, city, or state."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "pattern": "^[A-Z]{2}$", "example": "NC" }
          },
          {
            "name": "asset_tier",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["mega", "large", "mid", "small", "micro"] }
          },
          {
            "name": "min_assets",
            "in": "query",
            "required": false,
            "schema": { "type": "number", "example": 1000000000 }
          },
          {
            "name": "max_assets",
            "in": "query",
            "required": false,
            "schema": { "type": "number", "example": 10000000000 }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["assets", "members", "name", "net_worth_ratio", "return_on_assets", "delinquency", "loan_to_share"],
              "default": "assets"
            }
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 0, "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "Institution list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstitutionListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Query-string API key rejected"
          },
          "401": {
            "description": "Missing bearer API key"
          },
          "403": {
            "description": "Invalid, revoked, or non-data_access key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/cuwiredata-institution": {
      "get": {
        "summary": "Return one current institution profile",
        "description": "Returns one promoted-period institution profile with readable field names, balances, ratios, named benchmark percentiles, capitalization classification, branch summary, and compact history.",
        "operationId": "getCuWireDataInstitution",
        "parameters": [
          {
            "name": "charter",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "pattern": "^\\d+$", "example": "66310" },
            "description": "NCUA charter number."
          }
        ],
        "responses": {
          "200": {
            "description": "Institution profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstitutionDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing charter or query-string API key rejected"
          },
          "401": {
            "description": "Missing bearer API key"
          },
          "403": {
            "description": "Invalid, revoked, or non-data_access key"
          },
          "404": {
            "description": "Institution was not found"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "CUWIREDATA_API_KEY",
        "description": "Send as Authorization: Bearer <CUWIREDATA_API_KEY>. Keys must have tier data_access."
      }
    },
    "schemas": {
      "DataFeedManifestResponse": {
        "type": "object",
        "required": ["ok", "trace_id", "data"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "trace_id": { "type": "string" },
          "data": {
            "type": "object",
            "required": ["product", "period", "coverage", "files", "api", "archive"],
            "properties": {
              "product": { "type": "string", "example": "CU Wire Quarterly Data Feed" },
              "package_version": { "type": "integer", "example": 1 },
              "generated_at": { "type": "string", "format": "date-time" },
              "period": { "type": "string", "example": "2026-Q1" },
              "cycle_date": { "type": "string", "format": "date", "example": "2026-03-31" },
              "coverage": { "type": "object" },
              "files": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/DataFeedFile" }
              },
              "api": { "type": "object" },
              "archive": { "type": "object" }
            },
            "additionalProperties": true
          }
        }
      },
      "DataFeedFile": {
        "type": "object",
        "required": ["path", "rows", "bytes", "sha256", "href"],
        "properties": {
          "path": { "type": "string", "example": "institutions.csv" },
          "rows": { "type": "integer", "minimum": 0 },
          "bytes": { "type": "integer", "minimum": 0 },
          "sha256": { "type": "string" },
          "href": { "type": "string" }
        },
        "additionalProperties": true
      },
      "SummaryResponse": {
        "type": "object",
        "required": ["ok", "trace_id", "data"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "trace_id": { "type": "string" },
          "data": {
            "type": "object",
            "required": ["period", "source"],
            "properties": {
              "period": { "type": "string", "example": "2026-Q1" },
              "as_of_date": { "type": "string", "format": "date" },
              "total_credit_unions": { "type": "integer" },
              "total_assets_usd": { "type": "number" },
              "total_loans_usd": { "type": "number" },
              "total_shares_usd": { "type": "number" },
              "total_members": { "type": "integer" },
              "source": { "type": "string", "example": "ncua_call_report" }
            },
            "additionalProperties": false
          }
        }
      },
      "InstitutionListResponse": {
        "type": "object",
        "required": ["ok", "trace_id", "data"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "trace_id": { "type": "string" },
          "data": {
            "type": "object",
            "required": ["period", "source", "total", "limit", "offset", "results"],
            "properties": {
              "period": { "type": "string", "example": "2026-Q1" },
              "as_of_date": { "type": "string", "format": "date" },
              "source": { "type": "string", "example": "ncua_call_report" },
              "total": { "type": "integer" },
              "limit": { "type": "integer" },
              "offset": { "type": "integer" },
              "results": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/InstitutionListItem" }
              }
            }
          }
        }
      },
      "InstitutionListItem": {
        "type": "object",
        "properties": {
          "charter": { "type": "string", "example": "66310" },
          "name": { "type": "string", "example": "STATE EMPLOYEES'" },
          "city": { "type": "string", "example": "RALEIGH" },
          "state": { "type": "string", "example": "NC" },
          "charter_type": { "type": "string", "example": "State" },
          "asset_tier": { "type": "string", "example": "mega" },
          "asset_tier_label": { "type": "string", "example": "$10B+" },
          "assets_usd": { "type": "number", "example": 59758618263 },
          "members": { "type": "integer", "example": 2978851 },
          "net_worth_ratio_pct": { "type": "number", "example": 9.98 },
          "return_on_assets_pct": { "type": "number", "example": 0.64 },
          "delinquency_ratio_pct": { "type": "number", "example": 1.44 },
          "loan_to_share_ratio_pct": { "type": "number", "example": 71.08 },
          "health": { "type": "string", "example": "healthy" },
          "website": { "type": "string", "example": "http://www.ncsecu.org" },
          "period": { "type": "string", "example": "2026-Q1" },
          "as_of_date": { "type": "string", "format": "date" },
          "source": { "type": "string", "example": "ncua_call_report" },
          "profile_url": { "type": "string", "example": "/credit-unions/state-employees-66310" },
          "app_url": { "type": "string", "example": "/institution.html?cu=66310" }
        },
        "additionalProperties": false
      },
      "InstitutionDetailResponse": {
        "type": "object",
        "required": ["ok", "trace_id", "data"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "trace_id": { "type": "string" },
          "data": {
            "type": "object",
            "required": ["institution", "balances", "performance", "ratios", "ratio_benchmarks", "branches", "history"],
            "properties": {
              "institution": { "type": "object" },
              "balances": { "type": "object" },
              "performance": { "type": "object" },
              "ratios": { "type": "object" },
              "capitalization": { "type": ["object", "null"] },
              "ratio_benchmarks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": { "type": "string", "example": "net_worth_ratio" },
                    "label": { "type": "string", "example": "Net Worth Ratio" },
                    "category": { "type": "string", "example": "capital_adequacy" },
                    "source_key": { "type": "string", "example": "nwr" },
                    "value": { "type": "number", "example": 9.98 },
                    "percentile": { "type": "number", "example": 44 }
                  },
                  "additionalProperties": false
                }
              },
              "branches": { "type": "object" },
              "history": {
                "type": "array",
                "items": { "type": "object" }
              }
            },
            "additionalProperties": false
          }
        }
      }
    }
  }
}
