Overview

Garden.gg uses gamification to make gardening more engaging. Earn XP for garden activities, unlock badges for milestones, maintain care streaks, and compete on leaderboards. The Achievements API lets you query all gamification data.

XP Values

Every garden activity earns experience points:

ActivityXP Earned
Watering5
Note / Observation5
Pest treatment5
Thinning5
Fertilizing10
Pruning10
Mulching10
Weeding10
Training/Staking10
Sowing10
Harvesting15
Transplanting15
Photo upload20

Achievement Categories

CategoryDescription
PlantingMilestones for number of plants grown
HarvestingMilestones for total harvest weight and variety
StreaksConsecutive days of garden care activity
CommunitySharing gardens, helping others, public profiles
DiscoveryGrowing new plant types, trying new techniques

Endpoints

MethodPathDescriptionAuth Required
GET/achievementsList all achievements with statusYes
GET/achievements/badgesList available badgesYes
GET/gamification/statsGet your gamification statsYes
GET/leaderboardGet the leaderboardYes
GET/leaderboard/friendsGet friends-only leaderboardYes

List Achievements

Retrieve all achievements and your unlock status for each.

GET /achievements

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Items per page (max 100)
categorystringFilter by category
unlockedbooleanFilter by unlock status (true/false)

Response 200 OK

{
  "data": [
    {
      "id": "ach_first_seed",
      "name": "First Seed",
      "description": "Sow your first seed",
      "category": "Planting",
      "icon_url": "https://cdn.garden.gg/badges/first_seed.png",
      "xp_reward": 50,
      "unlocked": true,
      "unlocked_at": "2026-02-15T09:30:00Z"
    },
    {
      "id": "ach_green_thumb",
      "name": "Green Thumb",
      "description": "Grow 10 different plant types",
      "category": "Discovery",
      "icon_url": "https://cdn.garden.gg/badges/green_thumb.png",
      "xp_reward": 200,
      "unlocked": false,
      "unlocked_at": null,
      "progress": {
        "current": 7,
        "target": 10
      }
    },
    {
      "id": "ach_harvest_king",
      "name": "Harvest Royalty",
      "description": "Harvest over 10kg total",
      "category": "Harvesting",
      "icon_url": "https://cdn.garden.gg/badges/harvest_king.png",
      "xp_reward": 500,
      "unlocked": false,
      "unlocked_at": null,
      "progress": {
        "current": 4250,
        "target": 10000,
        "unit": "grams"
      }
    }
  ],
  "total": 42,
  "page": 1,
  "per_page": 20
}

Examples

cURL

# List unlocked achievements
curl -X GET "https://garden.gg/api/v1/achievements?unlocked=true" \
  -H "Authorization: Bearer gg_live_your_api_key_here"

# List planting achievements
curl -X GET "https://garden.gg/api/v1/achievements?category=Planting" \
  -H "Authorization: Bearer gg_live_your_api_key_here"

Python

import requests

headers = {"Authorization": "Bearer gg_live_your_api_key_here"}

# Get all achievements and show progress
response = requests.get(
    "https://garden.gg/api/v1/achievements",
    headers=headers,
    params={"per_page": 100},
)

achievements = response.json()
for ach in achievements["data"]:
    status = "Unlocked" if ach["unlocked"] else "Locked"
    progress = ""
    if not ach["unlocked"] and "progress" in ach:
        p = ach["progress"]
        progress = f" ({p['current']}/{p['target']})"
    print(f"[{status}] {ach['name']}: {ach['description']}{progress}")

Node.js

const response = await fetch(
  "https://garden.gg/api/v1/achievements?per_page=100",
  { headers: { Authorization: "Bearer gg_live_your_api_key_here" } }
);

const { data: achievements } = await response.json();
const unlocked = achievements.filter((a) => a.unlocked);
const locked = achievements.filter((a) => !a.unlocked);

console.log(`Unlocked: ${unlocked.length} / ${achievements.length}`);
locked.forEach((a) => {
  const progress = a.progress
    ? ` (${a.progress.current}/${a.progress.target})`
    : "";
  console.log(`  - ${a.name}${progress}`);
});

List Badges

Retrieve all available badges. Badges are visual representations of achievements displayed on your profile.

GET /achievements/badges

Response 200 OK

