launch.json spec
Modeled on the Product Hunt submission form, with the Jocohunt fields in the same file.
Location
Put launch.json at .well-known/launch.json on your site. The folder that holds it is the base URL, and one base URL is one listing. Autohunt looks in the pinged path's folder first, then each parent, and stops at the domain root.
| Case | Pinged URL → base URL |
|---|---|
| CaseRoot site | Pinged URL → base URLPinghttps:// |
| CaseGitHub project page | Pinged URL → base URLPinghttps:// |
Ownership is proven by links.website, which must start with the base URL. Relative image paths resolve against the base URL; a website or images on another origin are refused.
URLs are normalized before comparing: lowercase and punycode host, no default port, no trailing dot, no query or fragment. www and the bare domain are different origins.
Fields
The base language is English, as on PH; Korean text goes in i18n.ko.
| Field | Type | Limit | Required | Product Hunt | Jocohunt |
|---|---|---|---|---|---|
| Main info | |||||
| Fieldname | Typestring | Limit1–40 | RequiredRequired | Product HuntName of the launch | Jocohunt제품 이름 |
| Fieldtagline | Typestring | Limit1–60 | RequiredRequired | Product HuntTagline | Jocohunt한 줄 소개 |
| Fielddescription | Typestring | Limit1–500 (≤260 recommended) | RequiredRequired | Product HuntDescription | Jocohunt설명 |
| Fieldlinks.website | TypeHTTPS URL | Limit200 + <title>, starts with base URL | RequiredRequired | Product HuntLinks (first) | Jocohunt웹사이트 |
| Fieldlinks.github | TypeURL | null | Limit— | RequiredOptional | Product HuntLinks | JocohuntGitHub |
| Fieldlinks.other | TypeURL[] | Limit— | RequiredOptional | Product HuntLinks | Jocohunt— |
| FieldopenSource | Typeboolean | Limit— | RequiredOptional | Product HuntIs this an open source project? | Jocohunt— |
| Fieldx | Typestring | null | Limithandle after x.com/ | RequiredOptional | Product HuntX account of the launch | Jocohunt— |
| FieldphTags | Typestring[] | Limit0–3 | RequiredRecommended | Product HuntLaunch tags | Jocohunt— |
| FieldfirstComment | Typestring | null | Limit— | RequiredRecommended | Product HuntFirst comment | Jocohunt— |
| Images and media | |||||
| Fieldmedia.thumbnail | Typepath | URL | Limitsquare ≥240px, PNG/JPEG/GIF/WebP, ≤2,097,152 B | RequiredRequired | Product HuntThumbnail | Jocohunt로고 |
| Fieldmedia.gallery | Type(path | URL)[] | Limit1–8, 1270:760 ±2% | RequiredRequired | Product HuntGallery | Jocohunt스크린샷 |
| Fieldmedia.video | TypeYouTube/ | Limit— | RequiredRecommended | Product HuntVideo / Loom | Jocohunt데모 영상 |
| Fieldmedia.interactiveDemo | TypeURL | null | Limit— | RequiredOptional | Product HuntInteractive demo | Jocohunt— |
| Makers | |||||
| Fieldmakers[] | Type{ name, x?, github?, producthunt?, email?, role? }[] | Limitname required | RequiredRecommended | Product HuntMakers | Jocohunt메이커 |
| FieldsubmitterIsMaker | Typeboolean | Limit— | RequiredOptional | Product HuntDid you work on this product? | Jocohunt— |
| Extras | |||||
| Fieldpricing | Type"free" | "paid" | "freemium" | Limit— | RequiredRecommended | Product HuntPricing | Jocohunt가격 모델 |
| Fieldpromo | Type{ offer, code, expires } | null | Limitall three or null | RequiredOptional | Product HuntPromo code | Jocohunt— |
| FieldlaunchDate | TypeYYYY-MM-DD | null | Limitfuture date shows from that day (KST) | RequiredOptional | Product HuntLaunch date | Jocohunt— |
| Autohunt and Jocohunt only | |||||
| Fieldcategories | Typeenum[] | Limit1+ of 14, no duplicates | RequiredRequired | Product Hunt— | Jocohunt카테고리 |
| Fieldstage | Type"idea" | "development" | "beta" | "launched" | Limit— | RequiredOptional | Product Hunt— | Jocohunt단계 |
| FieldfeedbackWanted | Typeenum[] | LimitUX, 가격, 아이디어 검증, 네이밍, 마케팅, GTM | RequiredOptional | Product Hunt— | Jocohunt받고 싶은 피드백 |
| Fielddraft | Typeboolean | Limittrue is never collected | RequiredOptional | Product Hunt— | Jocohunt— |
| Fieldi18n.ko | Type{ tagline?, description?, firstComment? } | Limitsame limits | RequiredRecommended | Product Hunt— | Jocohunt한국어 문구 |
Length is counted in code points; one Hangul syllable or one emoji is 1. Promo all-or-none and the same-origin rule cannot be expressed in JSON Schema, so only the server checks them.
Full example
The example from the policy, the same value as examplePayload in the MCP's autohunt_get_guide.
{ "$schema": "https:// autohunt. flowoodz. com/ schema/ launch. v1. json", "version": 1, "name": "Loupecast", "tagline": "Free, open- source Screen Studio alternative for macOS", "description": "A free, open- source Screen Studio alternative for macOS. It records your screen and zooms toward each click. ", "links": { "website": "https:// dunzkoi. github. io/ loupecast/ en/ ", "github": "https:// github. com/ dunzkoi/ loupecast", "other": [] }, "openSource": true, "x": "flowoodzx", "phTags": [ "Open Source", "Design Tools", "GIFs" ], "categories": [ "크리에이터 도구" ], "pricing": "free", "stage": "launched", "promo": null, "firstComment": "I wanted click- zoom screen recordings on macOS for free, so I built Loupecast in the open. ", "media": { "thumbnail": "/ launch/ thumbnail. png", "gallery": [ "/ launch/ gallery- 1. png", "/ launch/ gallery- 2. png", "/ launch/ gallery- 3. png" ], "video": null, "interactiveDemo": null }, "makers": [ { "name": "Dun Z", "x": "flowoodzx", "producthunt": null, "github": "dunzkoi", "role": "maker" } ], "submitterIsMaker": true, "feedbackWanted": [ "UX", "아이디어 검증" ], "launchDate": null, "i18n": { "ko": { "tagline": "macOS용 무료 오픈소스 Screen Studio 대안", "description": "macOS용 무료 오픈소스 Screen Studio 대안입니다. 화면을 녹화하면서 클릭한 곳으로 확대합니다. ", "firstComment": "macOS에서 클릭 확대 녹화를 무료로 쓰고 싶어서 Loupecast를 공개로 만들었습니다. " } }}On wide screens it is pinned on the right.
Checks
Any error blocks the listing; warnings never do. Each message comes with its fix.
Errors
requiredA required value is missing: version, name, tagline, description, links.website, categories, media.thumbnail, media.gallery, makers[].name.
invalid_typeinvalid_valueWrong type, or a value not in the allowed list (version is 1; pricing, stage, feedbackWanted).
too_longOver 40 for name, 60 for tagline, or 500 for description. The same goes for i18n.ko; length is counted in code points.
too_many_tagsMore than 3 phTags.
categories_emptycategory_unknowncategory_duplicatecategories is empty, has a value outside the 14, or repeats one.
promo_partialOnly some of promo's offer, code, and expires are filled.
date_formatpromo.expires or launchDate is not a real date in YYYY-MM-DD.
website_not_httpslinks.website is not an https:// URL.
website_not_ownedlinks.website does not start with the base URL.
website_statuswebsite_no_titleThe website does not return 200, or not HTML with a <title> (when a deployed site is checked).
video_unrecognizedmedia.video is not a YouTube (watch, youtu.be, shorts, embed) or Loom (share, embed) URL.
thumbnail_not_squarethumbnail_too_smallThe thumbnail is not square or is under 240 px.
gallery_emptygallery_too_manyThe gallery is empty or has more than 8 images.
gallery_ratioA gallery image is more than 2% off 1270:760.
image_typeimage_too_largeimage_no_sizeimage_fetch_failedBy its bytes the image is not PNG, JPEG, GIF, or WebP; is over 2,097,152 bytes; has no size within the first 256 KB; or could not be fetched.
asset_other_originasset_invalidAn image is an absolute URL on another origin, or not a valid URL.
draft"draft": true. It is not collected.
Warnings
description_longThe description is over 260.
gallery_fewFewer than 3 gallery images.
gallery_narrowA gallery image is narrower than 1270 px.
video_missingNo demo video.
first_comment_missingNo firstComment.
i18n_ko_missingAn i18n.ko tagline, description, or firstComment is empty. Korean pages show the English value.
makers_aloneNo maker besides the submitter.
ph_tag_unknownA phTags value is not in the embedded PH tag list.
promo_expiredpromo.expires is in the past.
pricing_missingNo pricing.
Image checks (type, size, dimensions) run only against a deployed site. A draft alone gets the field rules.