Raw schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The product name, up to 80 characters."
},
"oneLiner": {
"type": "string",
"description": "One sentence saying what it does, up to 80 characters. Not a tagline."
},
"description": {
"type": "string",
"description": "REQUIRED, up to 800 characters. A short paragraph in the builder's OWN words about what the product is and who it is for, shown on the listing's own page. Plain text β links are not rendered, so put the address in websiteUrl. Never write it yourself, and never pad it to a length: ask the builder for it, the way you would ask for the URL. A short answer in their words is worth more here than a long one in yours. It became required on 2026-09-03 because a listing without one has nothing on its page a search engine can tell apart from every other listing."
},
"websiteUrl": {
"type": "string",
"description": "REQUIRED. The product's own https URL β the address a reader opens. A code repository or an app store page counts. REFUSED: a shared document (Drive, Docs, Dropbox, Notion), and a free platform deploy subdomain (vercel.app, netlify.app, github.io, web.app, railway.app and the like) β the builder needs a domain of their own first. Never invent one: ask the builder."
},
"logoUrl": {
"type": "string",
"description": "An https URL to a square logo, or null."
},
"category": {
"type": "string",
"description": "REQUIRED. The product's MAIN category, from list_filters. Closed vocabulary. This is the one a row, a card and the sharing image show."
},
"categories": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional. Up to 3 categories from list_filters, MAIN FIRST β for a product that is honestly more than one thing (an AI agent that is also a dev tool). The first must be the same value as `category`; send it first or leave it out of the list and it is put there. A listing is findable and filed under all of them, so send only the ones the builder would claim: three loosely-related categories are worse for them than one true one. Ask the builder rather than inferring from their site."
},
"region": {
"type": "string",
"description": "REQUIRED. Country name from list_filters. Closed vocabulary. Use \"Global\" where the builder is not anywhere in particular or would rather not say β that is a real answer on this list, and it is the one to send rather than guessing a country or omitting the field."
},
"city": {
"type": "string",
"description": "City, or null."
},
"fundingStage": {
"type": "string",
"enum": [
"bootstrapped",
"pre-seed",
"seed",
"series-a",
"undisclosed"
],
"description": "Funding stage. Use \"undisclosed\" where the builder has not said β never guess."
},
"activelyRaising": {
"type": [
"boolean",
"null"
],
"description": "true, false, or null for \"would rather not say\". Default null."
},
"openTo": {
"type": "array",
"items": {
"type": "string",
"enum": [
"investment",
"advisors",
"beta-users",
"co-founders",
"partnerships",
"hiring"
]
},
"description": "What the builder invited contact about. Omit for none."
},
"mrr": {
"type": [
"number",
"null"
],
"description": "Monthly recurring revenue, only where the builder chose to publish it."
},
"builder": {
"type": "object",
"description": "Attribution. `name` is required; the rest is optional.",
"properties": {
"name": {
"type": "string"
},
"avatarUrl": {
"type": [
"string",
"null"
]
},
"region": {
"type": [
"string",
"null"
]
},
"socials": {
"type": "object",
"description": "Accounts keyed by platform, e.g. { \"x\": \"β¦\" }."
}
},
"required": [
"name"
]
},
"socials": {
"type": "object",
"description": "The PRODUCT's own accounts, keyed by platform β not the builder's, which go under `builder.socials`. Keys: `x`, `linkedin`, `instagram`, `tiktok`, `youtube`, `facebook`, `github`, `email`. Each is `{ \"url\": \"β¦\" }` except `x`, which is `{ \"handle\": \"β¦\" }`, and `email`, which is `{ \"address\": \"β¦\" }` and should be a business address (support@, hello@) rather than a person's. `github` is the PRODUCT's repository β the code somebody would clone. The builder's own GitHub account is a different thing and goes in `builder.socials.github`."
}
},
"required": [
"name",
"oneLiner",
"description",
"websiteUrl",
"category",
"region",
"fundingStage",
"builder"
],
"additionalProperties": false
}