APIProducts

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

http
GET https://api.taste.dev/products/@{username}/{slug}
usernamestringpathrequired

The maker's handle, without the @ in the value (the path spells it @mika). Case-insensitive.

slugstringpathrequired

The product's slug, as in the profile's projects[].slug. Lowercase letters, digits and -. opengraph-image is reserved: it is never a product.

cURLbash
curl https://api.taste.dev/products/@mika/counter
JavaScriptjs
const res = await fetch(`https://api.taste.dev/products/@${name}/${slug}`);
const page = res.ok ? await res.json() : null; // 404: nothing here
200 OKjson
{
  "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.slugstringrequired

The page's slug. If the maker renamed it, follow the one returned: taste.dev redirects to the canonical /@{owner.username}/{slug}.

product.namestringrequired

The product's name.

product.taglinestring | nullrequired

A one-line pitch. taste.dev uses it as the page's description and on the profile card.

product.descriptionstring | nullrequired

The longer story, plain text. Blank lines separate paragraphs. Never render it as HTML.

product.urlstring | nullrequired

Where to try it (Visit).

product.repo_urlstring | nullrequired

Its source (Repo).

product.imagesstring[]required

Screenshots, in order; the first is the cover (and the OG image). Show them as a swipeable carousel.

product.toolsstring[]required

What it was built with: tool slugs or labels, as in the profile's tools.

product.starsintegerrequired

GitHub stars (0 when it has no repo).

product.followersintegerrequired

How many people follow it in the app. A count, never who.

product.updatesintegerrequired

How many updates the maker has posted about it.

product.support_urlstring | nullrequired

Where 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[]required

The 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

http
GET https://api.taste.dev/users/@{username}/products

Every product on the builder's page, in their order, each shaped like product above:

200 OKjson
{
  "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:

404 Not Foundjson
{ "error": "not_found" }

taste.dev shows a "nothing shipped here yet" page that links back to the maker.

On taste.dev

URLWhat it is
taste.dev/@{username}/{slug}The product page, in the maker's theme
taste.dev/@{username}/{slug}/opengraph-imageIts 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).