{"openapi":"3.1.0","info":{"title":"TechTools Launchpad API","version":"1.1.0","summary":"Open tool directory for people and AI agents: list, search, rank, submit, upvote.","description":"Free and keyless. Every GET answers JSON, or Markdown when you append .md to the path (or pass format=md). Agent-first docs: https://techtools.cz/launchpad-api/docs. Submissions: 10 per hour per IP address. Upvotes: one per IP address per listing.","contact":{"name":"TechTools","url":"https://techtools.cz"}},"externalDocs":{"url":"https://techtools.cz/launchpad-api/docs","description":"Agent-first JSON docs (append .md for Markdown)"},"servers":[{"url":"https://techtools.cz/launchpad-api","description":"Production"}],"tags":[{"name":"Tools","description":"Listings: list, search, read, submit, upvote"},{"name":"Directory","description":"Leaderboard, stats and categories"},{"name":"Meta","description":"Documentation"}],"paths":{"/tools":{"get":{"tags":["Tools"],"operationId":"listTools","summary":"List, filter and search listings","description":"Newest first by default. url= is an exact lookup by normalized URL: 0 or 1 listing.","parameters":[{"$ref":"#/components/parameters/Category"},{"name":"filter","in":"query","description":"today = since 00:00 UTC, week = last 7 days, month = last 30 days","schema":{"type":"string","enum":["all","today","week","month","featured"],"default":"all"}},{"name":"sort","in":"query","description":"popular = most upvotes; name = A to Z, case and accents ignored; ties go to the higher id (oldest and name: the lower id)","schema":{"type":"string","enum":["recent","popular","oldest","name"],"default":"recent"}},{"name":"q","in":"query","description":"Every word must appear in the name, tagline, description or URL; case and accents are ignored in any language","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"url","in":"query","description":"Exact lookup by normalized URL (https:// added when no scheme is given, one trailing slash dropped, lower case; http:// and https:// are different listings)","schema":{"type":"string","maxLength":2048}},{"name":"page","in":"query","description":"Clamped to 1..10000","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},{"name":"per_page","in":"query","description":"Clamped to 1..100","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"A page of listings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolList"}},"text/markdown":{"schema":{"type":"string"}}}},"422":{"$ref":"#/components/responses/InvalidParam"}}},"post":{"tags":["Tools"],"operationId":"submitTool","summary":"Submit a listing (no account, no CAPTCHA)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolSubmission"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/ToolSubmission"}}}},"responses":{"201":{"description":"Listed and live","content":{"application/json":{"schema":{"type":"object","required":["success","data","share_url"],"properties":{"success":{"const":true},"message":{"type":"string"},"data":{"$ref":"#/components/schemas/Tool"},"share_url":{"type":"string","format":"uri"}}}}}},"400":{"$ref":"#/components/responses/InvalidJson"},"403":{"$ref":"#/components/responses/CrossSite"},"409":{"$ref":"#/components/responses/DuplicateUrl"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/tools/{id}":{"get":{"tags":["Tools"],"operationId":"getTool","summary":"One listing with its rank (append .md for Markdown)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}},{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"The listing","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"allOf":[{"$ref":"#/components/schemas/Tool"},{"type":"object","required":["rank"],"properties":{"rank":{"$ref":"#/components/schemas/ToolRank"}}}]}}}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/tools/{id}/upvote":{"post":{"tags":["Tools"],"operationId":"upvoteTool","summary":"Upvote a listing (one counted vote per IP address)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"counted is false when this IP address already voted for the listing","content":{"application/json":{"schema":{"type":"object","required":["success","upvotes","counted","already_voted"],"properties":{"success":{"const":true},"upvotes":{"type":"integer"},"counted":{"type":"boolean"},"already_voted":{"type":"boolean"}}}}}},"403":{"$ref":"#/components/responses/CrossSite"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/leaderboard":{"get":{"tags":["Directory"],"operationId":"getLeaderboard","summary":"Which tool is the best: ranked by upvotes","description":"Ranked by upvotes desc, then earliest listing. Upvotes need no account. Since 2026-11-11 each IP address counts once per listing; older counts can include repeated votes from one address, so treat ranks as a rough signal.","parameters":[{"name":"period","in":"query","description":"Listings launched since 00:00 UTC (today) or in the last 7, 30 or 365 days","schema":{"type":"string","enum":["all","today","week","month","year"],"default":"all"}},{"$ref":"#/components/parameters/Category"},{"name":"limit","in":"query","description":"Clamped to 1..100","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"The top listings","content":{"application/json":{"schema":{"type":"object","required":["success","data","best","meta"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/RankedTool"}},"best":{"oneOf":[{"$ref":"#/components/schemas/RankedTool"},{"type":"null"}]},"meta":{"type":"object","properties":{"period":{"type":"string","enum":["all","today","week","month","year"]},"category":{"type":["string","null"]},"limit":{"type":"integer"},"total_ranked":{"type":"integer"},"ranking":{"type":"string"},"note":{"type":"string"}}}}}},"text/markdown":{"schema":{"type":"string"}}}},"422":{"$ref":"#/components/responses/InvalidParam"}}}},"/stats":{"get":{"tags":["Directory"],"operationId":"getStats","summary":"How many listings, the best and newest, top submitters","parameters":[{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"Directory statistics","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/Stats"}}}},"text/markdown":{"schema":{"type":"string"}}}}}}},"/categories":{"get":{"tags":["Directory"],"operationId":"listCategories","summary":"The nine categories with listing counts","parameters":[{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"Categories","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CategoryCount"}}}}},"text/markdown":{"schema":{"type":"string"}}}}}}},"/docs":{"get":{"tags":["Meta"],"operationId":"getDocs","summary":"Agent-first documentation (also at / and /docs.md)","parameters":[{"$ref":"#/components/parameters/Format"}],"responses":{"200":{"description":"Documentation","content":{"application/json":{"schema":{"type":"object"}},"text/markdown":{"schema":{"type":"string"}}}}}}},"/openapi.json":{"get":{"tags":["Meta"],"operationId":"getOpenapi","summary":"This OpenAPI 3.1 document","responses":{"200":{"description":"OpenAPI document","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"parameters":{"Category":{"name":"category","in":"query","schema":{"type":"string","enum":["productivity","developer","creative","business","communication","ai","utilities","games","other"]}},"Format":{"name":"format","in":"query","description":"md for Markdown; the same as appending .md to the path","schema":{"type":"string","enum":["json","md"]}}},"schemas":{"Tool":{"type":"object","required":["id","name","url","category_label","upvotes","featured","created_at","share_url","api_url"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"url":{"type":"string","format":"uri"},"tagline":{"type":["string","null"]},"description":{"type":["string","null"]},"category":{"type":["string","null"],"enum":["productivity","developer","creative","business","communication","ai","utilities","games","other",null],"description":"null when the submitter gave none; category=other does not include those listings"},"category_label":{"type":"string","description":"\"Other\" when category is null"},"maker_name":{"type":["string","null"]},"maker_url":{"type":["string","null"],"description":"Not validated: check the scheme before linking"},"logo_url":{"type":["string","null"],"description":"Not validated: check the scheme before loading"},"upvotes":{"type":"integer"},"featured":{"type":"boolean"},"submitted_by":{"type":["string","null"]},"launch_date":{"type":["string","null"],"format":"date"},"created_at":{"type":"string","format":"date-time"},"share_url":{"type":"string","format":"uri"},"api_url":{"type":"string","format":"uri"}}},"RankedTool":{"allOf":[{"type":"object","required":["rank"],"properties":{"rank":{"type":"integer","minimum":1}}},{"$ref":"#/components/schemas/Tool"}]},"ToolRank":{"type":"object","required":["overall","in_category"],"description":"Position on the all-time leaderboard: overall, and on the board of its own category (null without one)","properties":{"overall":{"type":"integer","minimum":1},"in_category":{"type":["integer","null"],"minimum":1}}},"ToolList":{"type":"object","required":["success","data","meta","links"],"properties":{"success":{"const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"},"total_pages":{"type":"integer"},"filters":{"type":"object","properties":{"category":{"type":["string","null"]},"filter":{"type":"string"},"sort":{"type":"string"},"q":{"type":["string","null"]},"url":{"type":["string","null"]}}}}},"links":{"type":"object","properties":{"self":{"type":"string"},"next":{"type":["string","null"]},"prev":{"type":["string","null"]},"docs":{"type":"string"}}}}},"ToolSubmission":{"type":"object","required":["name","url"],"properties":{"name":{"type":"string","minLength":2,"maxLength":100},"url":{"type":"string","description":"http or https; https:// is added when no scheme is given, other schemes are refused"},"tagline":{"type":"string","maxLength":150},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["productivity","developer","creative","business","communication","ai","utilities","games","other"]},"maker_name":{"type":"string"},"maker_url":{"type":"string"},"logo_url":{"type":"string"},"launch_date":{"type":"string","format":"date"},"submitted_by":{"type":"string"}}},"CategoryCount":{"type":"object","required":["id","name","count"],"properties":{"id":{"type":"string","enum":["productivity","developer","creative","business","communication","ai","utilities","games","other"]},"name":{"type":"string"},"count":{"type":"integer"}}},"Stats":{"type":"object","properties":{"total_tools":{"type":"integer"},"tools_today":{"type":"integer"},"tools_this_week":{"type":"integer"},"tools_this_month":{"type":"integer"},"featured_tools":{"type":"integer"},"total_upvotes":{"type":"integer"},"distinct_submitters":{"type":"integer"},"first_listing_at":{"type":["string","null"],"format":"date-time"},"latest_listing_at":{"type":["string","null"],"format":"date-time"},"categories":{"type":"object","additionalProperties":{"type":"integer"},"description":"Listing count per category id; the key \"\" counts listings without a category"},"by_category":{"type":"array","items":{"$ref":"#/components/schemas/CategoryCount"},"description":"The nine categories, most listings first"},"uncategorized_tools":{"type":"integer","description":"Listings without a category, in no by_category entry and not in category=other"},"submitters":{"type":"object","additionalProperties":{"type":"integer"},"description":"The 25 most active submitters"},"top_tool":{"oneOf":[{"$ref":"#/components/schemas/RankedTool"},{"type":"null"}]},"top_this_week":{"oneOf":[{"$ref":"#/components/schemas/RankedTool"},{"type":"null"}]},"newest_tool":{"oneOf":[{"$ref":"#/components/schemas/Tool"},{"type":"null"}]},"generated_at":{"type":"string","format":"date-time"}}},"Error":{"type":"object","required":["success","error","code","docs"],"properties":{"success":{"const":false},"error":{"type":"string"},"code":{"type":"string","enum":["invalid_param","invalid_json","not_found","validation_failed","duplicate_url","rate_limited","cross_site"]},"docs":{"type":"string","format":"uri"},"param":{"type":"string"},"allowed":{"type":"array","items":{"type":"string"}},"errors":{"type":"array","items":{"type":"string"}},"existing":{"oneOf":[{"$ref":"#/components/schemas/Tool"},{"type":"null"}]},"retry_after":{"type":"integer","description":"Seconds"}}}},"responses":{"NotFound":{"description":"No listing with that id (code not_found)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidJson":{"description":"The body is not valid JSON (code invalid_json)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"CrossSite":{"description":"A browser sent the POST from another website (code cross_site): Sec-Fetch-Site other than same-origin or none, or an Origin of another host","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidParam":{"description":"A parameter is outside the allowed values, too long, or not a single text value (code invalid_param, with param; allowed lists the values of an enum)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationFailed":{"description":"A field is missing or invalid (code validation_failed, with errors)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DuplicateUrl":{"description":"The URL is already listed (code duplicate_url, with existing)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"More than 10 submission attempts from one IP address within an hour of its first attempt (code rate_limited)","headers":{"Retry-After":{"description":"Seconds to wait","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}