{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "$schema": {
      "type": "string"
    },
    "version": {
      "type": "number",
      "const": 1
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "Name of the launch (PH Main info).",
      "maxLength": 40
    },
    "tagline": {
      "type": "string",
      "minLength": 1,
      "description": "Tagline. Do not repeat the name.",
      "maxLength": 60
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "description": "What it is and how it differs. 260 code points or fewer recommended.",
      "maxLength": 500
    },
    "links": {
      "type": "object",
      "properties": {
        "website": {
          "type": "string",
          "minLength": 1,
          "pattern": "^https://",
          "description": "HTTPS URL that returns 200. Must start with the base URL (the folder holding .well-known/launch.json)."
        },
        "github": {
          "description": "GitHub repository URL.",
          "type": [
            "string",
            "null"
          ]
        },
        "other": {
          "description": "App Store, Google Play, Steam, ...",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "website"
      ],
      "additionalProperties": {}
    },
    "openSource": {
      "type": "boolean"
    },
    "x": {
      "description": "X account of the launch, handle after x.com/.",
      "type": [
        "string",
        "null"
      ]
    },
    "phTags": {
      "description": "Up to 3 Product Hunt launch tags.",
      "maxItems": 3,
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "categories": {
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "AI 도구",
          "B2B SaaS",
          "개발자 도구",
          "게임",
          "교육",
          "기타",
          "노코드",
          "디자인",
          "마케팅",
          "모바일 앱",
          "생산성",
          "웹 서비스",
          "자동화",
          "크리에이터 도구"
        ]
      },
      "description": "One or more Jocohunt categories, no duplicates."
    },
    "pricing": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "free",
            "paid",
            "freemium"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "stage": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "idea",
            "development",
            "beta",
            "launched"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "promo": {
      "description": "null, or all three of offer, code, expires (YYYY-MM-DD). All-or-none is checked by the server.",
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "offer": {
              "type": "string"
            },
            "code": {
              "type": "string"
            },
            "expires": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          "additionalProperties": {}
        },
        {
          "type": "null"
        }
      ]
    },
    "firstComment": {
      "description": "Why you made it, the problem, the process. Posted at launch.",
      "type": [
        "string",
        "null"
      ]
    },
    "media": {
      "type": "object",
      "properties": {
        "thumbnail": {
          "type": "string",
          "minLength": 1,
          "description": "Square, 240x240 or larger, PNG/JPEG/GIF/WebP, at most 2,097,152 bytes."
        },
        "gallery": {
          "minItems": 1,
          "maxItems": 8,
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "1-8 images at 1270:760 (2% tolerance); 1270x760 or 2540x1520 recommended; 3+ recommended."
        },
        "video": {
          "description": "YouTube (watch, youtu.be, shorts, embed) or Loom (share, embed) URL.",
          "type": [
            "string",
            "null"
          ]
        },
        "interactiveDemo": {
          "description": "Arcade, Storylane, Supademo, ... link.",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "thumbnail",
        "gallery"
      ],
      "additionalProperties": {}
    },
    "makers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Maker name (required)."
          },
          "x": {
            "description": "X handle without @.",
            "type": [
              "string",
              "null"
            ]
          },
          "github": {
            "description": "GitHub username.",
            "type": [
              "string",
              "null"
            ]
          },
          "producthunt": {
            "description": "Product Hunt username.",
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "description": "Email, used only in the Product Hunt paste-pack.",
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "description": "e.g. maker, hunter.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": {}
      }
    },
    "submitterIsMaker": {
      "type": "boolean"
    },
    "feedbackWanted": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "UX",
          "가격",
          "아이디어 검증",
          "네이밍",
          "마케팅",
          "GTM"
        ]
      }
    },
    "launchDate": {
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "YYYY-MM-DD. A future date is shown from that day (KST).",
      "type": [
        "string",
        "null"
      ]
    },
    "draft": {
      "description": "true: the server does not collect this launch.",
      "type": "boolean"
    },
    "i18n": {
      "type": "object",
      "properties": {
        "ko": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "maxLength": 40
            },
            "tagline": {
              "type": "string",
              "maxLength": 60
            },
            "description": {
              "type": "string",
              "maxLength": 500
            },
            "firstComment": {
              "type": "string"
            }
          },
          "additionalProperties": {}
        }
      },
      "additionalProperties": {}
    }
  },
  "required": [
    "version",
    "name",
    "tagline",
    "description",
    "links",
    "categories",
    "media"
  ],
  "additionalProperties": {},
  "$id": "https://autohunt.flowoodz.com/schema/launch.v1.json",
  "title": "Autohunt launch.json v1",
  "description": "Autohunt launch.json v1. Place at <base URL>/.well-known/launch.json; relative asset paths (including ones starting with a single /) resolve against the base URL. Generated from the zod schema (zod 4.6.7). maxLength counts Unicode code points. Checked only by the server (not expressible here): promo all-or-none; links.website starting with the base URL (ownership); assets and website on the same origin; image type by magic bytes, size <= 2,097,152 bytes, thumbnail square >= 240 px, gallery ratio within 2% of 1270:760; draft must not be true to be listed; categories without duplicates; dates must be real calendar dates; media.video must be a recognized YouTube or Loom URL."
}
