{
  "openapi": "3.0.3",
  "info": {
    "title": "InnoBee Public API",
    "version": "1.0.0",
    "description": "Read-only public API for InnoBee (Phase 4, Week 23-24). Bearer-token authenticated via API keys issued from Account Settings \u2192 Login. Flat rate limit of 60 requests/minute per key.",
    "contact": { "email": "support@innobee.buzz" }
  },
  "servers": [{ "url": "https://innobee.buzz" }],
  "security": [{ "ApiKeyAuth": [] }],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "ib_live_...",
        "description": "Create a key from /account/settings/login. Send as 'Authorization: Bearer ib_live_...'."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "example": "UNAUTHORIZED" },
              "message": { "type": "string" }
            }
          }
        }
      },
      "Creator": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "username": { "type": "string" },
          "display_name": { "type": "string" },
          "avatar_url": { "type": "string", "nullable": true },
          "is_verified": { "type": "boolean" },
          "tier": { "type": "string" }
        }
      },
      "Challenge": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "tagline": { "type": "string", "nullable": true },
          "cover_url": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true },
          "tags": { "type": "array", "items": { "type": "string" } },
          "difficulty": { "type": "string" },
          "status": { "type": "string" },
          "opens_at": { "type": "string", "format": "date-time", "nullable": true },
          "closes_at": { "type": "string", "format": "date-time", "nullable": true },
          "results_at": { "type": "string", "format": "date-time", "nullable": true },
          "prize_pool_total": { "type": "number" },
          "prize_currency": { "type": "string" },
          "prize_type": { "type": "string" },
          "participant_count": { "type": "integer" },
          "submission_count": { "type": "integer" },
          "view_count": { "type": "integer" },
          "like_count": { "type": "integer" },
          "is_featured": { "type": "boolean" },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "creator": { "$ref": "#/components/schemas/Creator" }
        }
      },
      "Submission": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "summary": { "type": "string", "nullable": true },
          "cover_url": { "type": "string", "nullable": true },
          "video_url": { "type": "string", "nullable": true },
          "external_url": { "type": "string", "nullable": true },
          "status": { "type": "string" },
          "average_score": { "type": "number", "nullable": true },
          "rank": { "type": "integer", "nullable": true },
          "prize_tier": { "type": "string", "nullable": true },
          "submitted_at": { "type": "string", "format": "date-time", "nullable": true },
          "view_count": { "type": "integer" },
          "like_count": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "submitter": { "$ref": "#/components/schemas/Creator" }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "username": { "type": "string" },
          "display_name": { "type": "string" },
          "bio": { "type": "string", "nullable": true },
          "headline": { "type": "string", "nullable": true },
          "avatar_url": { "type": "string", "nullable": true },
          "cover_url": { "type": "string", "nullable": true },
          "country": { "type": "string", "nullable": true },
          "website_url": { "type": "string", "nullable": true },
          "linkedin_url": { "type": "string", "nullable": true },
          "github_url": { "type": "string", "nullable": true },
          "twitter_url": { "type": "string", "nullable": true },
          "primary_role": { "type": "string" },
          "tier": { "type": "string" },
          "hive_score": { "type": "integer" },
          "challenges_created": { "type": "integer" },
          "challenges_won": { "type": "integer" },
          "challenges_joined": { "type": "integer" },
          "is_verified": { "type": "boolean" },
          "skills": { "type": "array", "items": { "type": "string" } },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "LeaderboardRow": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "username": { "type": "string" },
          "display_name": { "type": "string" },
          "avatar_url": { "type": "string", "nullable": true },
          "tier": { "type": "string" },
          "score": { "type": "number" }
        }
      },
      "PageMeta": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page": { "type": "integer" },
          "limit": { "type": "integer" },
          "hasMore": { "type": "boolean" }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, malformed, or revoked API key.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource not found or not publicly visible.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "RateLimited": {
        "description": "More than 60 requests/minute for this key.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  },
  "paths": {
    "/api/v1/challenges": {
      "get": {
        "summary": "List public challenges",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 50 } }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "data": { "type": "array", "items": { "$ref": "#/components/schemas/Challenge" } },
              "meta": { "$ref": "#/components/schemas/PageMeta" }
            } } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/challenges/{slug}": {
      "get": {
        "summary": "Get a public challenge by slug",
        "parameters": [{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "data": { "$ref": "#/components/schemas/Challenge" }
            } } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/challenges/{slug}/submissions": {
      "get": {
        "summary": "List a challenge's public submissions",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 50 } }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "data": { "type": "array", "items": { "$ref": "#/components/schemas/Submission" } },
              "meta": { "$ref": "#/components/schemas/PageMeta" }
            } } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/profiles/{username}": {
      "get": {
        "summary": "Get a public profile by username",
        "parameters": [{ "name": "username", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "data": { "$ref": "#/components/schemas/Profile" }
            } } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/leaderboard": {
      "get": {
        "summary": "Get the Hive Score leaderboard",
        "parameters": [{ "name": "period", "in": "query", "schema": { "type": "string", "enum": ["all", "weekly", "learning"], "default": "all" } }],
        "responses": {
          "200": {
            "description": "OK",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "data": { "type": "array", "items": { "$ref": "#/components/schemas/LeaderboardRow" } }
            } } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "422": { "description": "Invalid period" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  }
}
