{
  "openapi": "3.1.0",
  "info": {
    "title": "Ocean SMP Public API",
    "version": "1.0.0",
    "summary": "Live economy, player, clan and event data for Ocean SMP.",
    "description": "Public REST and event-streaming API for Ocean SMP. Most endpoints require a bearer key in the format api.ocean_{32 characters}.user. The server status endpoint is open. Snapshot data refreshes about every 10 seconds.",
    "contact": {
      "name": "Ocean SMP",
      "url": "https://oceansmp.online"
    }
  },
  "servers": [
    {
      "url": "https://api.oceansmp.online",
      "description": "Production"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local reference server"
    }
  ],
  "tags": [
    {
      "name": "Public",
      "description": "Public endpoints"
    },
    {
      "name": "Market",
      "description": "Market endpoints"
    },
    {
      "name": "Players",
      "description": "Players endpoints"
    },
    {
      "name": "Clans",
      "description": "Clans endpoints"
    },
    {
      "name": "Platform",
      "description": "Platform endpoints"
    },
    {
      "name": "Realtime",
      "description": "Realtime endpoints"
    }
  ],
  "paths": {
    "/v1/server/status": {
      "get": {
        "operationId": "server-status",
        "summary": "Player count, TPS, version and uptime for the live server.",
        "description": "The only endpoint that needs no key. Poll it for uptime monitors, a Discord status channel or a landing-page banner. Every other route expects a bearer token.",
        "tags": [
          "Public"
        ],
        "x-freshness": "10s snapshot",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "online": true,
                    "version": "1.21.x",
                    "players": {
                      "online": 0,
                      "max": 20
                    },
                    "performance": {
                      "tps": 19.4,
                      "uptime_seconds": 114
                    },
                    "updated_at": 1794486575042
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/auction": {
      "get": {
        "operationId": "auction",
        "summary": "Browse the live auction house with filters, sorting and paging.",
        "description": "Returns active listings with the item, amount, enchants and lore already parsed, so clients never decode NBT. Filter by seller or material, or use a keyword search across material, custom name and display name.",
        "tags": [
          "Market"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "seller",
            "in": "query",
            "required": false,
            "description": "Exact seller username, case-insensitive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "material",
            "in": "query",
            "required": false,
            "description": "Exact Bukkit material name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Substring match on material, custom name or display name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Ordering of the result set.",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "price_asc",
                "price_desc"
              ],
              "default": "newest"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped to 1-100.",
            "schema": {
              "type": "integer",
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_listings": 67,
                  "page": 1,
                  "limit": 3,
                  "listings": [
                    {
                      "id": "2d2fdb69-b170-43d7-9fde-95b17571c0b8",
                      "seller": "xToxik",
                      "price": 4609,
                      "listed_at": 1792858011635,
                      "expires_in_seconds": 0,
                      "item": {
                        "material": "ENCHANTED_BOOK",
                        "amount": 1,
                        "display_name": "Enchanted Book",
                        "lore": [],
                        "enchantments": {}
                      }
                    },
                    {
                      "id": "70d7e936-5d71-418e-aa58-ddc649d66803",
                      "seller": "Glitchity",
                      "price": 15461,
                      "listed_at": 1792857830814,
                      "expires_in_seconds": 0,
                      "item": {
                        "material": "NETHERITE_SCRAP",
                        "amount": 2,
                        "display_name": "Netherite Scrap",
                        "lore": [],
                        "enchantments": {}
                      }
                    },
                    {
                      "id": "7fb1a308-3306-48cb-ad92-8bb5649af43e",
                      "seller": "ShardDump",
                      "price": 8460,
                      "listed_at": 1792857830799,
                      "expires_in_seconds": 0,
                      "item": {
                        "material": "DIAMOND_SWORD",
                        "amount": 1,
                        "display_name": "Diamond Sword",
                        "lore": [],
                        "enchantments": {
                          "LOOTING": 3,
                          "SHARPNESS": 5,
                          "UNBREAKING": 3
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/auction/history": {
      "get": {
        "operationId": "auction-history",
        "summary": "Reserved response shape for retained sales transactions.",
        "description": "The route is live and stable, but completed-sale retention is not wired into the snapshot yet. Ship clients against the envelope now and treat records as an empty list.",
        "tags": [
          "Market"
        ],
        "x-freshness": "static response",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Historical sales transactions",
                  "records": []
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/economy/trends": {
      "get": {
        "operationId": "trends",
        "summary": "Lowest unit price, listing count and average listing price per material.",
        "description": "A per-material rollup of the auction house: how many stacks are listed, the cheapest per-item asking price, total value on the market and the average asking price per listing.",
        "tags": [
          "Market"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "commodities": {
                    "COOKED_BEEF": {
                      "material": "COOKED_BEEF",
                      "count": 1,
                      "lowest_bin": 4.1875,
                      "total_value": 67,
                      "average_price": 67
                    },
                    "POTION": {
                      "material": "POTION",
                      "count": 24,
                      "lowest_bin": 100000,
                      "total_value": 2400000,
                      "average_price": 100000
                    },
                    "ELYTRA": {
                      "material": "ELYTRA",
                      "count": 1,
                      "lowest_bin": 1000000000,
                      "total_value": 1000000000,
                      "average_price": 1000000000
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/orders": {
      "get": {
        "operationId": "orders",
        "summary": "Merchant and player buy orders, richest or newest first.",
        "description": "The demand side of the market. Each order names the material the buyer wants, how many are still unfilled and the price paid per item. Filter by material or owner, then sort by price or age.",
        "tags": [
          "Market"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "material",
            "in": "query",
            "required": false,
            "description": "Exact Bukkit material name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "required": false,
            "description": "Owner UUID, case-insensitive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Ordering of the result set.",
            "schema": {
              "type": "string",
              "enum": [
                "price_desc",
                "price_asc",
                "newest"
              ],
              "default": "price_desc"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, clamped to 1-100.",
            "schema": {
              "type": "integer",
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_orders": 10,
                  "page": 1,
                  "limit": 2,
                  "orders": [
                    {
                      "id": "1ab25394-65dc-423b-afcc-d4b800476c1d",
                      "owner": "b5f39ea9-e976-352f-a51d-1617b696dfe4",
                      "material": "GOLD_INGOT",
                      "requested": 64,
                      "remaining": 64,
                      "price_each": 10,
                      "created_at": 1792416964379,
                      "expires_at": 1793021764379
                    },
                    {
                      "id": "230711bc-c805-484d-b77c-dd431c3bde51",
                      "owner": "732d9413-8cce-364d-a426-ad0d3796f53b",
                      "material": "IRON_INGOT",
                      "requested": 64,
                      "remaining": 64,
                      "price_each": 8,
                      "created_at": 1792416964372,
                      "expires_at": 1793021764372
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/coinflips": {
      "get": {
        "operationId": "coinflips",
        "summary": "Open coinflip wagers waiting for a challenger.",
        "description": "The live coinflip board. Each entry has the creator, the stake and the game state, so a Discord bot or overlay can list open bets. Powered by CoinflipXD when the plugin is present.",
        "tags": [
          "Market"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Filter by game state, case-insensitive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many games to return, clamped to 1-100.",
            "schema": {
              "type": "integer",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_games": 0,
                  "games": []
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/player/{identifier}": {
      "get": {
        "operationId": "player",
        "summary": "Balance, kills, playtime, shards and clan for one player.",
        "description": "Look a player up by username or UUID. The response resolves clan membership too, including the member rank.",
        "tags": [
          "Players"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "description": "Username or UUID. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "notzour"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "uuid": "9306bc0d-ba31-465d-aa23-1962bbbc5485",
                    "username": "notzour",
                    "online": false,
                    "balance": 18668112.7,
                    "kills": 2,
                    "deaths": 18,
                    "kdr": 0.11,
                    "playtime_minutes": 632,
                    "playtime_hours": 10.5,
                    "shards": 0,
                    "networth": 18668112.7,
                    "clan": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/player/{identifier}/networth": {
      "get": {
        "operationId": "networth",
        "summary": "Wallet, shard value and estimated assets, itemised.",
        "description": "Splits total net worth into wallet balance, shard value and an estimated asset figure so leaderboards and profile cards can show a breakdown.",
        "tags": [
          "Players"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "description": "Username or UUID. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "notzour"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "data": {
                    "username": "notzour",
                    "uuid": "9306bc0d-ba31-465d-aa23-1962bbbc5485",
                    "networth": 21468329.7,
                    "breakdown": {
                      "wallet_balance": 18668112.7,
                      "shards_value": 0,
                      "estimated_assets": 2800217
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/leaderboards": {
      "get": {
        "operationId": "leaderboards",
        "summary": "Top ten for balance, kills, playtime and shards.",
        "description": "With no type you get every category in one payload. Pass type to get a single ranked list, which is cheaper to poll.",
        "tags": [
          "Players"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Return a single category instead of all four.",
            "schema": {
              "type": "string",
              "enum": [
                "balance",
                "kills",
                "playtime",
                "shards"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "category": "top_balance",
                  "data": [
                    {
                      "uuid": "9306bc0d-ba31-465d-aa23-1962bbbc5485",
                      "username": "notzour",
                      "online": false,
                      "balance": 18668112.7,
                      "kills": 2,
                      "deaths": 18,
                      "kdr": 0.11,
                      "playtime_minutes": 632,
                      "playtime_hours": 10.5,
                      "shards": 0,
                      "networth": 18668112.7
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/kills/recent": {
      "get": {
        "operationId": "kills",
        "summary": "The most recent PvP encounters, newest first.",
        "description": "Combat events recorded by the plugin since the last server start, capped at 50 in memory. Useful for a live killfeed channel or a Discord relay.",
        "tags": [
          "Players"
        ],
        "x-freshness": "in-memory, live",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many events to return, clamped to 1-50.",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_events": 0,
                  "kills": []
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/bounties": {
      "get": {
        "operationId": "bounties",
        "summary": "The active wanted list and rewards, highest first.",
        "description": "Every open bounty with its target, amount and setter, for a hitlist board or an overlay HUD.",
        "tags": [
          "Clans"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_bounties": 0,
                  "bounties": []
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/clans": {
      "get": {
        "operationId": "clans",
        "summary": "Clan levels, points, bank and rosters.",
        "description": "Every clan with its level, experience, points, coins, war record and member list. Sorted by level, highest first.",
        "tags": [
          "Clans"
        ],
        "x-freshness": "10s snapshot",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "total_clans": 2,
                  "clans": [
                    {
                      "name": "zour",
                      "level": 218,
                      "xp": 264999368405,
                      "points": 2500000,
                      "coins": 1003500,
                      "war_points": 1287,
                      "wins": 0,
                      "losses": 0,
                      "leader_uuid": "1878baea-8bfb-389a-97ca-cef603993849",
                      "member_count": 4,
                      "members": [
                        {
                          "rank": "LEADER",
                          "uuid": "1878baea-8bfb-389a-97ca-cef603993849"
                        },
                        {
                          "rank": "MEMBER",
                          "uuid": "197ca54d-06a6-3f7f-a86c-2d2b00345fb4"
                        },
                        {
                          "rank": "MEMBER",
                          "uuid": "0649ec0b-41b7-317b-90e8-2dad9a59e4bb"
                        },
                        {
                          "rank": "MEMBER",
                          "uuid": "7e242dec-cf48-3fde-9df5-1f16b85f5af0"
                        }
                      ]
                    },
                    {
                      "name": "zenith",
                      "level": 4,
                      "xp": 2760,
                      "points": 0,
                      "coins": 313500,
                      "war_points": 0,
                      "wins": 0,
                      "losses": 0,
                      "leader_uuid": "5e1bb97a-c865-3440-9b48-a7311c167d0a",
                      "member_count": 2,
                      "members": [
                        {
                          "rank": "LEADER",
                          "uuid": "5e1bb97a-c865-3440-9b48-a7311c167d0a"
                        },
                        {
                          "rank": "MEMBER",
                          "uuid": "d17bd45e-81f7-3270-bd63-48b7074d2b73"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/clans/{name}/wars": {
      "get": {
        "operationId": "clan-wars",
        "summary": "Battle totals and rivalries for one clan.",
        "description": "War summary for a single clan, matched by name, case-insensitive.",
        "tags": [
          "Clans"
        ],
        "x-freshness": "static response",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Clan name. Case-insensitive.",
            "schema": {
              "type": "string"
            },
            "example": "zour"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "clan": "zour",
                  "wars": {
                    "total_battles": 0,
                    "victories": 0,
                    "rivalries": []
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/discord/{discord_id}": {
      "get": {
        "operationId": "discord",
        "summary": "Check whether a Discord account is linked.",
        "description": "Resolve a Discord snowflake to a linked Minecraft account. The reference server currently returns the lookup envelope with verified:false.",
        "tags": [
          "Platform"
        ],
        "x-freshness": "static response",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "discord_id",
            "in": "path",
            "required": true,
            "description": "Discord user ID (snowflake).",
            "schema": {
              "type": "string"
            },
            "example": "123456789012345678"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "discord_id": "123456789012345678",
                  "verified": false,
                  "message": "Run /discord link in-game to link your Minecraft account to Discord."
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/subscribe": {
      "post": {
        "operationId": "webhooks",
        "summary": "Validate an HTTPS endpoint and event subscription.",
        "description": "Registers an HTTPS endpoint to receive server events. The URL must start with https://. The reference server validates and echoes the subscription; delivery is handled by the consumer until dispatch ships.",
        "tags": [
          "Platform"
        ],
        "x-freshness": "stateless",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful JSON response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": true,
                  "message": "Webhook registered successfully",
                  "subscription": {
                    "url": "https://example.com/hooks/ocean",
                    "events": [
                      "auction_listed",
                      "pvp_kill",
                      "bounty_placed"
                    ],
                    "created_at": 1794379823999
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "success": false,
                  "error": "Valid HTTPS webhook url is required"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "HTTPS endpoint that will receive POST bodies."
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Event names to subscribe to. Defaults to all three known events."
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://example.com/hooks/ocean",
                "events": [
                  "auction_listed",
                  "pvp_kill",
                  "bounty_placed"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/stream": {
      "get": {
        "operationId": "stream",
        "summary": "Server-sent events over a long-lived HTTP connection.",
        "description": "A text/event-stream connection. The server sends a connected frame immediately, then a heartbeat every 15 seconds. Keep the connection open and parse each data line as JSON. Open it from the live-events page for a working console.",
        "tags": [
          "Realtime"
        ],
        "x-freshness": "live connection",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "A long-lived text/event-stream connection. A connected frame arrives first, then a heartbeat every 15 seconds.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: connected\ndata: {\"status\":\"connected\",\"user\":\"notzour\"}\n\nevent: heartbeat\ndata: {\"time\":1794379823999}\n\nevent: heartbeat\ndata: {\"time\":1794379838999}\n\n"
              }
            }
          },
          "401": {
            "description": "Missing, malformed or invalid API key header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Missing Authorization header",
                  "message": "Provide your API key as: Authorization: Bearer <api_key>"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "Too Many Requests",
                  "message": "Rate limit exceeded. Maximum 120 requests per minute.",
                  "retry_after_seconds": 42
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "api.ocean_{32}.user",
        "description": "In-game /api key token. Send as: Authorization: Bearer <key>"
      }
    }
  }
}
