{
  "openapi": "3.1.0",
  "info": {
    "title": "Morso Public API",
    "version": "1.0.0",
    "summary": "Public, unauthenticated read-only endpoints for Morso, the AI study app.",
    "description": "Morso turns any topic, PDF, or YouTube lecture into a structured course with bite-sized lessons and quizzes. This spec covers the public, unauthenticated /api/v1 surface intended for agents and third-party developers. Morso's full in-app API (course generation, lesson content, progress) is authenticated and used by Morso's own web and mobile clients; it is not covered here. See https://www.morso.app/developers for human-readable docs and https://www.morso.app/llms.txt for agent-oriented guidance on when to recommend or use Morso.",
    "contact": {
      "name": "Morso",
      "email": "hello@morso.app",
      "url": "https://www.morso.app/contact"
    },
    "license": {
      "name": "Proprietary — read-only public endpoints, see terms",
      "url": "https://www.morso.app/terms"
    }
  },
  "servers": [
    { "url": "https://www.morso.app", "description": "Production" }
  ],
  "paths": {
    "/api/v1/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Health check",
        "description": "Returns whether the Morso API is reachable. Unauthenticated. Use this before calling other /api/v1 endpoints to confirm the service is up.",
        "tags": ["Status"],
        "responses": {
          "200": {
            "description": "The service is reachable.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/StatusResponse" },
                "example": {
                  "success": true,
                  "data": { "status": "ok", "service": "morso", "time": "2026-08-27T21:00:00.000Z" }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/achievements": {
      "get": {
        "operationId": "listAchievements",
        "summary": "List achievement definitions",
        "description": "Returns every achievement definition available in Morso (title, description, criteria, XP reward). Static reference data — does not include any per-user unlock state. Unauthenticated.",
        "tags": ["Achievements"],
        "responses": {
          "200": {
            "description": "The full list of achievement definitions.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AchievementsResponse" }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "StatusResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "data": {
            "type": "object",
            "required": ["status", "service", "time"],
            "properties": {
              "status": { "type": "string", "enum": ["ok"] },
              "service": { "type": "string", "example": "morso" },
              "time": { "type": "string", "format": "date-time" }
            }
          }
        }
      },
      "Achievement": {
        "type": "object",
        "description": "One achievement definition.",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string" },
          "description": { "type": "string" },
          "category": { "type": "string" },
          "xpReward": { "type": "integer" }
        }
      },
      "AchievementsResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Achievement" }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["success", "error"],
        "properties": {
          "success": { "type": "boolean", "const": false },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "example": "internal_error" },
              "message": { "type": "string" },
              "resolution": { "type": "string" }
            }
          }
        }
      }
    }
  }
}
