From bf456eba3e108a88826d80570d1d7465d2a478b6 Mon Sep 17 00:00:00 2001
From: Charlie Brinicombe <55358291+cbrinicombe13@users.noreply.github.com>
Date: Mon, 21 Jul 2025 23:33:51 +0100
Subject: [PATCH 1/3] Add docs for new identify PUT API
---
...ntify-a-new-user.mdx => create-a-user.mdx} | 0
.../endpoints/users/identify-a-user.mdx | 3 +
api-reference/openapi.yml | 529 +++++++++---------
docs.json | 3 +-
platform/users.mdx | 19 +-
snippets/identify-user-request-block.mdx | 7 +-
6 files changed, 284 insertions(+), 277 deletions(-)
rename api-reference/endpoints/users/{identify-a-new-user.mdx => create-a-user.mdx} (100%)
create mode 100644 api-reference/endpoints/users/identify-a-user.mdx
diff --git a/api-reference/endpoints/users/identify-a-new-user.mdx b/api-reference/endpoints/users/create-a-user.mdx
similarity index 100%
rename from api-reference/endpoints/users/identify-a-new-user.mdx
rename to api-reference/endpoints/users/create-a-user.mdx
diff --git a/api-reference/endpoints/users/identify-a-user.mdx b/api-reference/endpoints/users/identify-a-user.mdx
new file mode 100644
index 0000000..3fbc4e2
--- /dev/null
+++ b/api-reference/endpoints/users/identify-a-user.mdx
@@ -0,0 +1,3 @@
+---
+openapi: put /users/{id}
+---
diff --git a/api-reference/openapi.yml b/api-reference/openapi.yml
index 9267f5c..1bbbd77 100644
--- a/api-reference/openapi.yml
+++ b/api-reference/openapi.yml
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: Trophy
- version: '1.0.4'
+ version: "1.0.4"
paths:
/achievements:
get:
@@ -10,14 +10,14 @@ paths:
tags:
- Achievements
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
- $ref: '#/components/schemas/AchievementWithStatsResponse'
+ $ref: "#/components/schemas/AchievementWithStatsResponse"
examples:
Successful operation:
value:
@@ -47,24 +47,24 @@ paths:
streakLength: 10
completions: 2
completedPercentage: 20
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Achievements not found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Achievements not found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get all achievements and their completion stats
security:
- ApiKeyAuth: []
@@ -83,12 +83,12 @@ paths:
type: string
example: finish-onboarding
responses:
- '201':
+ "201":
description: Successful operation
content:
application/json:
schema:
- $ref: '#/components/schemas/AchievementCompletionResponse'
+ $ref: "#/components/schemas/AchievementCompletionResponse"
examples:
Successful operation:
value:
@@ -100,25 +100,25 @@ paths:
description: Complete the onboarding process.
badgeUrl: https://example.com/badge.png
key: finish-onboarding
- achievedAt: '2021-01-01T00:00:00Z'
- '401':
- description: 'Unauthorized'
+ achievedAt: "2021-01-01T00:00:00Z"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Achievement Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Achievement Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Mark an achievement as completed
security:
- ApiKeyAuth: []
@@ -130,7 +130,7 @@ paths:
type: object
properties:
user:
- $ref: '#/components/schemas/UpdatedUser'
+ $ref: "#/components/schemas/UpdatedUser"
description: The user that completed the achievement.
required:
- user
@@ -157,12 +157,12 @@ paths:
type: string
example: words-written
responses:
- '201':
+ "201":
description: Created event
content:
application/json:
schema:
- $ref: '#/components/schemas/EventResponse'
+ $ref: "#/components/schemas/EventResponse"
examples:
Successful operation:
value:
@@ -177,32 +177,32 @@ paths:
metricValue: 500
name: 500 words written
description: Write 500 words in the app.
- achievedAt: '2020-01-01T00:00:00Z'
+ 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'
- '400':
- description: 'Bad Request'
+ started: "2025-04-02"
+ periodStart: "2025-03-31"
+ periodEnd: "2025-04-05"
+ expires: "2025-04-12"
+ "400":
+ description: "Bad Request"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '401':
- description: 'Unauthorized'
+ $ref: "#/components/schemas/ErrorBody"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Send a metric change event
security:
- ApiKeyAuth: []
@@ -214,7 +214,7 @@ paths:
type: object
properties:
user:
- $ref: '#/components/schemas/UpsertedUser'
+ $ref: "#/components/schemas/UpsertedUser"
description: The user that triggered the event.
value:
type: number
@@ -232,15 +232,15 @@ paths:
user:
email: user@example.com
tz: Europe/London
- id: '18'
+ id: "18"
value: 750
/users:
post:
- description: Identify a new user.
+ description: Create a new user.
operationId: users_create
tags:
- Users
- summary: Identify a new user
+ summary: Create a new user
security:
- ApiKeyAuth: []
requestBody:
@@ -249,15 +249,15 @@ paths:
application/json:
schema:
type: object
- $ref: '#/components/schemas/UpsertedUser'
+ $ref: "#/components/schemas/UpsertedUser"
description: The user object.
responses:
- '201':
+ "201":
description: Identified user
content:
application/json:
schema:
- $ref: '#/components/schemas/User'
+ $ref: "#/components/schemas/User"
examples:
Successful operation:
value:
@@ -265,26 +265,26 @@ paths:
email: user@example.com
tz: Europe/London
subscribedToEmails: true
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
- '400':
- description: 'Bad Request'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
+ "400":
+ description: "Bad Request"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '401':
- description: 'Unauthorized'
+ $ref: "#/components/schemas/ErrorBody"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
/users/{id}:
get:
description: Get a single user.
@@ -303,12 +303,12 @@ paths:
security:
- ApiKeyAuth: []
responses:
- '200':
+ "200":
description: Found user
content:
application/json:
schema:
- $ref: '#/components/schemas/User'
+ $ref: "#/components/schemas/User"
examples:
Successful operation:
value:
@@ -316,38 +316,38 @@ paths:
email: user@example.com
tz: Europe/London
subscribedToEmails: true
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
- '400':
- description: 'Bad Request'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
+ "400":
+ description: "Bad Request"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '401':
- description: 'Unauthorized'
+ $ref: "#/components/schemas/ErrorBody"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
put:
- description: Upsert a user (create or update).
+ description: Upsert a user.
operationId: users_upsert
tags:
- Users
- summary: Upsert a user
+ summary: Identify a user
security:
- ApiKeyAuth: []
parameters:
- name: id
in: path
- description: ID of the user to upsert.
+ description: ID of the user to identify.
required: true
schema:
type: string
@@ -357,19 +357,18 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/UpdatedUser'
+ $ref: "#/components/schemas/UpdatedUser"
description: The user object.
example:
- id: user-id
email: user@example.com
tz: Europe/London
responses:
- '200':
+ "200":
description: Upserted user
content:
application/json:
schema:
- $ref: '#/components/schemas/User'
+ $ref: "#/components/schemas/User"
examples:
Successful operation:
value:
@@ -377,26 +376,26 @@ paths:
email: user@example.com
tz: Europe/London
subscribedToEmails: true
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
- '400':
- description: 'Bad Request'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
+ "400":
+ description: "Bad Request"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '401':
- description: 'Unauthorized'
+ $ref: "#/components/schemas/ErrorBody"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
patch:
description: Update a user.
operationId: users_update
@@ -418,19 +417,19 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/UpdatedUser'
+ $ref: "#/components/schemas/UpdatedUser"
description: The user object.
example:
id: user-id
email: user@example.com
tz: Europe/London
responses:
- '200':
+ "200":
description: Updated user
content:
application/json:
schema:
- $ref: '#/components/schemas/User'
+ $ref: "#/components/schemas/User"
examples:
Successful operation:
value:
@@ -438,32 +437,32 @@ paths:
email: user@example.com
tz: Europe/London
subscribedToEmails: true
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
- '400':
- description: 'Bad Request'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
+ "400":
+ description: "Bad Request"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'User Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "User Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '401':
- description: 'Unauthorized'
+ $ref: "#/components/schemas/ErrorBody"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
/users/{id}/metrics:
get:
description: Get a single user's progress against all active metrics.
@@ -479,14 +478,14 @@ paths:
type: string
example: userId
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
- $ref: '#/components/schemas/MetricResponse'
+ $ref: "#/components/schemas/MetricResponse"
examples:
Successful operation:
value:
@@ -501,14 +500,14 @@ paths:
name: Novice Writer
metricId: d01dcbcb-d51e-4c12-b054-dc811dcdc623
metricValue: 500
- achievedAt: '2021-01-01T00:00:00Z'
+ achievedAt: "2021-01-01T00:00:00Z"
badgeUrl: https://example.com/badge1.png
- id: 8a07f2d0-9c72-4de1-bf92-9530ae82b4b6
trigger: metric
name: Intermediate Writer
metricId: d01dcbcb-d51e-4c12-b054-dc811dcdc623
metricValue: 1000
- achievedAt: '2021-01-02T00:00:00Z'
+ achievedAt: "2021-01-02T00:00:00Z"
badgeUrl: https://example.com/badge2.png
- id: 2090d038-aa04-4048-ab2e-e2b7bf2d3b9f
trigger: metric
@@ -516,24 +515,24 @@ paths:
metricId: d01dcbcb-d51e-4c12-b054-dc811dcdc623
metricValue: 2000
achievedAt: null
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'User Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "User Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get all metrics for a user
security:
- ApiKeyAuth: []
@@ -559,12 +558,12 @@ paths:
type: string
example: key
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
- $ref: '#/components/schemas/MetricResponse'
+ $ref: "#/components/schemas/MetricResponse"
examples:
Successful operation:
value:
@@ -579,13 +578,13 @@ paths:
name: Novice Writer
metricId: d01dcbcb-d51e-4c12-b054-dc811dcdc623
metricValue: 500
- achievedAt: '2021-01-01T00:00:00Z'
+ achievedAt: "2021-01-01T00:00:00Z"
- id: 8a07f2d0-9c72-4de1-bf92-9530ae82b4b6
trigger: metric
name: Intermediate Writer
metricId: d01dcbcb-d51e-4c12-b054-dc811dcdc623
metricValue: 1000
- achievedAt: '2021-01-02T00:00:00Z'
+ achievedAt: "2021-01-02T00:00:00Z"
- id: 2090d038-aa04-4048-ab2e-e2b7bf2d3b9f
trigger: metric
name: Expert Writer
@@ -593,24 +592,24 @@ paths:
metricValue: 2000
achievedAt: null
badgeUrl: https://example.com/badge.png
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a single metric for a user
security:
- ApiKeyAuth: []
@@ -653,7 +652,7 @@ paths:
schema:
type: string
format: date
- example: '2024-01-01'
+ example: "2024-01-01"
- name: endDate
in: query
description: The end date for the data range in YYYY-MM-DD format. The endDate must be after the startDate, and the date range must not exceed 400 days.
@@ -661,9 +660,9 @@ paths:
schema:
type: string
format: date
- example: '2024-01-31'
+ example: "2024-01-31"
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
@@ -676,7 +675,7 @@ paths:
type: string
format: date
description: The date of the data point. For weekly or monthly aggregations, this is the first date of the period.
- example: '2024-01-01'
+ example: "2024-01-01"
total:
type: number
format: double
@@ -694,33 +693,33 @@ paths:
examples:
Successful operation:
value:
- - date: '2024-01-01'
+ - date: "2024-01-01"
total: 100
change: 100
- - date: '2024-01-02'
+ - date: "2024-01-02"
total: 300
change: 200
- - date: '2024-01-03'
+ - date: "2024-01-03"
total: 600
change: 300
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a summary of metric events over time
security:
- ApiKeyAuth: []
@@ -739,14 +738,14 @@ paths:
type: string
example: userId
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
- $ref: '#/components/schemas/CompletedAchievementResponse'
+ $ref: "#/components/schemas/CompletedAchievementResponse"
examples:
Successful operation:
value:
@@ -754,7 +753,7 @@ paths:
trigger: api
key: completed-onboarding
name: Completed Onboarding
- achievedAt: '2021-01-01T00:00:00Z'
+ achievedAt: "2021-01-01T00:00:00Z"
badgeUrl: https://example.com/badge2.png
- id: d01dcbcb-d51e-4c12-b054-dc811dcdc623
trigger: metric
@@ -763,33 +762,33 @@ paths:
metricValue: 500
metricName: words written
name: Novice Writer
- achievedAt: '2021-02-01T00:00:00Z'
+ achievedAt: "2021-02-01T00:00:00Z"
badgeUrl: https://example.com/badge1.png
- id: d01dcbcb-d51e-4c12-b054-dc811dcdc624
trigger: streak
key: 3-day-streak
streakLength: 3
name: 3-Day Streak
- achievedAt: '2021-03-01T00:00:00Z'
+ achievedAt: "2021-03-01T00:00:00Z"
badgeUrl: https://example.com/badge2.png
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a user's completed achievements
security:
- ApiKeyAuth: []
@@ -816,62 +815,62 @@ paths:
The number of past streak periods to include in the streakHistory field of the
response.
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
type: object
- $ref: '#/components/schemas/StreakResponse'
+ $ref: "#/components/schemas/StreakResponse"
examples:
Successful operation:
value:
length: 1
frequency: weekly
- started: '2025-04-02'
- periodStart: '2025-03-31'
- periodEnd: '2025-04-05'
- expires: '2025-04-12'
+ started: "2025-04-02"
+ periodStart: "2025-03-31"
+ periodEnd: "2025-04-05"
+ expires: "2025-04-12"
streakHistory:
- - periodStart: '2025-03-30'
- periodEnd: '2025-04-05'
+ - periodStart: "2025-03-30"
+ periodEnd: "2025-04-05"
length: 1
- - periodStart: '2025-04-06'
- periodEnd: '2025-04-12'
+ - periodStart: "2025-04-06"
+ periodEnd: "2025-04-12"
length: 2
- - periodStart: '2025-04-13'
- periodEnd: '2025-04-19'
+ - periodStart: "2025-04-13"
+ periodEnd: "2025-04-19"
length: 3
- - periodStart: '2025-04-20'
- periodEnd: '2025-04-26'
+ - periodStart: "2025-04-20"
+ periodEnd: "2025-04-26"
length: 0
- - periodStart: '2025-04-27'
- periodEnd: '2025-05-03'
+ - periodStart: "2025-04-27"
+ periodEnd: "2025-05-03"
length: 1
- - periodStart: '2025-05-04'
- periodEnd: '2025-05-10'
+ - periodStart: "2025-05-04"
+ periodEnd: "2025-05-10"
length: 2
- - periodStart: '2025-05-11'
- periodEnd: '2025-05-17'
+ - periodStart: "2025-05-11"
+ periodEnd: "2025-05-17"
length: 3
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a user's streak status
security:
- ApiKeyAuth: []
@@ -898,12 +897,12 @@ paths:
maximum: 100
description: The number of recent point awards to return.
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
- $ref: '#/components/schemas/GetUserPointsResponse'
+ $ref: "#/components/schemas/GetUserPointsResponse"
examples:
Successful operation:
value:
@@ -911,7 +910,7 @@ paths:
awards:
- id: 0040fe51-6bce-4b44-b0ad-bddc4e123534
awarded: 10
- date: '2021-01-01T00:00:00Z'
+ date: "2021-01-01T00:00:00Z"
total: 100
trigger:
id: 0040fe51-6bce-4b44-b0ad-bddc4e123534
@@ -919,24 +918,24 @@ paths:
points: 10
metricName: words written
metricThreshold: 1000
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a user's points data
security:
- ApiKeyAuth: []
@@ -972,7 +971,7 @@ paths:
schema:
type: string
format: date
- example: '2024-01-01'
+ example: "2024-01-01"
- name: endDate
in: query
description: The end date for the data range in YYYY-MM-DD format. The endDate must be after the startDate, and the date range must not exceed 400 days.
@@ -980,9 +979,9 @@ paths:
schema:
type: string
format: date
- example: '2024-01-31'
+ example: "2024-01-31"
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
@@ -995,7 +994,7 @@ paths:
type: string
format: date
description: The date of the data point. For weekly or monthly aggregations, this is the first date of the period.
- example: '2024-01-01'
+ example: "2024-01-01"
total:
type: number
format: double
@@ -1013,33 +1012,33 @@ paths:
examples:
Successful operation:
value:
- - date: '2024-01-01'
+ - date: "2024-01-01"
total: 100
change: 100
- - date: '2024-01-02'
+ - date: "2024-01-02"
total: 300
change: 200
- - date: '2024-01-03'
+ - date: "2024-01-03"
total: 600
change: 300
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '422':
- description: 'Unprocessible Entity'
+ $ref: "#/components/schemas/ErrorBody"
+ "422":
+ description: "Unprocessible Entity"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a summary of points events over time
security:
- ApiKeyAuth: []
@@ -1050,12 +1049,12 @@ paths:
tags:
- Points
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
- $ref: '#/components/schemas/PointsSummaryResponse'
+ $ref: "#/components/schemas/PointsSummaryResponse"
examples:
Successful operation:
value:
@@ -1092,18 +1091,18 @@ paths:
- from: 901
to: 1000
users: 0
- '401':
- description: 'Unauthorized'
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
- '404':
- description: 'Not Found'
+ $ref: "#/components/schemas/ErrorBody"
+ "404":
+ description: "Not Found"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get a breakdown of users by points
security:
- ApiKeyAuth: []
@@ -1114,14 +1113,14 @@ paths:
tags:
- Points
responses:
- '200':
+ "200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
- $ref: '#/components/schemas/PointsTriggerResponse'
+ $ref: "#/components/schemas/PointsTriggerResponse"
examples:
Successful operation:
value:
@@ -1132,29 +1131,29 @@ paths:
metricId: 0040fe51-6bce-4b44-b0ad-bddc4e123534
metricName: words written
metricThreshold: 1000
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
- id: 0040fe51-6bce-4b44-b0ad-bddc4e123536
type: streak
points: 10
status: active
streakLengthThreshold: 7
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
- id: 0040fe51-6bce-4b44-b0ad-bddc4e123535
type: achievement
points: 50
status: active
achievementId: 0040fe51-6bce-4b44-b0ad-bddc4e123535
achievementName: finish onboarding
- created: '2021-01-01T00:00:00Z'
- updated: '2021-01-01T00:00:00Z'
- '401':
- description: 'Unauthorized'
+ created: "2021-01-01T00:00:00Z"
+ updated: "2021-01-01T00:00:00Z"
+ "401":
+ description: "Unauthorized"
content:
application/json:
schema:
- $ref: '#/components/schemas/ErrorBody'
+ $ref: "#/components/schemas/ErrorBody"
summary: Get all points triggers
security:
- ApiKeyAuth: []
@@ -1183,7 +1182,7 @@ components:
type: integer
description: The length of the user's current streak.
frequency:
- $ref: '#/components/schemas/StreakFrequency'
+ $ref: "#/components/schemas/StreakFrequency"
description: The frequency of the streak.
started:
type: string
@@ -1209,7 +1208,7 @@ components:
type: object
description: An object representing the user's streak after sending a metric event.
allOf:
- - $ref: '#/components/schemas/BaseStreakResponse'
+ - $ref: "#/components/schemas/BaseStreakResponse"
- type: object
properties:
extended:
@@ -1220,7 +1219,7 @@ components:
type: object
description: An object representing the user's streak.
allOf:
- - $ref: '#/components/schemas/BaseStreakResponse'
+ - $ref: "#/components/schemas/BaseStreakResponse"
- type: object
properties:
streakHistory:
@@ -1237,12 +1236,12 @@ components:
type: string
format: date
description: The date this streak period started.
- example: '2025-03-31'
+ example: "2025-03-31"
periodEnd:
type: string
format: date
description: The date this streak period ended.
- example: '2025-04-05'
+ example: "2025-04-05"
length:
type: integer
description: The length of the user's streak during this period.
@@ -1261,7 +1260,7 @@ components:
type:
type: string
description: The type of trigger
- enum: ['metric', 'achievement', 'streak']
+ enum: ["metric", "achievement", "streak"]
points:
type: number
description: The points awarded by this trigger.
@@ -1294,7 +1293,7 @@ components:
type: number
description: The user's total points after this award occurred.
trigger:
- $ref: '#/components/schemas/PointsTrigger'
+ $ref: "#/components/schemas/PointsTrigger"
GetUserPointsResponse:
title: GetUserPointsResponse
type: object
@@ -1306,12 +1305,12 @@ components:
type: array
description: Array of trigger awards that added points.
items:
- $ref: '#/components/schemas/PointsAward'
+ $ref: "#/components/schemas/PointsAward"
MetricEventPointsResponse:
title: MetricEventPointsResponse
type: object
allOf:
- - $ref: '#/components/schemas/GetUserPointsResponse'
+ - $ref: "#/components/schemas/GetUserPointsResponse"
- type: object
properties:
added:
@@ -1330,7 +1329,7 @@ components:
description: The name of this achievement.
trigger:
type: string
- enum: ['metric', 'streak', 'api']
+ enum: ["metric", "streak", "api"]
description: The trigger of the achievement.
description:
type: string
@@ -1358,7 +1357,7 @@ components:
type: string
description: The name of the metric associated with this achievement (only applicable if trigger = 'metric')
currentStreak:
- $ref: '#/components/schemas/MetricEventStreakResponse'
+ $ref: "#/components/schemas/MetricEventStreakResponse"
description: >-
The user's current streak for the metric, if the metric has streaks
enabled.
@@ -1370,7 +1369,7 @@ components:
title: CompletedAchievementResponse
type: object
allOf:
- - $ref: '#/components/schemas/AchievementResponse'
+ - $ref: "#/components/schemas/AchievementResponse"
- type: object
properties:
achievedAt:
@@ -1381,7 +1380,7 @@ components:
title: AchievementWithStatsResponse
type: object
allOf:
- - $ref: '#/components/schemas/AchievementResponse'
+ - $ref: "#/components/schemas/AchievementResponse"
- type: object
properties:
completions:
@@ -1408,7 +1407,7 @@ components:
description: The name of the metric.
example: Words written
status:
- $ref: '#/components/schemas/MetricStatus'
+ $ref: "#/components/schemas/MetricStatus"
description: The status of the metric.
current:
type: number
@@ -1418,7 +1417,7 @@ components:
achievements:
type: array
items:
- $ref: '#/components/schemas/CompletedAchievementResponse'
+ $ref: "#/components/schemas/CompletedAchievementResponse"
description: >-
A list of the metric's achievements and the user's progress towards
each.
@@ -1456,7 +1455,7 @@ components:
type: object
description: An object with editable user fields.
allOf:
- - $ref: '#/components/schemas/UpdatedUser'
+ - $ref: "#/components/schemas/UpdatedUser"
- type: object
properties:
id:
@@ -1470,7 +1469,7 @@ components:
type: object
description: A user of your application.
allOf:
- - $ref: '#/components/schemas/UpsertedUser'
+ - $ref: "#/components/schemas/UpsertedUser"
- type: object
properties:
control:
@@ -1481,12 +1480,12 @@ components:
type: string
format: date-time
description: The date and time the user was created, in ISO 8601 format.
- example: '2021-01-01T00:00:00Z'
+ example: "2021-01-01T00:00:00Z"
updated:
type: string
format: date-time
description: The date and time the user was last updated, in ISO 8601 format.
- example: '2021-01-01T00:00:00Z'
+ example: "2021-01-01T00:00:00Z"
ErrorBody:
title: ErrorBody
type: object
@@ -1504,7 +1503,7 @@ components:
description: The unique ID of the completion.
example: 0040fe51-6bce-4b44-b0ad-bddc4e123534
achievement:
- $ref: '#/components/schemas/CompletedAchievementResponse'
+ $ref: "#/components/schemas/CompletedAchievementResponse"
required:
- completionId
- achievement
@@ -1528,15 +1527,15 @@ components:
achievements:
type: array
items:
- $ref: '#/components/schemas/CompletedAchievementResponse'
+ $ref: "#/components/schemas/CompletedAchievementResponse"
description: Achievements completed as a result of this event.
currentStreak:
- $ref: '#/components/schemas/MetricEventStreakResponse'
+ $ref: "#/components/schemas/MetricEventStreakResponse"
description: >-
The user's current streak for the metric, if the metric has streaks
enabled.
points:
- $ref: '#/components/schemas/MetricEventPointsResponse'
+ $ref: "#/components/schemas/MetricEventPointsResponse"
description: >-
The points added by this event, and a breakdown of the points
awards that added points.
@@ -1566,7 +1565,7 @@ components:
to the greatest number of points a user has, rounded up to the nearest
power of 10.
items:
- $ref: '#/components/schemas/PointsRange'
+ $ref: "#/components/schemas/PointsRange"
PointsTriggerResponse:
title: PointsTriggerResponse
type: object
@@ -1576,14 +1575,14 @@ components:
description: The unique ID of the trigger.
type:
type: string
- enum: ['metric', 'achievement', 'streak']
+ enum: ["metric", "achievement", "streak"]
description: The type of trigger.
points:
type: number
description: The points awarded by this trigger.
status:
type: string
- enum: ['active', 'archived']
+ enum: ["active", "archived"]
description: The status of the trigger.
achievementId:
type: string
diff --git a/docs.json b/docs.json
index 7575d68..48a1814 100644
--- a/docs.json
+++ b/docs.json
@@ -134,7 +134,8 @@
{
"group": "Users",
"pages": [
- "api-reference/endpoints/users/identify-a-new-user",
+ "api-reference/endpoints/users/identify-a-user",
+ "api-reference/endpoints/users/create-a-user",
"api-reference/endpoints/users/get-a-single-user",
"api-reference/endpoints/users/update-a-user",
"api-reference/endpoints/users/get-all-metrics-for-a-user",
diff --git a/platform/users.mdx b/platform/users.mdx
index b3d303c..b7c4667 100644
--- a/platform/users.mdx
+++ b/platform/users.mdx
@@ -76,6 +76,8 @@ In this case, if this is the user's first interaction (i.e. they are a new user)
However if Trophy finds an existing record with the same `id`, then Trophy will update any details of the user that are passed through.
+In other words, inline identification is by means of an `UPSERT` operation.
+
```mermaid
@@ -107,25 +109,28 @@ This is why we recommend starting with inline identification first, then explori
### Explicit Identification
-Explicit identification is when you write code in your application that explicitly identifies users and updates their attributes, and is useful if you want complete control over how and when that happens.
+Explicit identification is when you write code in your application that explicitly tells Trophy about users seperate from any metric interactions. This is useful if you want complete control over how and when Trophy learns about your users.
Scenarios where you might want to use explicit identification might be:
- You want to tell Trophy about new users immediately on sign-up, before they increment a metric
+- You track a lot of metrics in Trophy, and don't want to repeat inline identification code.
- You want to only tell Trophy about a specific cohort of users, of which you control the conditions around
-- The system that manages your users is seperate to the system you want to gamify using Trophy
-In this case, you can tell Trophy about new users using the [User Identification API](/api-reference/endpoints/users/identify-a-new-user).
+In this case, you can tell Trophy about new users using the [User Identification API](/api-reference/endpoints/users/identify-a-user).
- Even if you use explicit identification, the [metric tracking
- API](/api-reference/endpoints/metrics/send-a-metric-change-event) will always
- create new and update existing users to ensure your user data is always in
- sync.
+ Just like in inline identification, explicit identifcation also works by means
+ of an `UPSERT` operation meaning all user attributes are kept in sync with
+ Trophy automatically.
+## Creating Users
+
+To explicitly create a new user in Trophy, use the [Create User API](/api-reference/endpoints/users/create-a-user).
+
## Keeping Users Up To Date
To tell Trophy about an update to a user in your platform you can use the [Update User API](/api-reference/endpoints/users/update-a-user).
diff --git a/snippets/identify-user-request-block.mdx b/snippets/identify-user-request-block.mdx
index 4133e44..552108f 100644
--- a/snippets/identify-user-request-block.mdx
+++ b/snippets/identify-user-request-block.mdx
@@ -1,15 +1,14 @@
```bash cURL
-curl --request POST \
- --url https://app.trophy.so/api/users \
+curl --request PUT \
+ --url https://app.trophy.so/api/users/{id} \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: ' \
--data '{
"email": "user@example.com",
"name": "User",
"tz": "Europe/London",
- "subscribeToEmails": true,
- "id": "user-id"
+ "subscribeToEmails": true
}'
```
From 18f8d52446b0348d7cf3fd8f8cf23eda70a8d5a0 Mon Sep 17 00:00:00 2001
From: Charlie Brinicombe <55358291+cbrinicombe13@users.noreply.github.com>
Date: Tue, 22 Jul 2025 16:14:46 +0100
Subject: [PATCH 2/3] Add GA4
---
docs.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/docs.json b/docs.json
index 48a1814..ff95606 100644
--- a/docs.json
+++ b/docs.json
@@ -29,6 +29,11 @@
"og:image": "/assets/og.png"
}
},
+ "integrations": {
+ "ga4": {
+ "measurementId": "G-R146N3CQHE"
+ }
+ },
"navigation": {
"tabs": [
{
From 2c7fad743e6e8e29fc2608cc6ff523b6e0fefe04 Mon Sep 17 00:00:00 2001
From: Charlie Brinicombe <55358291+cbrinicombe13@users.noreply.github.com>
Date: Tue, 22 Jul 2025 16:17:48 +0100
Subject: [PATCH 3/3] Tweaks
---
api-reference/openapi.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/api-reference/openapi.yml b/api-reference/openapi.yml
index 1bbbd77..66a1c8b 100644
--- a/api-reference/openapi.yml
+++ b/api-reference/openapi.yml
@@ -337,8 +337,8 @@ paths:
schema:
$ref: "#/components/schemas/ErrorBody"
put:
- description: Upsert a user.
- operationId: users_upsert
+ description: Identify a user.
+ operationId: users_identify
tags:
- Users
summary: Identify a user