CustomizeCard stats

Card stats

Choose 2–4 stats to show under your name, in the order you want them.

The stat row under your name is your card. You pick which stats it shows and in what order; the API computes the values. The schema is card-1.json (Schemas).

The catalog

idLabelValue
projectsProjectsProjects on the profile
starsStarsTotal GitHub stars across the profile's projects
followersFollowersBuilders following this profile
postsPostsPosts published (deleted posts excluded)
streakStreakCurrent Daily Taste streak in days (0 once broken)
badgesBadgesBadges earned
shippedShippedShip posts published (kind ship, deleted excluded)
joinedJoinedThe month the builder joined, as "YYYY-MM"

Every value is an integer ≥ 0 except joined, which is a "YYYY-MM" string. Stats show even when the matching section is hidden: they're the builder's choice.

Ids are stable forever. New stats can join the catalog at any time without a version bump, so build pickers from the live catalog rather than a hardcoded list:

bash
curl https://api.taste.dev/profile/stats/catalog
Responsejson
{
  "stats": [
    { "id": "projects", "label": "Projects", "description": "Projects on the profile." },
    { "id": "stars", "label": "Stars", "description": "Total GitHub stars across the profile's projects." },
    { "id": "followers", "label": "Followers", "description": "Builders following this profile." },
    { "id": "posts", "label": "Posts", "description": "Posts published (deleted posts excluded)." },
    { "id": "streak", "label": "Streak", "description": "Current Daily Taste streak in days (0 once broken)." },
    { "id": "badges", "label": "Badges", "description": "Badges earned." },
    { "id": "shipped", "label": "Shipped", "description": "Ship posts published (kind \"ship\")." },
    { "id": "joined", "label": "Joined", "description": "Month the builder joined, as YYYY-MM." }
  ]
}

The catalog is public and cached for a day.

Rules

  • 2 to 4 stats, no repeats, each a catalog id.
  • Order is yours. The page shows them left to right in the order you send.
  • Default. A profile that never picked shows ["stars", "projects", "followers"].
  • Retired stats disappear quietly. If an id is ever retired, cards that chose it drop it when read, and are topped up from the defaults so a card always shows at least 2.

Pick your stats

cURLbash
curl -X PUT https://api.taste.dev/profile/card \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"stats": ["streak", "stars", "projects"]}'
JavaScriptjs
await fetch('https://api.taste.dev/profile/card', {
  method: 'PUT',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ stats: ['streak', 'stars', 'projects'] }),
});

The body's stats is exactly the card's stats:

Request bodyjson
{ "stats": ["streak", "stars", "projects"] }

The response is the saved card:

200 OKjson
{ "card": { "schema": 1, "stats": ["streak", "stars", "projects"] } }

Anything else is 400, with a message that names the problem and lists the known ids:

400 Bad Requestjson
{
  "error": "invalid",
  "message": "unknown stat id \"karma\"; known ids: projects, stars, followers, posts, streak, badges, shipped, joined"
}

The other messages are stats must list 2 to 4 stat ids (got 5); known ids: … and duplicate stat id "stars".

Reading the card

Every page from GET /public/u/{username} carries both the choice and the values:

json
{
  "card": { "schema": 1, "stats": ["streak", "stars", "joined"] },
  "stats": [
    { "id": "streak", "label": "Streak", "value": 12 },
    { "id": "stars", "label": "Stars", "value": 1692 },
    { "id": "joined", "label": "Joined", "value": "2026-09" }
  ]
}

stats is in card order and holds only the chosen stats. label is the English display label.

Showing stats

taste.dev renders the row as pills: the value in the theme's display font, a small glyph in the highlight color, and the label in muted caps. Counts are compact (999, 1.2k, 12k, 1.3M), joined reads as a month (Sep '26), and zeros are muted. You're free to render them your own way.