import { TrophyApiClient } from '@trophyso/node';
const trophy = new TrophyApiClient({
apiKey: 'YOUR_API_KEY'
});
const response = await trophy.metrics.event(
"words-written",
{
user: {
id: 'user-id',
email: 'user@example.com',
tz: 'Europe/London',
subscribedToEmails: true,
attributes: {
department: 'engineering',
role: 'developer'
}
},
value: 750,
attributes: {
category: 'writing',
source: 'mobile-app'
}
}
);from trophy import TrophyApi
client = TrophyApi(api_key='YOUR_API_KEY')
user = UpsertedUser(
id="123",
email="user@example.com",
tz="Europe/London",
subscribedToEmails=True,
attributes={
"department": "engineering",
"role": "developer"
}
)
response = client.metrics.event(
"words-written",
user=user,
value=750,
attributes={
"category": "writing",
"source": "mobile-app"
})import (
"context"
api "github.com/trophyso/trophy-go"
trophyclient "github.com/trophyso/trophy-go/client"
"github.com/trophyso/trophy-go/option"
)
client := trophyclient.NewClient(
option.WithApiKey("YOUR_API_KEY"),
)
response, err := client.Metrics.Event(
context.TODO(),
"words-written",
&api.MetricsEventRequest{
User: &api.UpsertedUser{Id: "user-id"},
Value: 750,
Attributes: map[string]string{
"category": "writing",
"source": "mobile-app",
},
},
)curl --request POST \
--url https://api.trophy.so/v1/metrics/{key}/event \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"user": {
"email": "user@example.com",
"tz": "Europe/London",
"id": "18",
"attributes": {
"department": "engineering",
"role": "developer"
}
},
"value": 750,
"attributes": {
"category": "writing",
"source": "mobile-app"
}
}
'<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trophy.so/v1/metrics/{key}/event",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user' => [
'email' => 'user@example.com',
'tz' => 'Europe/London',
'id' => '18',
'attributes' => [
'department' => 'engineering',
'role' => 'developer'
]
],
'value' => 750,
'attributes' => [
'category' => 'writing',
'source' => 'mobile-app'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.post("https://api.trophy.so/v1/metrics/{key}/event")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user\": {\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\",\n \"id\": \"18\",\n \"attributes\": {\n \"department\": \"engineering\",\n \"role\": \"developer\"\n }\n },\n \"value\": 750,\n \"attributes\": {\n \"category\": \"writing\",\n \"source\": \"mobile-app\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trophy.so/v1/metrics/{key}/event")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user\": {\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\",\n \"id\": \"18\",\n \"attributes\": {\n \"department\": \"engineering\",\n \"role\": \"developer\"\n }\n },\n \"value\": 750,\n \"attributes\": {\n \"category\": \"writing\",\n \"source\": \"mobile-app\"\n }\n}"
response = http.request(request)
puts response.read_body{
"metricId": "d01dcbcb-d51e-4c12-b054-dc811dcdc623",
"eventId": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"total": 750,
"achievements": [
{
"id": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
"trigger": "metric",
"metricId": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
"metricName": "words written",
"metricValue": 500,
"name": "500 words written",
"description": "Write 500 words in the app.",
"achievedAt": "2020-01-01T00:00:00Z"
}
],
"currentStreak": {
"length": 1,
"frequency": "daily",
"started": "2025-04-02",
"periodStart": "2025-03-31",
"periodEnd": "2025-04-05",
"expires": "2025-04-12"
},
"points": {
"xp": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"name": "XP",
"description": null,
"badgeUrl": null,
"total": 10,
"level": {
"id": "1140fe51-6bce-4b44-b0ad-bddc4e123534",
"key": "bronze",
"name": "Bronze",
"description": "Starting level",
"badgeUrl": null,
"points": 0
},
"added": 10,
"awards": [
{
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"awarded": 10,
"date": "2021-01-01T00:00:00Z",
"total": 10,
"trigger": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"type": "metric",
"metricName": "words written",
"metricThreshold": 100,
"points": 10
}
}
]
}
},
"leaderboards": {
"all-time": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123535",
"key": "all-time",
"name": "All-Time Leaderboard",
"description": null,
"rankBy": "metric",
"runUnit": null,
"runInterval": null,
"maxParticipants": 100,
"breakdownAttribute": null,
"metricName": "words written",
"metricKey": "words-written",
"threshold": 10,
"start": "2025-01-01",
"end": null,
"previousRank": null,
"rank": 100
}
}
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Send a metric change event
Increment or decrement the value of a metric for a user.
import { TrophyApiClient } from '@trophyso/node';
const trophy = new TrophyApiClient({
apiKey: 'YOUR_API_KEY'
});
const response = await trophy.metrics.event(
"words-written",
{
user: {
id: 'user-id',
email: 'user@example.com',
tz: 'Europe/London',
subscribedToEmails: true,
attributes: {
department: 'engineering',
role: 'developer'
}
},
value: 750,
attributes: {
category: 'writing',
source: 'mobile-app'
}
}
);from trophy import TrophyApi
client = TrophyApi(api_key='YOUR_API_KEY')
user = UpsertedUser(
id="123",
email="user@example.com",
tz="Europe/London",
subscribedToEmails=True,
attributes={
"department": "engineering",
"role": "developer"
}
)
response = client.metrics.event(
"words-written",
user=user,
value=750,
attributes={
"category": "writing",
"source": "mobile-app"
})import (
"context"
api "github.com/trophyso/trophy-go"
trophyclient "github.com/trophyso/trophy-go/client"
"github.com/trophyso/trophy-go/option"
)
client := trophyclient.NewClient(
option.WithApiKey("YOUR_API_KEY"),
)
response, err := client.Metrics.Event(
context.TODO(),
"words-written",
&api.MetricsEventRequest{
User: &api.UpsertedUser{Id: "user-id"},
Value: 750,
Attributes: map[string]string{
"category": "writing",
"source": "mobile-app",
},
},
)curl --request POST \
--url https://api.trophy.so/v1/metrics/{key}/event \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"user": {
"email": "user@example.com",
"tz": "Europe/London",
"id": "18",
"attributes": {
"department": "engineering",
"role": "developer"
}
},
"value": 750,
"attributes": {
"category": "writing",
"source": "mobile-app"
}
}
'<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trophy.so/v1/metrics/{key}/event",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user' => [
'email' => 'user@example.com',
'tz' => 'Europe/London',
'id' => '18',
'attributes' => [
'department' => 'engineering',
'role' => 'developer'
]
],
'value' => 750,
'attributes' => [
'category' => 'writing',
'source' => 'mobile-app'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.post("https://api.trophy.so/v1/metrics/{key}/event")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user\": {\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\",\n \"id\": \"18\",\n \"attributes\": {\n \"department\": \"engineering\",\n \"role\": \"developer\"\n }\n },\n \"value\": 750,\n \"attributes\": {\n \"category\": \"writing\",\n \"source\": \"mobile-app\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trophy.so/v1/metrics/{key}/event")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user\": {\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\",\n \"id\": \"18\",\n \"attributes\": {\n \"department\": \"engineering\",\n \"role\": \"developer\"\n }\n },\n \"value\": 750,\n \"attributes\": {\n \"category\": \"writing\",\n \"source\": \"mobile-app\"\n }\n}"
response = http.request(request)
puts response.read_body{
"metricId": "d01dcbcb-d51e-4c12-b054-dc811dcdc623",
"eventId": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"total": 750,
"achievements": [
{
"id": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
"trigger": "metric",
"metricId": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
"metricName": "words written",
"metricValue": 500,
"name": "500 words written",
"description": "Write 500 words in the app.",
"achievedAt": "2020-01-01T00:00:00Z"
}
],
"currentStreak": {
"length": 1,
"frequency": "daily",
"started": "2025-04-02",
"periodStart": "2025-03-31",
"periodEnd": "2025-04-05",
"expires": "2025-04-12"
},
"points": {
"xp": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"name": "XP",
"description": null,
"badgeUrl": null,
"total": 10,
"level": {
"id": "1140fe51-6bce-4b44-b0ad-bddc4e123534",
"key": "bronze",
"name": "Bronze",
"description": "Starting level",
"badgeUrl": null,
"points": 0
},
"added": 10,
"awards": [
{
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"awarded": 10,
"date": "2021-01-01T00:00:00Z",
"total": 10,
"trigger": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
"type": "metric",
"metricName": "words written",
"metricThreshold": 100,
"points": 10
}
}
]
}
},
"leaderboards": {
"all-time": {
"id": "0040fe51-6bce-4b44-b0ad-bddc4e123535",
"key": "all-time",
"name": "All-Time Leaderboard",
"description": null,
"rankBy": "metric",
"runUnit": null,
"runInterval": null,
"maxParticipants": 100,
"breakdownAttribute": null,
"metricName": "words written",
"metricKey": "words-written",
"threshold": 10,
"start": "2025-01-01",
"end": null,
"previousRank": null,
"rank": 100
}
}
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Authorizations
Headers
The idempotency key for the event.
The tenant identifier for multi-tenant organisations. Required when the organisation has multi-tenancy enabled. The value should be your internal ID for the tenant. Ignored for single-tenant organisations.
Path Parameters
Unique reference of the metric as set when created.
Body
The user that triggered the event.
Show child attributes
Show child attributes
The value to add to the user's current total for the given metric.
750
Event attributes as key-value pairs. Keys must match existing event attributes set up in the Trophy dashboard.
Show child attributes
Show child attributes
{
"category": "writing",
"source": "mobile-app"
}
Response
Created event
The unique ID of the event.
"0040fe51-6bce-4b44-b0ad-bddc4e123534"
The unique ID of the metric that was updated.
"d01dcbcb-d51e-4c12-b054-dc811dcdc623"
The user's new total progress against the metric.
750
Achievements completed as a result of this event.
Show child attributes
Show child attributes
The user's current streak.
Show child attributes
Show child attributes
A map of points systems by key. Only contains points systems that were affected by the event.
Show child attributes
Show child attributes
A map of leaderboards by key. Only contains leaderboards that were affected by the event.
Show child attributes
Show child attributes
The idempotency key used for the event, if one was provided.
Whether the event was replayed due to idempotency.
Was this page helpful?