---
title: Achievements API
canonical_url: "https://trophy.so/developers/achievements"
description: "Achievements and badges API: award automatically from metric events, streaks, or API triggers. SDKs for Node.js, Python, Go, Java, PHP, Ruby, and .NET."
---

# The API for achievements and badges

Add achievements and badges to your app in under an hour. Trophy handles trigger evaluation, badge hosting, progress tracking and rarity calculations so you can focus on the user experience. Start for free, scale to millions of users.

[Full feature documentation](https://docs.trophy.so/features/achievements.md)

## Quickstart: three-call integration

Configure your achievements in the Trophy dashboard first, then use this code to track user progress, check unlocks, and mark completions. The full lifecycle takes three calls.

```ts
import { TrophyApiClient } from "@trophyso/node";

const trophy = new TrophyApiClient({ apiKey: process.env.TROPHY_API_KEY });

// 1. Track a metric event (e.g., user completed a lesson)
const eventResponse = await trophy.metrics.event("lessons", {
  user: { id: "user-123" },
  value: 1,
});

console.log("Event ID:", eventResponse.eventId);
console.log("Lifetime total:", eventResponse.total);

// 2. Check if any achievements unlocked from this event
if (eventResponse.achievements.length > 0) {
  for (const achievement of eventResponse.achievements) {
    console.log("Unlocked:", achievement.name, "| Badge:", achievement.badgeUrl);
  }
}

// 3. Fetch all achievements for a user (for profile display, history, etc.)
const userAchievements = await trophy.users.achievements("user-123");

for (const a of userAchievements) {
  console.log(a.name, "| Achieved:", a.achievedAt, "| Rarity:", a.rarity);
}

// 4. Mark an event-triggered achievement complete (e.g., finished onboarding)
const completion = await trophy.achievements.complete("finish-onboarding", {
  user: { id: "user-123" },
});

console.log("Completion ID:", completion.completionId);
console.log("Points awarded:", completion.points);
```

## Why use Trophy's achievements API?

A badge award API looks simple on the surface — store a completion flag, return a URL. The trigger evaluation, deduplication, and progress tracking underneath are where the complexity compounds.

| Consideration | Trophy | Build in-house | Why it matters |
| --- | --- | --- | --- |
| Integration Time | Configure achievements in the dashboard, integrate with one API call. Live in under an hour. | Design trigger evaluation engine, badge hosting mechanism, progress tracking, and rarity calculations. Expect 3-4 weeks for initial setup, with ongoing maintenance required for new achievements and updates. | Achievement systems look simple on the surface but require complex trigger logic for progression thresholds, streak milestonesand compound conditions that grows with every new achievement added. |
| Reliability | Exactly-once achievement completion with built-in deduplication. | You must guarantee achievements are awarded exactly once — not zero times, not twice — even under concurrent events and race conditions. | Double-awarding an achievement erodes user trust and creates support tickets. Missing one frustrates users who earned it and creates a bad experience. Both are hard to debug retroactively. |
| Scalability | Trophy evaluates achievement triggers millions of times a day in real time without performance degradation. | As you add more achievements and users, trigger evaluation becomes a combinatorial problem. Naive implementations degrade quickly and become hard to change at scale. | Every metric event needs to be checked against every relevant achievement which requires careful indexing and query optimization at scale. |
| Ongoing Maintenance | Add and update achievements from the dashboard. No code changes or deployments needed. Non-technical users can do this themselves. | Each new achievement requires code changes for trigger logic, database migrations for new thresholds, and testing across edge cases. Each update requires a deploy, creating a bottleneck between product and engineering. | Product teams want to iterate on achievements frequently. If every change requires a deploy, you create a bottleneck between product and engineering. |
| Feature Development | Badge hosting, rarity calculations, progress tracking, and new trigger types ship regularly. | Features like rarity percentages, progress bars, and compound triggers each require significant development and ongoing maintenance. | Users expect polished achievement experiences — progress indicators, rarity badges, shareable completions. Building each of these in-house adds up. |

## Achievement endpoints

Use Trophy's achievement tracking API to award badges automatically from metric events, streak milestones, or direct API calls. Progress is evaluated in real time with every event you send.

### `POST /metrics/{key}/event`

Send a metric event to track user activity and power achievements.

Docs: https://docs.trophy.so/api-reference/endpoints/metrics/send-a-metric-change-event.md

```ts
// Track a user event
await trophy.metrics.event("lessons", {
    user: {
      id: "user-123"
    },
    value: 1
  }
);

// This single event:
// - Records user activity
// - Evaluates achievement triggers
// - Returns new unlocked achievements
```

### `GET /users/{id}/achievements`

Get a user's achievements. By default returns only completed achievements.

Docs: https://docs.trophy.so/api-reference/endpoints/users/get-a-users-completed-achievements.md

```ts
// Fetch all achievements for a user
const achievements = await trophy.users
  .achievements("user-123");

// Response:
// [
//   { 
//     key: "completed-onboarding", 
//     name: "Completed Onboarding",
//     trigger: "api",
//     achievedAt: "2021-01-01T00:00:00Z",
//     badgeUrl: "https://...", 
//     rarity: 50 
//   }
// ]
```

### `POST /achievements/{key}/complete`

Mark an achievement as completed for a user. Use for API-triggered achievements.

Docs: https://docs.trophy.so/api-reference/endpoints/achievements/mark-an-achievement-as-completed.md

```ts
// Complete an achievement for a user
await trophy.achievements.complete(
  "finish-onboarding", 
  {
    user: { id: "user-123" }
  }
);

// Returns completionId, achievement
// object, and any points awarded
```

## Code examples

### get-achievements.ts

```ts
// Fetch and display achievements

const achievements = await trophy.users
  .achievements("user-123");

// Display badges
for (const a of achievements) {
  console.log(a.name, a.badgeUrl);
}
```

## FAQ

### What is the difference between achievements and badges?

In Trophy, the achievements API and badges API are two sides of the same concept. An achievement is a milestone a user can reach; each achievement has a badge — an image that represents the accomplishment. You configure both the trigger conditions and badge for each achievement in the dashboard.

### How do I trigger achievements automatically?

Trophy's gamification achievements API evaluates three trigger types: metric thresholds (e.g., "wrote 10,000 words"), streak milestones (e.g., "7-day streak"), and direct API calls (e.g., "profile completed") for custom logic. Triggers are evaluated automatically whenever you send a metric event — no polling or scheduled jobs needed.

### How do I award badges programmatically with custom images?

Upload any badge image when creating an achievement in the Trophy dashboard. Trophy hosts image files and returns the badge URL in every API response, so you can award badges programmatically and render them in your app without managing your own asset storage. Alternatively if you already have asset storage, you can pass a custom badge URL to Trophy directly.

### How do I show achievement progress to users?

Use the [get achievements](https://docs.trophy.so/api-reference/endpoints/users/get-a-users-completed-achievements) endpoint to fetch both completed and in-progress achievements. The response includes progress data so you can render progress bars, completion percentages and rarity statistics.

### Can I use achievements for onboarding milestones?

Yes, Trophy's achievements API is well-suited to onboarding sequences — "completed profile", "first project created", "invited a teammate" — triggered via the API when users complete each step. Across Trophy's platform, users who complete an achievement on their first day retain at 33.42% at day 30, compared to 20.36% for users who don't. so designing the first session so an achievement fires before the user leaves is one of the highest-leverage retention decisions you can make.

### Can I display badges in React, React Native, or mobile apps?

Yes. Adding achievements to any app with Trophy uses server-side SDKs (Node.js, Python, Go, Java, PHP, Ruby, and .NET) to handle trigger evaluation and completion logic on your backend. The API returns badge image URLs and completion data that you can render in any frontend — React, React Native, Next.js, Swift, Kotlin, Flutter, or any other framework.
