Products
GET /products/@{username}/{slug} and GET /users/@{username}/products: a builder's products, the pages at taste.dev/@name/slug.
On Taste, builders build a brand around their products. Every project on a profile can have its own page at taste.dev/@{username}/{slug}: screenshots, a pitch, links to try it, the tools it was built with and a timeline of updates. The page wears its maker's theme.
Both endpoints are public and need no key.
Get a product
GET https://api.taste.dev/products/@{username}/{slug}usernamestringpathrequiredThe maker's handle, without the @ in the value (the path spells it @mika). Case-insensitive.
slugstringpathrequiredThe product's slug, as in the profile's projects[].slug. Lowercase letters, digits and -. opengraph-image is reserved: it is never a product.
curl https://api.taste.dev/products/@mika/counterconst res = await fetch(`https://api.taste.dev/products/@${name}/${slug}`);
const page = res.ok ? await res.json() : null; // 404: nothing here{
"product": {
"id": "7b1c9e52-2f4a-4c1e-9a55-0d6f3c1e8a10",
"slug": "counter",
"name": "Counter",
"tagline": "The AI receptionist for indie pharmacies",
"description": "Counter answers the pharmacy phone so the pharmacist can stay behind the counter.",
"url": "https://counter.mika.build",
"repo_url": null,
"images": [
"https://storage.googleapis.com/taste-uploads/counter-1.png",
"https://storage.googleapis.com/taste-uploads/counter-2.png"
],
"tools": ["claude_code", "cursor", "v0"],
"stars": 412,
"followers": 214,
"updates": 3,
"support_url": null,
"created_at": "2026-07-02T15:00:00Z",
"updated_at": "2026-09-21T18:30:00Z",
"owner": {
"user_id": "3d2e8f10-5b6a-4c7d-9e0f-1a2b3c4d5e6f",
"username": "mika",
"display_name": "Mika Tanaka",
"photo_url": "https://api.taste.dev/avatars/glasses/mika.svg",
"theme_id": "terminal"
}
},
"posts": [
{
"id": "0f3a2b71-8c44-4d0e-b6a2-51e9d8f7c203",
"body": "Flu shot booking is live.",
"kind": "ship",
"media_urls": ["https://storage.googleapis.com/taste-uploads/counter-flu.png"],
"link_url": "https://counter.mika.build/changelog",
"like_count": 18,
"comment_count": 4,
"created_at": "2026-09-21T18:30:00Z"
}
]
}Product fields
product.slugstringrequiredThe page's slug. If the maker renamed it, follow the one returned: taste.dev redirects to the canonical /@{owner.username}/{slug}.
product.namestringrequiredThe product's name.
product.taglinestring | nullrequiredA one-line pitch. taste.dev uses it as the page's description and on the profile card.
product.descriptionstring | nullrequiredThe longer story, plain text. Blank lines separate paragraphs. Never render it as HTML.
product.urlstring | nullrequiredWhere to try it (Visit).
product.repo_urlstring | nullrequiredIts source (Repo).
product.imagesstring[]requiredScreenshots, in order; the first is the cover (and the OG image). Show them as a swipeable carousel.
product.toolsstring[]requiredWhat it was built with: tool slugs or labels, as in the profile's tools.
product.starsintegerrequiredGitHub stars (0 when it has no repo).
product.followersintegerrequiredHow many people follow it in the app. A count, never who.
product.updatesintegerrequiredHow many updates the maker has posted about it.
product.support_urlstring | nullrequiredWhere to back this product. When it's null, taste.dev's Support button uses the maker's first support link.
product.ownerobjectrequired{username, display_name, photo_url}: the maker. For their theme and support links, fetch their public profile.
postsobject[]requiredThe product's updates, newest first: {id, body, created_at, link_url, images}. body is plain text; images may be empty.
List a builder's products
GET https://api.taste.dev/users/@{username}/productsEvery product on the builder's page, in their order, each shaped like product above:
{
"products": [
{
"id": "7b1c9e52-2f4a-4c1e-9a55-0d6f3c1e8a10",
"slug": "counter",
"name": "Counter",
"tagline": "The AI receptionist for indie pharmacies",
"description": null,
"url": "https://counter.mika.build",
"repo_url": null,
"images": [],
"tools": ["claude_code"],
"stars": 412,
"followers": 214,
"updates": 3,
"support_url": null,
"created_at": "2026-07-02T15:00:00Z",
"updated_at": "2026-09-21T18:30:00Z",
"owner": { "username": "mika", "display_name": "Mika Tanaka", "photo_url": null }
}
]
}The profile's projects already carry slug, tagline and followers, which is enough to link each card to its page. Use this endpoint when you need the full products.
Not found
An unknown maker or slug, a hidden portfolio, or anything that isn't live and public:
{ "error": "not_found" }taste.dev shows a "nothing shipped here yet" page that links back to the maker.
On taste.dev
| URL | What it is |
|---|---|
taste.dev/@{username}/{slug} | The product page, in the maker's theme |
taste.dev/@{username}/{slug}/opengraph-image | Its 1200×630 share card: cover image, name, tagline, maker |
taste.dev/@{username} | The maker's profile; project cards open their product pages |
Product pages are cached like profiles: edits show up within about a minute (Caching).