{
  "openapi": "3.1.0",
  "info": {
    "title": "Claim outcome data API",
    "version": "0.1.0",
    "description": "Outcome rates of flight-compensation cases per German court, extracted from published decisions. Source: Open Legal Data (de.openlegaldata.io), ODbL. Statistics from published decisions, not legal advice and not a prediction for an individual claim.",
    "license": { "name": "ODbL-1.0 (data)", "url": "https://opendatacommons.org/licenses/odbl/1-0/" }
  },
  "servers": [{ "url": "https://claim-pricing.vitersoft.com" }],
  "security": [{ "apiKey": [] }],
  "paths": {
    "/score": {
      "get": {
        "summary": "Outcome rates for a court, an airline, or the pair",
        "parameters": [
          { "name": "court", "in": "query", "schema": { "type": "string" }, "example": "ag-koeln", "description": "Court slug from /courts, case-insensitive." },
          { "name": "airline", "in": "query", "schema": { "type": "string" }, "example": "eurowings", "description": "Airline slug from /airlines, case-insensitive." }
        ],
        "responses": {
          "200": {
            "description": "Rates, or insufficient data when fewer than 10 cases are decided.",
            "content": { "application/json": { "schema": { "oneOf": [{ "$ref": "#/components/schemas/Score" }, { "$ref": "#/components/schemas/InsufficientData" }] } } }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "404": {
            "description": "Unknown slug, with the closest valid slugs.",
            "content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/Error" }, { "type": "object", "properties": { "suggestions": { "type": "array", "items": { "type": "string" } } } }] } } }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/courts": {
      "get": {
        "summary": "Valid court slugs",
        "responses": {
          "200": {
            "description": "Courts with the number of decisions.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "courts": { "type": "array", "items": { "type": "object", "properties": { "slug": { "type": "string" }, "name": { "type": "string" }, "level": { "type": "string", "enum": ["AG", "LG", "OLG", "BGH", "other"] }, "n_total": { "type": "integer" } } } }, "source": { "type": "string" } } } } }
          },
          "401": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/airlines": {
      "get": {
        "summary": "Valid airline slugs",
        "responses": {
          "200": {
            "description": "Airlines with the number of decisions that name them as defendant.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "airlines": { "type": "array", "items": { "type": "object", "properties": { "slug": { "type": "string" }, "name": { "type": "string" }, "n_total": { "type": "integer" } } } }, "source": { "type": "string" } } } } }
          },
          "401": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Service status and data version",
        "security": [],
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "const": "ok" }, "pipeline_version": { "type": "string" }, "dump": { "type": "string" }, "cases": { "type": "integer" } } } } } } }
      }
    }
  },
  "components": {
    "securitySchemes": { "apiKey": { "type": "apiKey", "in": "header", "name": "X-API-Key" } },
    "schemas": {
      "Score": {
        "type": "object",
        "required": ["airline", "court", "n_total", "n_decided", "share_claimant_success", "share_dismissed", "share_default_or_ack", "median_duration_days", "n_with_dates", "median_amount_eur", "date_range", "caveats", "source"],
        "properties": {
          "airline": { "type": ["string", "null"] },
          "court": { "type": ["string", "null"] },
          "n_total": { "type": "integer" },
          "n_decided": { "type": "integer", "description": "Cases whose winning side is known." },
          "share_claimant_success": { "type": "number", "minimum": 0, "maximum": 1 },
          "share_dismissed": { "type": "number", "minimum": 0, "maximum": 1 },
          "share_default_or_ack": { "type": "number", "minimum": 0, "maximum": 1 },
          "median_duration_days": { "type": ["integer", "null"], "description": "Filing to decision; null below 5 cases with both dates." },
          "n_with_dates": { "type": "integer" },
          "median_amount_eur": { "type": ["integer", "null"] },
          "date_range": { "type": "array", "items": { "type": "string", "format": "date" }, "minItems": 2, "maxItems": 2 },
          "caveats": { "type": "array", "items": { "type": "string" } },
          "source": { "type": "string" }
        }
      },
      "InsufficientData": {
        "type": "object",
        "required": ["status", "n_decided", "source"],
        "properties": {
          "status": { "const": "insufficient_data" },
          "airline": { "type": ["string", "null"] },
          "court": { "type": ["string", "null"] },
          "n_total": { "type": "integer" },
          "n_decided": { "type": "integer" },
          "min_n_decided": { "type": "integer" },
          "caveats": { "type": "array", "items": { "type": "string" } },
          "source": { "type": "string" }
        }
      },
      "Error": { "type": "object", "required": ["error", "message"], "properties": { "error": { "type": "string" }, "message": { "type": "string" } } }
    },
    "responses": {
      "Error": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "More than 60 requests per minute for this key.", "headers": { "Retry-After": { "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
