{
  "openapi": "3.1.0",
  "info": {
    "title": "FounderOmni Showcase Submission API",
    "version": "1.1.0",
    "description": "Free preparation, founder confirmation, moderated publication and scoped listing management. Private keys belong in Authorization, never query strings. Up to 6 images and one MP4 video, 5 MB per file. Images use slots 0–5; video uses slot 6. Cover image slot 0 is required. upload accepts mediaBase64, mediaType (image or video), slot, and resetMedia (true only for slot 0 to replace the gallery). Legacy imageBase64 remains supported. All media stay private until owner confirmation and admin approval. Media display: portrait 9:16, recommended 1080 × 1920 px for images and MP4 video. Other ratios are center-cropped without stretching. Originals are retained; the founder must review every cropped slide before confirmation."
  },
  "servers": [
    {
      "url": "https://kghdjjjwnpanzpuagqjb.supabase.co/functions/v1"
    }
  ],
  "paths": {
    "/launch-public": {
      "get": {
        "operationId": "listApprovedProducts",
        "parameters": [
          {
            "name": "slug",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "leaderboard",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "week",
                "month",
                "all"
              ]
            },
            "description": "Rank published products by recorded browser likes: rolling 24 hours (day), 7 days (week), 30 days (month), or all time."
          }
        ],
        "responses": {
          "200": {
            "description": "Approved public products"
          },
          "404": {
            "description": "Product unavailable"
          },
          "503": {
            "description": "Catalog unavailable"
          }
        }
      },
      "post": {
        "operationId": "launchAction",
        "security": [
          {},
          {
            "managementKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "New products require email. Edits require productId and the original key. A draft is not submitted.",
                    "properties": {
                      "action": {
                        "const": "prepare"
                      },
                      "name": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      "tagline": {
                        "type": "string",
                        "minLength": 10,
                        "maxLength": 140
                      },
                      "description": {
                        "type": "string",
                        "minLength": 40,
                        "maxLength": 3000
                      },
                      "creatorName": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 100
                      },
                      "websiteUrl": {
                        "type": "string",
                        "format": "uri",
                        "pattern": "^https://"
                      },
                      "category": {
                        "type": "string",
                        "enum": [
                          "AI agents",
                          "Developer tools",
                          "Design",
                          "Productivity",
                          "Marketing",
                          "Education",
                          "Commerce",
                          "Other"
                        ]
                      },
                      "pricing": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      "tags": {
                        "type": "array",
                        "maxItems": 5,
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 30
                        }
                      },
                      "imageAlt": {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 240
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "productId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "action",
                      "name",
                      "tagline",
                      "description",
                      "creatorName",
                      "websiteUrl",
                      "category"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Requires a private bearer key. update",
                    "properties": {
                      "action": {
                        "const": "update"
                      },
                      "name": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      "tagline": {
                        "type": "string",
                        "minLength": 10,
                        "maxLength": 140
                      },
                      "description": {
                        "type": "string",
                        "minLength": 40,
                        "maxLength": 3000
                      },
                      "creatorName": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 100
                      },
                      "websiteUrl": {
                        "type": "string",
                        "format": "uri",
                        "pattern": "^https://"
                      },
                      "category": {
                        "type": "string",
                        "enum": [
                          "AI agents",
                          "Developer tools",
                          "Design",
                          "Productivity",
                          "Marketing",
                          "Education",
                          "Commerce",
                          "Other"
                        ]
                      },
                      "pricing": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      "tags": {
                        "type": "array",
                        "maxItems": 5,
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 30
                        }
                      },
                      "imageAlt": {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 240
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "productId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "submissionId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "action",
                      "submissionId",
                      "name",
                      "tagline",
                      "description",
                      "creatorName",
                      "websiteUrl",
                      "category"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Owned draft only. Every media change invalidates an older email confirmation. Use 5 MB per file; imageBase64 remains compatible. Recommended: 1080 × 1920 px (9:16) for images and video; display uses a centered crop. Review every cropped slide before confirmation.",
                    "properties": {
                      "action": {
                        "const": "upload"
                      },
                      "submissionId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "imageBase64": {
                        "type": "string",
                        "contentEncoding": "base64"
                      },
                      "mediaBase64": {
                        "type": "string",
                        "description": "Base64 PNG/JPEG/WebP or MP4 bytes; maximum decoded size 5 MB"
                      },
                      "mediaType": {
                        "type": "string",
                        "enum": [
                          "image",
                          "video"
                        ],
                        "default": "image"
                      },
                      "slot": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 6,
                        "default": 0,
                        "description": "Images 0–5, MP4 6. Cover image slot 0 is required."
                      },
                      "resetMedia": {
                        "type": "boolean",
                        "default": false,
                        "description": "True with slot 0 replaces the old gallery."
                      }
                    },
                    "required": [
                      "action",
                      "submissionId"
                    ],
                    "anyOf": [
                      {
                        "required": [
                          "mediaBase64"
                        ]
                      },
                      {
                        "required": [
                          "imageBase64"
                        ]
                      }
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Requires a private bearer key. preview",
                    "properties": {
                      "action": {
                        "const": "preview"
                      },
                      "submissionId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "action",
                      "submissionId"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Human finalization in the website. Agents stop at the private review link. Requires a private bearer key. request_confirmation",
                    "properties": {
                      "action": {
                        "const": "request_confirmation"
                      },
                      "submissionId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "action",
                      "submissionId"
                    ],
                    "x-agent-allowed": false
                  },
                  {
                    "type": "object",
                    "description": "Human finalization in the website. Agents stop at the private review link. Requires a private bearer key. Requires the founder to review the preview and explicitly confirm.",
                    "properties": {
                      "action": {
                        "const": "confirm"
                      },
                      "challengeId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "code": {
                        "type": "string",
                        "pattern": "^[0-9]{8}$"
                      },
                      "ownerConfirmed": {
                        "const": true
                      },
                      "reviewedMedia": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 7,
                        "uniqueItems": true,
                        "items": {
                          "type": "string",
                          "pattern": "^[a-f0-9]{64}$"
                        },
                        "description": "All reviewId values in the current private preview; the human must review every image and video."
                      }
                    },
                    "required": [
                      "action",
                      "challengeId",
                      "code",
                      "ownerConfirmed",
                      "reviewedMedia"
                    ],
                    "x-agent-allowed": false
                  },
                  {
                    "type": "object",
                    "description": "Requires a private bearer key. manage",
                    "properties": {
                      "action": {
                        "const": "manage"
                      }
                    },
                    "required": [
                      "action"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "recover",
                    "properties": {
                      "action": {
                        "const": "recover"
                      },
                      "productId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "submissionId": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Confirmed submission ID, used when no Product ID exists yet."
                      }
                    },
                    "required": [
                      "action",
                      "email"
                    ],
                    "oneOf": [
                      {
                        "required": [
                          "productId"
                        ]
                      },
                      {
                        "required": [
                          "submissionId"
                        ]
                      }
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Requires a private bearer key. recover_confirm",
                    "properties": {
                      "action": {
                        "const": "recover_confirm"
                      },
                      "challengeId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "code": {
                        "type": "string",
                        "pattern": "^[0-9]{8}$"
                      }
                    },
                    "required": [
                      "action",
                      "challengeId",
                      "code"
                    ]
                  },
                  {
                    "type": "object",
                    "required": [
                      "action",
                      "productId",
                      "visitorKey",
                      "reaction"
                    ],
                    "properties": {
                      "action": {
                        "const": "vote"
                      },
                      "productId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "visitorKey": {
                        "type": "string",
                        "pattern": "^[a-f0-9]{64}$"
                      },
                      "reaction": {
                        "type": "string",
                        "enum": [
                          "like",
                          "skip",
                          "clear"
                        ]
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "action",
                      "productId",
                      "visitorKey"
                    ],
                    "properties": {
                      "action": {
                        "const": "open"
                      },
                      "productId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "visitorKey": {
                        "type": "string",
                        "pattern": "^[a-f0-9]{64}$"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Human action: email a code to open works from the original submission email. Generic response whether or not the email exists.",
                    "x-agent-allowed": false,
                    "properties": {
                      "action": {
                        "const": "request_management_code"
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      }
                    },
                    "required": [
                      "action",
                      "email"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Human action: verify the emailed code with the pending session bearer token. Returns a two-hour browser session; does not rotate existing agent keys.",
                    "x-agent-allowed": false,
                    "properties": {
                      "action": {
                        "const": "verify_management_code"
                      },
                      "challengeId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "code": {
                        "type": "string",
                        "pattern": "^[0-9]{8}$"
                      }
                    },
                    "required": [
                      "action",
                      "challengeId",
                      "code"
                    ]
                  },
                  {
                    "type": "object",
                    "description": "Revoke the current browser session.",
                    "x-agent-allowed": false,
                    "properties": {
                      "action": {
                        "const": "end_management_session"
                      }
                    },
                    "required": [
                      "action"
                    ]
                  }
                ],
                "discriminator": {
                  "propertyName": "action"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action complete"
          },
          "201": {
            "description": "Private draft created; save key and review URL"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid or expired key"
          },
          "403": {
            "description": "Invalid verification or owner access"
          },
          "409": {
            "description": "Draft or product changed"
          },
          "413": {
            "description": "Request too large"
          },
          "429": {
            "description": "Rate limited; wait before retrying"
          },
          "503": {
            "description": "Unavailable; inspect saved receipt before preparing again"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "managementKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Private scoped 256-bit capability. New preparation/recovery are public; private actions and editing require a key."
      }
    }
  },
  "x-showcase-media-display": {
    "aspectRatio": "9:16",
    "recommendedWidth": 1080,
    "recommendedHeight": 1920,
    "fit": "cover",
    "objectPosition": "50% 50%",
    "originalsRetained": true,
    "required": "Founder reviews all cropped media before confirmation; dimensions are recommended, not an upload rejection rule."
  },
  "x-showcase-agent-workflow": {
    "agentActions": [
      "prepare",
      "upload",
      "preview",
      "update"
    ],
    "humanActions": [
      "request_confirmation",
      "confirm"
    ],
    "handoff": "Return the private review link and stop. The human reviews all media, verifies their email and confirms. Agents must not handle codes, mark reviews or call confirm.",
    "mediaGeneration": "Use the caller agent’s own tools with owner permission. Accurate AI illustrations and screenshots are supported; optional video requires full human playback review.",
    "revisionRule": "Any product or media edit invalidates the prior email challenge; review and verify again."
  }
}