{
  "data": [
    {
      "id": "bdg_seedling",
      "name": "Seedling",
      "description": "Reach level 5",
      "icon_url": "https://cdn.garden.gg/badges/seedling.png",
      "tier": "bronze",
      "unlocked": true
    },
    {
      "id": "bdg_grower",
      "name": "Grower",
      "description": "Reach level 15",
      "icon_url": "https://cdn.garden.gg/badges/grower.png",
      "tier": "silver",
      "unlocked": false
    },
    {
      "id": "bdg_master_gardener",
      "name": "Master Gardener",
      "description": "Reach level 30",
      "icon_url": "https://cdn.garden.gg/badges/master_gardener.png",
      "tier": "gold",
      "unlocked": false
    }
  ]
}

Gamification Stats

Get your current gamification summary.

GET /gamification/stats

Response 200 OK

{
  "user_id": "usr_a1b2c3d4",
  "xp": 2450,
  "level": 12,
  "xp_to_next_level": 550,
  "xp_for_next_level": 3000,
  "streak_days": 14,
  "longest_streak": 31,
  "badge_count": 8,
  "total_badges": 24,
  "achievements_unlocked": 15,
  "total_achievements": 42,
  "total_harvests": 23,
  "total_harvest_grams": 4250,
  "plants_grown": 7,
  "gardens_count": 2
}

Examples

cURL

curl -X GET "https://garden.gg/api/v1/gamification/stats" \
  -H "Authorization: Bearer gg_live_your_api_key_here"

Python

import requests

headers = {"Authorization": "Bearer gg_live_your_api_key_here"}
response = requests.get(
    "https://garden.gg/api/v1/gamification/stats",
    headers=headers,
)

stats = response.json()
print(f"Level {stats['level']}{stats['xp']} XP")
print(f"Streak: {stats['streak_days']} days (best: {stats['longest_streak']})")
print(f"Badges: {stats['badge_count']}/{stats['total_badges']}")
print(f"Harvested: {stats['total_harvest_grams']}g from {stats['total_harvests']} harvests")

Node.js

const response = await fetch("https://garden.gg/api/v1/gamification/stats", {
  headers: { Authorization: "Bearer gg_live_your_api_key_here" },
});

const stats = await response.json();
console.log(`Level ${stats.level} — ${stats.xp} XP`);
console.log(`Streak: ${stats.streak_days} days (best: ${stats.longest_streak})`);
console.log(`Badges: ${stats.badge_count}/${stats.total_badges}`);

Leaderboard

Retrieve the global leaderboard, ranked by XP.

GET /leaderboard

Query Parameters

ParameterTypeDefaultDescription
periodstringweeklyOne of: weekly, monthly, all_time
pageinteger1Page number
per_pageinteger20Items per page (max 100)

Response 200 OK

{
  "period": "weekly",
  "data": [
    {
      "rank": 1,
      "user": {
        "username": "plant_master",
        "display_name": "Plant Master",
        "level": 28,
        "avatar_url": "https://cdn.garden.gg/avatars/plant_master.jpg"
      },
      "xp": 890,
      "activities": 47
    },
    {
      "rank": 2,
      "user": {
        "username": "green_thumb",
        "display_name": "Green Thumb",
        "level": 12,
        "avatar_url": "https://cdn.garden.gg/avatars/green_thumb.jpg"
      },
      "xp": 735,
      "activities": 38
    }
  ],
  "your_rank": 15,
  "total": 1234,
  "page": 1,
  "per_page": 20
}

Examples

cURL

# Get monthly leaderboard
curl -X GET "https://garden.gg/api/v1/leaderboard?period=monthly" \
  -H "Authorization: Bearer gg_live_your_api_key_here"

Python

import requests

headers = {"Authorization": "Bearer gg_live_your_api_key_here"}
response = requests.get(
    "https://garden.gg/api/v1/leaderboard",
    headers=headers,
    params={"period": "weekly"},
)

board = response.json()
print(f"Your rank: #{board['your_rank']} (out of {board['total']})")
for entry in board["data"][:5]:
    print(f"  #{entry['rank']} {entry['user']['display_name']}{entry['xp']} XP")

Node.js

const response = await fetch(
  "https://garden.gg/api/v1/leaderboard?period=all_time",
  { headers: { Authorization: "Bearer gg_live_your_api_key_here" } }
);

const board = await response.json();
console.log(`Your rank: #${board.your_rank}`);
board.data.forEach((e) =>
  console.log(`  #${e.rank} ${e.user.display_name} — ${e.xp} XP`)
);

Friends Leaderboard

Retrieve a leaderboard limited to users you follow.

GET /leaderboard/friends

Same query parameters and response format as the global leaderboard. Returns only users you follow, plus your own entry.

Error Responses

ScenarioHTTP StatusError Code
Invalid period value400VALIDATION_ERROR
Invalid category filter400VALIDATION_ERROR
Not authenticated401UNAUTHORIZED