{
  "openapi": "3.1.0",
  "info": {
    "title": "Slidz.io Public Developer API",
    "version": "v1.0.0",
    "description": "Programmatic access to atomic PowerPoint presentation deconstruction, hybrid pgvector semantic search, and slide asset distribution. Requires an active ELITE or ENTERPRISE subscription.",
    "contact": {
      "name": "Slidz.io Developer Support",
      "email": "developers@slidz.io",
      "url": "https://www.slidz.io/api/"
    },
    "license": {
      "name": "Commercial",
      "url": "https://www.slidz.io/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.slidz.io",
      "description": "Production API Server"
    },
    {
      "url": "https://api.dev.slidz.io",
      "description": "Staging Sandbox Server"
    },
    {
      "url": "http://localhost:8080",
      "description": "Local Development Server"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/api/v1/public/presentations": {
      "get": {
        "tags": ["Presentations"],
        "summary": "Search & list presentations",
        "description": "Returns a paginated list of PowerPoint presentations belonging to the authenticated tenant workspace with optional title text query.",
        "operationId": "listPresentations",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Filter by presentation title keyword",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "Page size limit (1 to 100)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presentations retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicPresentationDto"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitExceeded"
          }
        }
      }
    },
    "/api/v1/public/presentations/{id}": {
      "get": {
        "tags": ["Presentations"],
        "summary": "Get presentation details",
        "description": "Retrieves comprehensive presentation metadata along with the ordered sequence of its deconstructed atomic slides.",
        "operationId": "getPresentation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Presentation UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presentation details retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicPresentationDetailDto"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/public/presentations/upload": {
      "post": {
        "tags": ["Presentations"],
        "summary": "Upload presentation (.pptx)",
        "description": "Uploads a PowerPoint .pptx file for asynchronous atomic slide deconstruction, thumbnail rendering, and pgvector embeddings. Returns 202 Accepted with a status tracking URL.",
        "operationId": "uploadPresentation",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "PowerPoint presentation file (.pptx)"
                  },
                  "title": {
                    "type": "string",
                    "description": "Custom presentation title (defaults to filename)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Presentation accepted for asynchronous processing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicUploadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "413": {
            "description": "File size exceeds tier maximum upload limit (250 MB for Elite, 500 MB for Enterprise)"
          }
        }
      }
    },
    "/api/v1/public/presentations/{id}/status": {
      "get": {
        "tags": ["Presentations"],
        "summary": "Check presentation processing status",
        "description": "Polls the asynchronous deconstruction and indexing progress of an uploaded presentation.",
        "operationId": "getPresentationStatus",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Presentation UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Processing status retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicPresentationStatusDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/presentations/{id}/download": {
      "get": {
        "tags": ["Presentations"],
        "summary": "Download presentation",
        "description": "Streams the full assembled presentation in .pptx or .pdf format.",
        "operationId": "downloadPresentation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "Output format ('pptx' or 'pdf')",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["pptx", "pdf"],
              "default": "pptx"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presentation file binary stream",
            "content": {
              "application/vnd.openxmlformats-officedocument.presentationml.presentation": {},
              "application/pdf": {}
            }
          }
        }
      }
    },
    "/api/v1/public/presentations/{id}/thumbnail": {
      "get": {
        "tags": ["Presentations"],
        "summary": "Get presentation cover thumbnail",
        "description": "Streams the presentation cover image in PNG format.",
        "operationId": "getPresentationThumbnail",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PNG image data",
            "content": {
              "image/png": {}
            }
          }
        }
      }
    },
    "/api/v1/public/slides/search": {
      "get": {
        "tags": ["Atomic Slides"],
        "summary": "Search atomic slides",
        "description": "Performs hybrid semantic vector and text search across the tenant slide library.",
        "operationId": "searchSlides",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search query concept or text",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "layout",
            "in": "query",
            "description": "Filter by slide layout taxonomy (TITLE, TWO_COLUMN, METRICS, TIMELINE, etc.)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results to return (1-50)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search hits returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSearchResultDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/slides/{id}": {
      "get": {
        "tags": ["Atomic Slides"],
        "summary": "Get slide details",
        "description": "Retrieves extracted text, speaker notes, aspect ratio, and metadata for an atomic slide.",
        "operationId": "getSlide",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Slide details retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSlideDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/slides/{id}/download": {
      "get": {
        "tags": ["Atomic Slides"],
        "summary": "Download standalone slide (.pptx)",
        "description": "Downloads an individual atomic slide as a standalone single-slide PowerPoint presentation.",
        "operationId": "downloadSlide",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Standalone single-slide .pptx binary stream",
            "content": {
              "application/vnd.openxmlformats-officedocument.presentationml.presentation": {}
            }
          }
        }
      }
    },
    "/api/v1/public/slides/{id}/thumbnail": {
      "get": {
        "tags": ["Atomic Slides"],
        "summary": "Get slide preview thumbnail",
        "description": "Streams the high-resolution PNG thumbnail image of the atomic slide.",
        "operationId": "getSlideThumbnail",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PNG image data",
            "content": {
              "image/png": {}
            }
          }
        }
      }
    },
    "/api/v1/public/slides/upload-single": {
      "post": {
        "tags": ["Atomic Slides"],
        "summary": "Upload standalone single slide",
        "description": "Uploads a single slide .pptx file directly into the tenant catalog.",
        "operationId": "uploadSingleSlide",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Single-slide .pptx file"
                  },
                  "title": {
                    "type": "string",
                    "description": "Optional slide title"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Slide created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicSlideDto"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/me": {
      "get": {
        "tags": ["Account & Quotas"],
        "summary": "Get workspace API usage & quota",
        "description": "Returns current tenant metadata, tier, sliding rate limits, and monthly quota usage.",
        "operationId": "getAccountUsage",
        "responses": {
          "200": {
            "description": "Workspace account and quota details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicAccountUsageDto"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "name": "X-API-KEY",
        "in": "header",
        "description": "API Key token (e.g. `slidz_live_...`)"
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT authentication for workspace administration"
      }
    },
    "schemas": {
      "PublicPresentationDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "teamId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "slideCount": {
            "type": "integer"
          },
          "aspectRatio": {
            "type": "string",
            "example": "16:9"
          },
          "thumbnailUrl": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublicPresentationDetailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "teamId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "slideCount": {
            "type": "integer"
          },
          "aspectRatio": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": "string"
          },
          "slides": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSlideDto"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublicSlideDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "presentationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "slideIndex": {
            "type": "integer"
          },
          "aspectRatio": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": "string"
          },
          "extractedText": {
            "type": "string"
          },
          "speakerNotes": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublicUploadResponse": {
        "type": "object",
        "properties": {
          "presentationId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "example": "queued"
          },
          "message": {
            "type": "string"
          },
          "statusUrl": {
            "type": "string"
          }
        }
      },
      "PublicPresentationStatusDto": {
        "type": "object",
        "properties": {
          "presentationId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "completed"
          },
          "slideCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublicSearchHitDto": {
        "type": "object",
        "properties": {
          "slideId": {
            "type": "string",
            "format": "uuid"
          },
          "presentationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "snippet": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": "string"
          },
          "aspectRatio": {
            "type": "string"
          },
          "similarityScore": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "PublicSearchResultDto": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "totalHits": {
            "type": "integer"
          },
          "hits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSearchHitDto"
            }
          }
        }
      },
      "PublicAccountUsageDto": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string",
            "format": "uuid"
          },
          "companyName": {
            "type": "string"
          },
          "billingTier": {
            "type": "string",
            "example": "ELITE"
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "example": 300
          },
          "monthlyQuota": {
            "type": "integer",
            "example": 250000
          },
          "monthlyUsage": {
            "type": "integer",
            "example": 1420
          },
          "remainingMonthlyQuota": {
            "type": "integer",
            "example": 248580
          },
          "maxUploadSizeMb": {
            "type": "integer",
            "example": 250
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "UNAUTHORIZED"
          },
          "message": {
            "type": "string",
            "example": "Invalid or missing API key"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameters or malformed request payload",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, invalid, or expired API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Access denied. Public API access requires an ELITE or ENTERPRISE subscription tier.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Requested resource not found in tenant workspace",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimitExceeded": {
        "description": "Rate limit or monthly quota exceeded (HTTP 429)",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Requests permitted per sliding minute"
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Remaining calls in the window"
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Epoch timestamp of rate limit reset"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait before retrying"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
