diff --git a/api-reference/endpoints/points/get-all-points-triggers.mdx b/api-reference/endpoints/points/get-all-points-triggers.mdx deleted file mode 100644 index 6673a6b..0000000 --- a/api-reference/endpoints/points/get-all-points-triggers.mdx +++ /dev/null @@ -1,3 +0,0 @@ ---- -openapi: get /points/triggers ---- diff --git a/api-reference/endpoints/points/get-points-summary.mdx b/api-reference/endpoints/points/get-points-summary.mdx index 7ac2423..cca6764 100644 --- a/api-reference/endpoints/points/get-points-summary.mdx +++ b/api-reference/endpoints/points/get-points-summary.mdx @@ -1,3 +1,3 @@ --- -openapi: get /points/summary +openapi: get /points/{key}/summary --- diff --git a/api-reference/endpoints/points/get-points.mdx b/api-reference/endpoints/points/get-points.mdx new file mode 100644 index 0000000..a0bf039 --- /dev/null +++ b/api-reference/endpoints/points/get-points.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /points/{key} +--- diff --git a/api-reference/endpoints/users/get-a-users-points-summary.mdx b/api-reference/endpoints/users/get-a-users-points-summary.mdx index baaa426..cd6d192 100644 --- a/api-reference/endpoints/users/get-a-users-points-summary.mdx +++ b/api-reference/endpoints/users/get-a-users-points-summary.mdx @@ -1,3 +1,3 @@ --- -openapi: get /users/{id}/points/event-summary +openapi: get /users/{id}/points/{key}/event-summary --- diff --git a/api-reference/endpoints/users/get-a-users-points.mdx b/api-reference/endpoints/users/get-a-users-points.mdx index 578d3b9..c2ffb81 100644 --- a/api-reference/endpoints/users/get-a-users-points.mdx +++ b/api-reference/endpoints/users/get-a-users-points.mdx @@ -1,3 +1,3 @@ --- -openapi: get /users/{id}/points +openapi: get /users/{id}/points/{key} --- diff --git a/api-reference/openapi.yml b/api-reference/openapi.yml index de00a3d..1afaebe 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: @@ -20,14 +20,14 @@ paths: const response = await trophy.achievements.all(); 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: @@ -68,18 +68,18 @@ paths: userAttributes: - key: plan-type value: premium - '401': - description: 'Unauthorized' + "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: Get all achievements and their completion stats security: - ApiKeyAuth: [] @@ -112,12 +112,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: @@ -129,7 +129,7 @@ paths: description: Complete the onboarding process. badgeUrl: https://example.com/badge.png key: finish-onboarding - achievedAt: '2021-01-01T00:00:00Z' + achievedAt: "2021-01-01T00:00:00Z" points: points-system-key: id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 @@ -141,31 +141,31 @@ paths: awards: - id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 awarded: 10 - date: '2021-01-01T00:00:00Z' + date: "2021-01-01T00:00:00Z" total: 10 trigger: id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 type: achievement achievementName: Finish onboarding points: 10 - '401': - description: 'Unauthorized' + "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: [] @@ -177,7 +177,7 @@ paths: type: object properties: user: - $ref: '#/components/schemas/UpsertedUser' + $ref: "#/components/schemas/UpsertedUser" description: The user that completed the achievement. required: - user @@ -231,12 +231,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: @@ -251,14 +251,14 @@ 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' + started: "2025-04-02" + periodStart: "2025-03-31" + periodEnd: "2025-04-05" + expires: "2025-04-12" points: xp: id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 @@ -270,7 +270,7 @@ paths: awards: - id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 awarded: 10 - date: '2021-01-01T00:00:00Z' + date: "2021-01-01T00:00:00Z" total: 10 trigger: id: 0040fe51-6bce-4b44-b0ad-bddc4e123534 @@ -278,24 +278,24 @@ paths: metricName: words written metricThreshold: 100 points: 10 - '400': - description: 'Bad Request' + "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: [] @@ -307,7 +307,7 @@ paths: type: object properties: user: - $ref: '#/components/schemas/UpsertedUser' + $ref: "#/components/schemas/UpsertedUser" description: The user that triggered the event. value: type: number @@ -333,7 +333,7 @@ paths: user: email: user@example.com tz: Europe/London - id: '18' + id: "18" attributes: department: engineering role: developer @@ -375,15 +375,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: @@ -391,29 +391,29 @@ paths: email: user@example.com tz: Europe/London subscribedToEmails: true - created: '2021-01-01T00:00:00Z' - updated: '2021-01-01T00:00:00Z' + created: "2021-01-01T00:00:00Z" + updated: "2021-01-01T00:00:00Z" attributes: department: engineering role: developer - '400': - description: 'Bad Request' + "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. @@ -442,12 +442,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: @@ -455,29 +455,29 @@ paths: email: user@example.com tz: Europe/London subscribedToEmails: true - created: '2021-01-01T00:00:00Z' - updated: '2021-01-01T00:00:00Z' + created: "2021-01-01T00:00:00Z" + updated: "2021-01-01T00:00:00Z" attributes: department: engineering role: developer - '400': - description: 'Bad Request' + "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: Identify a user. operationId: users_identify @@ -516,7 +516,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UpdatedUser' + $ref: "#/components/schemas/UpdatedUser" description: The user object. example: email: user@example.com @@ -525,12 +525,12 @@ paths: department: engineering role: developer responses: - '200': + "200": description: Upserted user content: application/json: schema: - $ref: '#/components/schemas/User' + $ref: "#/components/schemas/User" examples: Successful operation: value: @@ -538,26 +538,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 @@ -596,7 +596,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UpdatedUser' + $ref: "#/components/schemas/UpdatedUser" description: The user object. example: id: user-id @@ -606,12 +606,12 @@ paths: department: engineering role: developer responses: - '200': + "200": description: Updated user content: application/json: schema: - $ref: '#/components/schemas/User' + $ref: "#/components/schemas/User" examples: Successful operation: value: @@ -619,32 +619,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. @@ -670,14 +670,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: @@ -692,14 +692,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 @@ -707,24 +707,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: [] @@ -760,12 +760,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: @@ -780,13 +780,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 @@ -794,24 +794,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: [] @@ -868,7 +868,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. @@ -876,9 +876,9 @@ paths: schema: type: string format: date - example: '2024-01-31' + example: "2024-01-31" responses: - '200': + "200": description: Successful operation content: application/json: @@ -891,7 +891,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 @@ -909,33 +909,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: [] @@ -982,17 +982,17 @@ paths: required: false schema: type: string - enum: ['true'] - example: 'true' + enum: ["true"] + example: "true" 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: @@ -1000,7 +1000,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 completions: 10 rarity: 90.13 @@ -1011,7 +1011,7 @@ 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 completions: 8 rarity: 22.98 @@ -1020,28 +1020,28 @@ paths: 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 completions: 12 rarity: 89.52 - '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 achievements security: - ApiKeyAuth: [] @@ -1080,62 +1080,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: [] @@ -1179,12 +1179,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: @@ -1196,7 +1196,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 @@ -1204,24 +1204,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: [] @@ -1278,7 +1278,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. @@ -1286,9 +1286,9 @@ paths: schema: type: string format: date - example: '2024-01-31' + example: "2024-01-31" responses: - '200': + "200": description: Successful operation content: application/json: @@ -1301,7 +1301,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 @@ -1319,33 +1319,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: [] @@ -1383,12 +1383,12 @@ paths: type: string example: plan-type:premium,region:us-east responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/PointsSummaryResponse' + $ref: "#/components/schemas/PointsSummaryResponse" examples: Successful operation: value: @@ -1425,24 +1425,24 @@ 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' - '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 breakdown of users by points security: - ApiKeyAuth: [] @@ -1471,12 +1471,12 @@ paths: type: string example: points-system-key responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/PointsSystemResponse' + $ref: "#/components/schemas/PointsSystemResponse" examples: Successful operation: value: @@ -1500,15 +1500,15 @@ paths: eventAttribute: key: source value: mobile-app - 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 @@ -1518,20 +1518,20 @@ paths: userAttributes: - key: plan-type value: premium - 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' - '404': - description: 'Points system not found' + $ref: "#/components/schemas/ErrorBody" + "404": + description: "Points system not found" content: application/json: schema: - $ref: '#/components/schemas/ErrorBody' + $ref: "#/components/schemas/ErrorBody" summary: Get a points system with its triggers security: - ApiKeyAuth: [] @@ -1560,7 +1560,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 @@ -1586,7 +1586,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: @@ -1597,7 +1597,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: @@ -1614,12 +1614,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. @@ -1638,7 +1638,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. @@ -1671,7 +1671,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 @@ -1695,7 +1695,7 @@ components: type: array description: Array of trigger awards that added points. items: - $ref: '#/components/schemas/PointsAward' + $ref: "#/components/schemas/PointsAward" required: - id - name @@ -1705,7 +1705,7 @@ components: title: MetricEventPointsResponse type: object allOf: - - $ref: '#/components/schemas/GetUserPointsResponse' + - $ref: "#/components/schemas/GetUserPointsResponse" - type: object properties: added: @@ -1724,7 +1724,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 @@ -1752,7 +1752,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. @@ -1764,7 +1764,7 @@ components: title: CompletedAchievementResponse type: object allOf: - - $ref: '#/components/schemas/AchievementResponse' + - $ref: "#/components/schemas/AchievementResponse" - type: object properties: achievedAt: @@ -1775,7 +1775,7 @@ components: title: AchievementWithStatsResponse type: object allOf: - - $ref: '#/components/schemas/AchievementResponse' + - $ref: "#/components/schemas/AchievementResponse" - type: object properties: completions: @@ -1834,7 +1834,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 @@ -1844,7 +1844,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. @@ -1878,7 +1878,7 @@ components: items: type: string description: The device token. - example: ['token1', 'token2'] + example: ["token1", "token2"] subscribeToEmails: type: boolean default: true @@ -1897,7 +1897,7 @@ components: type: object description: An object with editable user fields. allOf: - - $ref: '#/components/schemas/UpdatedUser' + - $ref: "#/components/schemas/UpdatedUser" - type: object properties: id: @@ -1911,7 +1911,7 @@ components: type: object description: A user of your application. allOf: - - $ref: '#/components/schemas/UpsertedUser' + - $ref: "#/components/schemas/UpsertedUser" - type: object properties: control: @@ -1922,12 +1922,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 @@ -1945,11 +1945,11 @@ components: description: The unique ID of the completion. example: 0040fe51-6bce-4b44-b0ad-bddc4e123534 achievement: - $ref: '#/components/schemas/CompletedAchievementResponse' + $ref: "#/components/schemas/CompletedAchievementResponse" points: type: object additionalProperties: - $ref: '#/components/schemas/MetricEventPointsResponse' + $ref: "#/components/schemas/MetricEventPointsResponse" description: >- A map of points systems by key that were affected by this achievement completion. required: @@ -1975,17 +1975,17 @@ 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: type: object additionalProperties: - $ref: '#/components/schemas/MetricEventPointsResponse' + $ref: "#/components/schemas/MetricEventPointsResponse" description: >- A map of points systems by key that were affected by this event. required: @@ -2014,7 +2014,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 @@ -2024,14 +2024,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 @@ -2111,7 +2111,7 @@ components: type: array description: Array of active triggers for this points system. items: - $ref: '#/components/schemas/PointsTriggerResponse' + $ref: "#/components/schemas/PointsTriggerResponse" required: - id - name diff --git a/assets/platform/achievements/check_user_completions.png b/assets/platform/achievements/check_user_completions.png new file mode 100644 index 0000000..b8fc7ef Binary files /dev/null and b/assets/platform/achievements/check_user_completions.png differ diff --git a/assets/platform/emails/advanced_usage_singular_plural.png b/assets/platform/emails/advanced_usage_singular_plural.png new file mode 100644 index 0000000..3eeddaf Binary files /dev/null and b/assets/platform/emails/advanced_usage_singular_plural.png differ diff --git a/assets/platform/emails/advanced_variables_prefix_suffix.png b/assets/platform/emails/advanced_variables_prefix_suffix.png new file mode 100644 index 0000000..67fd5b5 Binary files /dev/null and b/assets/platform/emails/advanced_variables_prefix_suffix.png differ diff --git a/assets/platform/emails/email_types.mp4 b/assets/platform/emails/email_types.mp4 new file mode 100644 index 0000000..d54a6c0 Binary files /dev/null and b/assets/platform/emails/email_types.mp4 differ diff --git a/assets/platform/emails/email_types.png b/assets/platform/emails/email_types.png deleted file mode 100644 index a9edfb7..0000000 Binary files a/assets/platform/emails/email_types.png and /dev/null differ diff --git a/assets/platform/emails/email_variables_demo.mp4 b/assets/platform/emails/email_variables_demo.mp4 new file mode 100644 index 0000000..2848d67 Binary files /dev/null and b/assets/platform/emails/email_variables_demo.mp4 differ diff --git a/assets/platform/emails/recap_trigger.png b/assets/platform/emails/recap_trigger.png new file mode 100644 index 0000000..1c1c4cc Binary files /dev/null and b/assets/platform/emails/recap_trigger.png differ diff --git a/assets/platform/emails/streak_emails.png b/assets/platform/emails/streak_emails.png new file mode 100644 index 0000000..31dddb0 Binary files /dev/null and b/assets/platform/emails/streak_emails.png differ diff --git a/assets/platform/emails/streak_trigger.png b/assets/platform/emails/streak_trigger.png new file mode 100644 index 0000000..8fda1c8 Binary files /dev/null and b/assets/platform/emails/streak_trigger.png differ diff --git a/assets/platform/emails/using_variables.mp4 b/assets/platform/emails/using_variables.mp4 deleted file mode 100644 index 4a01c21..0000000 Binary files a/assets/platform/emails/using_variables.mp4 and /dev/null differ diff --git a/assets/platform/events/create_custom_event_attribute.mp4 b/assets/platform/events/create_custom_event_attribute.mp4 new file mode 100644 index 0000000..11b115e Binary files /dev/null and b/assets/platform/events/create_custom_event_attribute.mp4 differ diff --git a/assets/platform/events/using_attributes_in_email_charts.mp4 b/assets/platform/events/using_attributes_in_email_charts.mp4 new file mode 100644 index 0000000..318c9d4 Binary files /dev/null and b/assets/platform/events/using_attributes_in_email_charts.mp4 differ diff --git a/assets/platform/events/using_attributes_in_emails.mp4 b/assets/platform/events/using_attributes_in_emails.mp4 new file mode 100644 index 0000000..fe867af Binary files /dev/null and b/assets/platform/events/using_attributes_in_emails.mp4 differ diff --git a/assets/platform/points/create_system.mp4 b/assets/platform/points/create_system.mp4 new file mode 100644 index 0000000..f517fb5 Binary files /dev/null and b/assets/platform/points/create_system.mp4 differ diff --git a/assets/platform/points/create_trigger.mp4 b/assets/platform/points/create_trigger.mp4 index 9385ff9..503f577 100644 Binary files a/assets/platform/points/create_trigger.mp4 and b/assets/platform/points/create_trigger.mp4 differ diff --git a/assets/platform/points/points_analytics.png b/assets/platform/points/points_analytics.png index c53d021..4793124 100644 Binary files a/assets/platform/points/points_analytics.png and b/assets/platform/points/points_analytics.png differ diff --git a/assets/platform/users/create_custom_user_attribute.mp4 b/assets/platform/users/create_custom_user_attribute.mp4 new file mode 100644 index 0000000..b5f5479 Binary files /dev/null and b/assets/platform/users/create_custom_user_attribute.mp4 differ diff --git a/assets/platform/users/segmenting_analytics.mp4 b/assets/platform/users/segmenting_analytics.mp4 new file mode 100644 index 0000000..5812de1 Binary files /dev/null and b/assets/platform/users/segmenting_analytics.mp4 differ diff --git a/docs.json b/docs.json index ff95606..03d549c 100644 --- a/docs.json +++ b/docs.json @@ -132,8 +132,8 @@ { "group": "Points", "pages": [ - "api-reference/endpoints/points/get-points-summary", - "api-reference/endpoints/points/get-all-points-triggers" + "api-reference/endpoints/points/get-points", + "api-reference/endpoints/points/get-points-summary" ] }, { diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6ab6825 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "docs", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/platform/achievements.mdx b/platform/achievements.mdx index 503ea97..9830daa 100644 --- a/platform/achievements.mdx +++ b/platform/achievements.mdx @@ -1,7 +1,7 @@ --- title: Achievements description: Learn how to use Achievements in a gamified product experience with Trophy. -"og:description": Use metric, standalone and streak achievements to rewards users for continued progress and to encourage them to discover new parts of your app. +"og:description": Use metric, API and streak achievements to rewards users for continued progress and to encourage them to discover new parts of your app. icon: trophy --- @@ -39,7 +39,7 @@ Watch Charlie run walk through using achievements in a NextJS application: ## Achievement Types -Trophy offers three types of achievements, [Metric](#metric-achievements), [Standalone](#standalone-achievements) and [Streak achievements](#streak-achievements), detailed below. +Trophy offers three types of achievements, [Metric](#metric-achievements), [API](#api-achievements) and [Streak achievements](#streak-achievements), detailed below. ### Metric Achievements @@ -62,9 +62,9 @@ When achievements are unlocked, Trophy includes information about the unlocked a -### Standalone Achievements +### API Achievements -Standalone achievements can only be completed once and are useful for rewarding users for taking specific actions. +API achievements can only be completed once and are useful for rewarding users for taking specific actions. Common examples include: @@ -72,9 +72,9 @@ Common examples include: - A user linking their social account to a platform - A user sharing their product experience on social media -Standalone achievements serve as an easy way to reward users for completing any action that you think is important for retention. +API achievements serve as an easy way to reward users for completing any action that you think is important for retention. -Just like metric achievements, standalone achievements can also trigger automated [Achievement Emails](/platform/emails#achievement-emails) if configured. +Just like metric achievements, API achievements can also trigger automated [Achievement Emails](/platform/emails#achievement-emails) if configured. ### Streak Achievements @@ -82,7 +82,7 @@ Streak achievements are directly tied to a user's [Streak](/platform/streaks) an You can create as many streak achievements as you like for increasing lengths of streak, for example 7 days, 30 days and 365 days to motivate users to use your app more and more. -Just like metric and standalone achievements, you can add a custom name and assign a badge to streak achievements. +Just like metric and API achievements, you can add a custom name and assign a badge to streak achievements. ## Creating Achievements @@ -104,14 +104,26 @@ To create new achievements, head to the [achievements page](https://app.trophy.s Enter a name for the achievement. This will be returned from APIs and made available for use in emails and other areas of Trophy where appropriate. + + Enter a short description of the achievement. This will be returned from APIs + and made available for use in emails and other areas of Trophy where + appropriate. + + + + You can upload and assign a badge to the achievement that will be returned in + API responses and made available in emails and other areas of Trophy where + appropriate. + + Choose how you want this achievement to be unlocked. -- Choosing **Metric** will mean the achievement will be automatically unlocked when the user's total reaches the achievement trigger value. +- Choosing **Metric** will mean the achievement will be automatically unlocked when the user's metric total reaches the achievement trigger value. - Choosing **Streak** will mean the achievement will be automatically unlocked when the user's streak length reaches the achievement trigger value. -- Choosing **API Call** will mean the achievement will only be unlocked when explicitly marked as completed by your code through an API call. +- Choosing **API Call** will mean the achievement will only be unlocked when explicitly marked as completed by your code through a request to the [complete achievement API](/api-reference/endpoints/achievements/mark-an-achievement-as-completed). @@ -126,10 +138,13 @@ To create new achievements, head to the [achievements page](https://app.trophy.s - - You can upload and assign a badge to the achievement that will be returned in - API responses and made available in emails and other areas of Trophy where - appropriate. + + You can assign _attribute filters_ to an achievement to further restrict who can unlock them and when. + +- To limit a **Metric** achievement to only apply to events with specific [custom event attributes](/platform/events#custom-event-attributes), select an attribute and enter a value in the **Event Attribute** section. + +- To limit any type of achievement to only apply to a user with one or more specific [custom user attributes](/platform/users#custom-user-attributes), add attributes and the desired values in the **User Attributes** section. + @@ -137,13 +152,77 @@ To create new achievements, head to the [achievements page](https://app.trophy.s +## Managing Achievements + +Trophy has built in tools to help you test and control which achievements can be unlocked, by who and when, without affecting production. + +### Achievement Statuses + +Here's an overview of the different achievement statuses and what they mean. + +**Inactive** + +All achievements are created as inactive. Inactive achievements can't be completed and aren't returned in any achievement APIs. Users won't see them until you make them active. + +**Active** + +When you make an achievement active, it makes it 'live'. Users can complete it and it will be returned from all achievement APIs. + +**Locked** + +When you lock an achievement, users who haven't unlocked it yet won't be able to unlock it anymore, but users who have already unlocked it won't be affected. + +Locked acheivements are only returned in APIs for users who have already achieved them. + +**Archived** + +Archvied achievements can't be completed and aren't returned in any achievement APIs. + + + Once you archive an achievement it disapears from Trophy so be sure to only + archive achievements that you no longer need. + + +Archived achievements can be restored by [contacting support](#get-support). + +### Acheivement Workflow + +Achievements can be moved through different statuses according to the following workfow: + +```mermaid +flowchart LR + A@{ shape: rounded, label: "Inactive" } + B@{ shape: rounded, label: "Active" } + C@{ shape: rounded, label: "Active" } + D@{ shape: rounded, label: "Locked" } + E@{ shape: rounded, label: "Archived" } + F@{ shape: rounded, label: "Locked" } + G@{ shape: rounded, label: "Active" } + H@{ shape: rounded, label: "Archived" } + A-->B + C-->D + D-->E + C-->E + F-->G + F-->H + style A fill:#FDFDEA,stroke:#F7F0D5 + style B fill:#F2FAF7,stroke:#E2F6E6 + style C fill:#F2FAF7,stroke:#E2F6E6 + style D fill:#eee,stroke:#ddd + style E fill:#ddd,stroke:#ccc + style F fill:#eee,stroke:#ddd + style G fill:#F2FAF7,stroke:#E2F6E6 + style H fill:#ddd,stroke:#ccc + +``` + ## Completing Achievements If you're using metric achievements, there's no need to explicitly _complete_ achievements. Once you've set up [metric tracking](/platform/events#tracking-metric-events) in your code, all achievements linked to the metric will be automatically tracked. Similarly, if you're using streak achievements, all achievements related to the user's streak will automatically be unlocked when a user reaches the respective streak length. -However if you're using any standalone achievements, you will have to mark them as completed for each user as appropriate. To do this, you can use the [Complete Achievement API](/api-reference/endpoints/achievements/mark-an-achievement-as-completed) using the `key` of the achievement you want to complete. +However if you're using any API achievements, you will have to mark them as completed for each user as appropriate. To do this, you can use the [Complete Achievement API](/api-reference/endpoints/achievements/mark-an-achievement-as-completed) using the `key` of the achievement you want to complete. This will return back a response that contains details of the achievement that was completed that can be used in any post-completion workflows, like showing an in-app notification. @@ -162,6 +241,28 @@ This will return back a response that contains details of the achievement that w } ``` +## Backdating Achievements + +By default, whenever you move an achievement to 'Active' [status](#managing-achievements), Trophy will check if any existing users meet the requirements of the achievment and complete it for them behind the scenes. + +This means when you release new achievments into production, or edit an existing live achievement, backdating will happen automatically. + + + When achievements are completed in this way, users don't receive any + notifications this has happened. This is to prevent changes to your + achievements in Trophy resulting in users getting lots of notifications. + + +You can check how many users have completed achievements at any time on the [acheivements page](https://app.trophy.so/achievements) in the Trophy dashboard. The _Users_ column in the acheivements can update during backdating. + + + + + ## Using Badges @@ -216,15 +317,18 @@ To display a high-level overview of all achievements users can complete, use the > -The all achievements endpoint returns a list of all achievements within your Trophy account along with details of 'rarity' (the percentage of users who have completed each achievement) as follows: +The all achievements endpoint returns a list of all achievements within your Trophy account. Each achievement returned also includes `completions` (the number of users who have compelted the acheivement) and `rarity` (the percentage of users who have completed the achievement) as follows: ### User Achievements -If instead you're building user-specific UI elements, then use the [user achievements endpoint](/api-reference/endpoints/users/get-a-users-completed-achievements) to get only the achievements a specific user has completed. +If instead you're building user-specific UI elements, then use the [user achievements endpoint](/api-reference/endpoints/users/get-a-users-completed-achievements) to return achievements a specific user has completed. -Use this data to display achievements against a user's profile for example. + + You can also include achievements that a user has yet to complete by including + the query parameter `includeIncomplete=true`. + diff --git a/platform/emails.mdx b/platform/emails.mdx index 3084fc8..1e2f442 100644 --- a/platform/emails.mdx +++ b/platform/emails.mdx @@ -14,22 +14,216 @@ Trophy supports 4 types of emails, each of which is designed to suit a common sc All emails are optional, but all four can be used simultaneously and can be controlled from the [Emails](https://app.trophy.so/emails/configure) page in the Trophy dashboard. - + -### Achievement Emails +- **Achievement emails** are sent to users each time they unlock an [Achievement](/platform/achievements). +- **Recap emails** are sent to users on a pre-defined frequency to summarize progress. Recap Emails can be configured to be sent daily, weekly, monthly or yearly depending on your use case. +- **Reactivation emails** are sent to users after they become inactive with the goal of bringing them back to your app. +- **Streak emails** are automatically sent to users reminding them to extend their [Streak](/platform/streaks). + +## Sending Emails + +To start sending emails with Trophy, you'll need to verify your domain and enable email triggers. + +### Domain Verification + +Trophy supports sending emails from your own domain out-of-the-box. There are two ways to set this up, Single Sender Verification and DNS Verification. + +All domain settings can be found in the [Domains](https://app.trophy.so/emails/domains) page in the Trophy dashboard. + + + If you're looking to get set up quickly we recommend starting with Single + Sender Verification then setting up DNS Verification when you're ready to move + to production. + + + + + Quickly verify a single email address + + + Recommended for production use + + + +#### Sender Verification (Basic) + +During onboarding you'll be prompted to set up Sender Verification. This is a super simple way to quickly verify a single email address that you want to use with Trophy without needing to change any code or DNS settings. + +You'll be prompted to enter the email address, from name and reply-to email that you'd like Trophy to use when sending emails: + + + + + +Trophy will send a verification email to that address. Simply click the link in the email to let Trophy know what you own the address and you'll be good to go. + + + The email you receive will come from our email provider, Postmark. So keep an + eye out for 'Postmark Support' in your inbox! + + +Sender Verification is great for getting started but is limited in that you won't benefit from your existing email reputation and can only send emails from one address. + +Also, if you want to change the address in the future, you'll have to go through Sender Verification again which you can do in the [settings screen](https://app.trophy.so/integration?tab=domains). + +#### DNS Verification (Advanced) + +Recommended for production use + +For production use we recommend DNS Verification. Once set up, this allows you to configure Trophy to send emails from any address on your domain. So if you want to change the address in future, you won't need to verify again. + +Completing DNS verification also gives you the full benefits of any existing domain reputation and is the best way to make sure your emails avoid the spam folder. + +This does however require adding a couple of new entries into your DNS to allow Trophy to verify you own the domain. + +Follow the steps below to set up DNS verification: + + + + Within the Emails page, you'll find the [Domains](https://app.trophy.so/emails/domains) tab which is where you'll configure everything related to the email domain Trophy will use to send emails on your behalf. + + + + Head down to the DNS Verification section and enter the domain you want to set up with Trophy. + + You can also also configure a custom Return Path. This is where Trophy will forward notifications of bounced emails to help you investigate deliverability issues: + + + + + + + + + + Once you've entered your email domain, Trophy will provide you with details for two new DNS records that you'll need to add to your DNS provider. + + + + + + - First is the **DKIM** record which is used by inbox providers like Google to verify the authenticity of emails. Enter the name and value provided as a new **TXT** record in your DNS provider. + - Second is the **Return Path** record. This is used to forward notifications of email bounces to your domain. Enter the name and value provided as a new **CNAME** record in your DNS provider. + + Here are the pages for the most common DNS providers on how to set up new records: + + + + [Add a TXT record](https://www.godaddy.com/en-uk/help/add-a-txt-record-19232) + [Add a CNAME record](https://www.godaddy.com/en-uk/help/add-a-cname-record-19236) + + + [Add DNS records](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/#create-dns-records) + + + [Add a CNAME record](https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain/) + [Add a TXT record](https://www.namecheap.com/support/knowledgebase/article.aspx/317/2237how-do-i-add-txtspfdkimdmarc-records-for-my-domain/#:~:text=this%20guide%20.-,DKIM%20records,-DKIM%20(DomainKeys%20Identified)) + + + + Note: If you're using a proxy like Cloudflare, make sure to turn it off for these records or Trophy won't be able to properly verify them. + + + + + + Once you've added the two records into your DNS settings, hit the refresh icon and Trophy will attempt to verify the records for you. + + Usually Trophy can verify records within a few minutes but bear in mind that DNS changes can take up to a few hours to fully propogate. + + If you see the following alert, the records may not have propogated yet, or there may be an issue with your setup. + + + + + + Once you're sure everything's set up correctly in your DNS provider, hit refresh and Trophy will attempt to verify your DNS records once again. -Achievement emails are sent to users each time they unlock an [Achievement](/platform/achievements). + As soon as you see the following message, you know everything's verified: -### Recap Emails + + + -Recap emails are sent to users on a pre-defined frequency to summarize progress. Recap Emails can be configured to be sent daily, weekly, monthly or yearly depending on your use case. + -### Reactivation Emails + -As Trophy monitors usage across your entire userbase, it can detect when users become inactive and send automated win-back emails to encourage them to return. + Once your DNS records are verified, it's time to choose the email address you want to send emails from. Note that now you've fully verified your domain, you can change this address whenever you like without impacting deliverability. -Emails are sent as follows: + Simply enter the email address you want Trophy to send from, the name to show to users in the inbox when they receive emails and a support email address they can use to contact you if needed: + + + + + + + + + +### Email Triggers + +You can manage email triggers on the [Email Configuration](https://app.trophy.so/emails/configure) page of the Trophy dashboard. There, you'll see a list of triggers that can be turned on or off: + +#### Recap Emails + +The **Recap** trigger sends daily, weekly, or monthly progress reports to users. You can change the frequency of these emails on the [Integration](https://app.trophy.so/integration) page using the **Aggregation Period** setting. + + + + + +#### Reactivation Emails + +The **Reactivation** trigger sends win-back emails to users after they become inactive. These emails are sent according to the following timeline: - After 3 days of inactivity - After 5 days of inactivity @@ -37,9 +231,80 @@ Emails are sent as follows: - After 14 days of inactivity - After 30 days of inactivity -### Streak Reminder Emails + + + + +#### Streak Emails + +The **Streak** trigger sends an email to each user before their streak expires. These emails are sent according to the streak frequency you configured on the [Streaks page](https://app.trophy.so/streaks): + +- If your app uses a **daily streak**, this email will send four hours before the end of the day (in each user's timezone). +- For **weekly streaks**, it will send on Friday morning. +- For **monthly streaks**, it will send on the 25th of the month. + + + + + +#### Achievement Emails + +The **Achievement** trigger sends an email congratulating users when they complete an [achievements](/platform/achievements) you've configured in Trophy. These emails send between 5-9PM on the day the achievement is completed, or the next day at 5PM if it is past 9PM when the user completes the achievement. + + + + + +#### Email Templates -Streak reminder emails are automatically sent to users up to 4 hours before they are about to lose their [Streak](/platform/streaks). +For each trigger, you can assign an **Email Template** that the trigger uses. You can leave this set to _Trophy Default_ or [design your own email templates](#designing-emails) right in the Trophy dashboard. + + + + + + + For **Achievement Emails**, you can configure a different template for each + type of achievement. For example, you could have a different template for API + achievements, streak achievements, and each metric with metric achievements. + + +#### Limiting Emails to Specific Types of Users + +Each email trigger can be limited to users with specific [custom user attribute](/platform/users#custom-user-attributes) values. For each attribute you'd like to restrict the email to, click the Plus icon next to the **User Filters** header for the email trigger, then select the attribute and enter the desired value. Only users that have **all** specified attribute values will receive emails from this trigger. + + + + + +#### Time Zones + +If you specify a timezone for each user through [User Identification](/platform/users#param-tz), Trophy will use that local time zone to schedule emails according to the logic specified above. If you do not provide time zones for the users you identify, Trophy will default to Eastern Time. ## Designing Emails @@ -273,21 +538,13 @@ Where achievements have badges, these will be automatically shown, as well as th ### Email Variables -Trophy provides an expansive set of dynamic variables that are useful for designing highly relevant and personalized emails. Variables bring context from your Trophy account, the recipient's progress data, and email specific settings to your email templates. +Trophy provides an expansive set of email variables that can be used to insert highly relevant and personalized copy into the body of emails and subject lines. - - - +Variables bring context from your Trophy account, the recipient's progress data, and email specific settings to your email templates. + +Email variables can be inserted by typing `@` in any block that supports rich text, like headers, paragraphs, and buttons, and searching for your chosen variable. -Email variables can be inserted by typing `{{` in any block that supports rich text, like headers, paragraphs, and buttons, and searching for your chosen variable. The editor will insert the variable code for you. +This will open up the variable editor window where you can configure variables as in the demo below. You can also use variables in email subject lines. @@ -298,108 +555,132 @@ Email variables can be inserted by typing `{{` in any block that supports rich t loop playsInline className="w-full aspect-video" - src="../assets/platform/emails/using_variables.mp4" + src="../assets/platform/emails/email_variables_demo.mp4" > -See below for a full list of all email variables supported by the email builder: - - - Variables related to the recipient of the email. - - - - The full name of the user, if set. - - - - - - Variables referencing data from metrics within your Trophy account. - - In all metric variables, `key` relates to the unique reference you set for the metric when created. You can find this in the details page for each metric. - - - Variables for a metric called 'Words written' with a `key` of `words` would be accessed with a `metrics.words` prefix. For example `metrics.words.percentile`. - - - - - Indicates where the recipient's all time metric total ranks compared to all other tracked users. For example, if a user is in the 90th percentile, their all time metric total is higher than 90% of users that have at least one event recorded against the metric. - - - The recipent's percentile within the most recent [Aggregation Period](#aggregation-period). - - - The recipient's current total value of all events recorded against the metric. - - - The percentage increase (or decrease) in the recipient's metric total as compared to the last [Aggregation Period](#aggregation-period). For example if the recipent has doubled their metric total within the aggregation period, `percentChange` would show +100. We leave it up to you to display a '%' sign if required. - - - The absolute increase (or decrease) in the recipient's metric total as compared to the last [Aggregation Period](#aggregation-period). For example if the recipents metric total has increased from 500 to 750, `changeThisPeriod` would show 250. - - - - - - Variables related to the recipient's streak. +See below for a full list of all email variables supported by the email builder, broken down by category. + + + +Variables related to the recipient of the email. + +- **Name**: The recipient's name, if set + +Additionally all [custom user attributes](/platform/users#custom-user-attributes) are available as email variables. - - - `true` if the recipient has an active streak, `false` otherwise. - - - `true` if the recipient has extended their streak within the current streak period, `false` otherwise. - - - The number of consequtive periods that the user has kept their streak. 0 if the user does not have an active streak. - - - The number of days since the user last extended their streak. 0 if the user has an active streak. - - - - - - Variables related to the current setting of the data [Aggregation Period](#aggregation-period). - - - - The string representation of the current aggregation period. For example 'June 1 - June 7'. - - - - - + + + Variables related to the recipients tracked event data againt metrics. + +Each Trophy metric supports the following email variables: + +- **Metric Name**: The name of the metric +- **Metric Units**: The metric's units +- **Current Total**: The sum of all the recipients event values to date +- **Change This Period**: Absolute change in the recipients current total in the current aggregation period +- **Change This Period (%)**: Percent change in the recipients current total in the current aggregation period +- **Percentile (All Time)**: The recipients current total compared to all other users for all time +- **Percentile (This Period)**: The recipients current total compared to all other users in the current aggregion period + +Additionally, the **Highest** and **Lowest** dynamic aliases support the same set of variables. When using these aliases, Trophy will pick the metric where the recipient has either the highest or lowest current total at send time. + +When using metric variables, you also have the option of filtering the data that any of the above variables reference through a [custom event attribute](/platform/events#custom-event-attributes). + + + + + +Similarly to metrics, each points system has the following variables that can be used to add dynamic data to email copy: + +- **Current Total**: The recipients total points +- **Change This Period**: Absolute change in the recipients total points in the current aggregation period +- **Change This Period (%)**: Percent change in the recipients total points in the current aggregation period +- **Percentile (All Time)**: The recipients total points compared to all other users for all time +- **Percentile (This Period)**: The recipients total points compared to all other users in the current aggregion period + +. + + + - Only relevant in the context of [Achievement Emails](#achievement-emails). + These variables are only relevant for [achievement emails](#achievement-emails). - - - The `name` of the unlocked achievement that triggered the email. - - - `true` if the achievement the recipent unlocked is the last achievement for it's metric, `false` otherwise. - - - The percentage progress that the recipent has made to the next achievement against the same metric. 100 if `isLastAchievement` is true. - - - - - +When configuring a template for use with achievement emails, the following variables are available: + +- **Is Final Achievement**: If the achievement triggering the email is part of a series of metric achievements, this is true when the achievment is the final achievement in the series +- **Percent To Next Achievement**: If the achievement triggering the email is part of a series of metric achievements, this is the percentage until the user unlocks the next achievment in the series +- **Achievement Name**: The name of the achievement that triggered the email +- **Achievement Description**: The description of the achievement that triggered the email + +. + + + + Variables related to the recipient's streak. + +- **Has Active Streak**: True if the recipient has an active streak at the time the email is sent, false otherwise +- **Streak Length**: The length of the recipient's current streak +- **Streak Extended**: True if the recipient's streak was extended, false otherwise +- **Days Since Last Extended**: The number of days since the user last extended their streak + +. + + + - Only relevant in the context of [Reactivation Emails](#reactivation-emails). + These variables are only relevant for [reactivation emails](#reactivation-emails). + + +- **Message Number**: The number of the message in the reactivation sequence (1-5) + +. + + + + + These variables are only relevant for [recap emails](#recap-emails). - - - Trophy sends 5 reactivation emails over 30 days. This is the number of the current email in the sequence. Useful for displaying different email content throughout the sequence. - - - +- **Current Period Date Range**: The start and end dates of the current aggregation period + +. + + + + +#### Advanced Usage + +There are a couple of additional options to consider when using emails variables. + +**Prefix & Suffix** + +You can provide a prefix and suffix for text variables like the recipients name, or the name of a particular metric. + + + + + +If the value of the variable fails to render when the email is sent, then Trophy won't display the variable or the prefix or suffix to keep emails clean. + +**Singular & Plural** + +When using numeric variables like the recipients current points total or metric total, you can also provide a singular and plural suffix to accompany it. + + + + ### Text Variations @@ -501,54 +782,6 @@ The email editor offers rich text formatting including bold, italics, [hyperlink > -It also supports more complex text formatting use cases based on the [Mustache](https://mustache.github.io/mustache.5.html) specification with the most common use case being to conditionally show text based on the value of [Email Variables](#email-variables). - - - If you need more complex conditional formatting, or aren't familiar with - Mustache, consider using [Conditional Blocks](#conditional-blocks) instead. - - -Here's an example where we show text if the email recipient has an active streak or not: - -``` -{{#streak.active}} - You're on a streak! -{{/streak.active}} -``` - -Additionally, the editor support pluralization. In the below example we show different text based on if the value of the `metrics.words.currentTotal` is `1` (singular) or greater than `1` (plural). - -``` -{{#plural}} - {{metrics.words.currentTotal}} words written -{{/plural}} -{{#singular}} - {{metrics.words.currentTotal}} word written -{{/singular}} -``` - - - For `#plural` and `#singular` to work, the first entry must be a number - variable. - - -## Email Customization - -### Aggregation Period - - - - - -The aggregation period controls the timeframe over which blocks like the [Progress Chart](#progress-chart) display usage. It also controls the frequency at which [Recap Emails](#recap-emails) are sent. Possible values are daily, weekly, monthly or yearly. - -Head into the [Integration](https://app.trophy.so/integration) page to manage this setting. - ### Font Style On the [email configure page](https://app.trophy.so/emails/configure), you'll find a setting to change the font style used in all emails. @@ -564,183 +797,6 @@ On the [email configure page](https://app.trophy.so/emails/configure), you'll fi Other email styles are pulled from your Trophy account's [Branding](https://app.trophy.so/branding) settings. -## Send-time Optimization - -In most cases, emails sent by Trophy are sent at **17:00PM ET**, however sending emails to users based on their local timezone usually results in better engagement rates. - -That's why if through [User Identification](/platform/users#param-tz) you specify a timezone for each user, Trophy will optimize the send-time for you by sending emails to users at 17:00PM in their local timezone. - -## Setting up Emails - -Trophy supports sending emails from your own domain out-of-the-box. There are two ways to set this up, Single Sender Verification and DNS Verification. - -All domain settings can be found in the [Domains](https://app.trophy.so/emails/domains) page in the Trophy dashboard. - - - If you're looking to get set up quickly we recommend starting with Single - Sender Verification then setting up DNS Verification when you're ready to move - to production. - - - - - Quickly verify a single email address - - - Recommended for production use - - - -### Sender Verification (Basic) - -During onboarding you'll be prompted to set up Sender Verification. This is a super simple way to quickly verify a single email address that you want to use with Trophy without needing to change any code or DNS settings. - -You'll be prompted to enter the email address, from name and reply-to email that you'd like Trophy to use when sending emails: - - - - - -Trophy will send a verification email to that address. Simply click the link in the email to let Trophy know what you own the address and you'll be good to go. - - - The email you receive will come from our email provider, Postmark. So keep an - eye out for 'Postmark Support' in your inbox! - - -Sender Verification is great for getting started but is limited in that you won't benefit from your existing email reputation and can only send emails from one address. - -Also, if you want to change the address in the future, you'll have to go through Sender Verification again which you can do in the [settings screen](https://app.trophy.so/integration?tab=domains). - -### DNS Verification (Advanced) - -Recommended for production use - -For production use we recommend DNS Verification. Once set up, this allows you to configure Trophy to send emails from any address on your domain. So if you want to change the address in future, you won't need to verify again. - -Completing DNS verification also gives you the full benefits of any existing domain reputation and is the best way to make sure your emails avoid the spam folder. - -This does however require adding a couple of new entries into your DNS to allow Trophy to verify you own the domain. - -Follow the steps below to set up DNS verification: - - - - Within the Emails page, you'll find the [Domains](https://app.trophy.so/emails/domains) tab which is where you'll configure everything related to the email domain Trophy will use to send emails on your behalf. - - - - Head down to the DNS Verification section and enter the domain you want to set up with Trophy. - - You can also also configure a custom Return Path. This is where Trophy will forward notifications of bounced emails to help you investigate deliverability issues: - - - - - - - - - - Once you've entered your email domain, Trophy will provide you with details for two new DNS records that you'll need to add to your DNS provider. - - - - - - - First is the **DKIM** record which is used by inbox providers like Google to verify the authenticity of emails. Enter the name and value provided as a new **TXT** record in your DNS provider. - - Second is the **Return Path** record. This is used to forward notifications of email bounces to your domain. Enter the name and value provided as a new **CNAME** record in your DNS provider. - - Here are the pages for the most common DNS providers on how to set up new records: - - - - [Add a TXT record](https://www.godaddy.com/en-uk/help/add-a-txt-record-19232) - [Add a CNAME record](https://www.godaddy.com/en-uk/help/add-a-cname-record-19236) - - - [Add DNS records](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/#create-dns-records) - - - [Add a CNAME record](https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain/) - [Add a TXT record](https://www.namecheap.com/support/knowledgebase/article.aspx/317/2237how-do-i-add-txtspfdkimdmarc-records-for-my-domain/#:~:text=this%20guide%20.-,DKIM%20records,-DKIM%20(DomainKeys%20Identified)) - - - - Note: If you're using a proxy like Cloudflare, make sure to turn it off for these records or Trophy won't be able to properly verify them. - - - - - - Once you've added the two records into your DNS settings, hit the refresh icon and Trophy will attempt to verify the records for you. - - Usually Trophy can verify records within a few minutes but bear in mind that DNS changes can take up to a few hours to fully propogate. - - If you see the following alert, the records may not have propogated yet, or there may be an issue with your setup. - - - - - - Once you're sure everything's set up correctly in your DNS provider, hit refresh and Trophy will attempt to verify your DNS records once again. - - As soon as you see the following message, you know everything's verified: - - - - - - - - - - Once your DNS records are verified, it's time to choose the email address you want to send emails from. Note that now you've fully verified your domain, you can change this address whenever you like without impacting deliverability. - - Simply enter the email address you want Trophy to send from, the name to show to users in the inbox when they receive emails and a support email address they can use to contact you if needed: - - - - - - - - - ## Handling Unsubscribes All emails that Trophy sends include an unsubscribe link and message. This is important for maintaining compliance with regulations and it's not possible to hide it. @@ -777,7 +833,7 @@ Trophy has built-in analytics for all Emails that it sends. This includes: - Yes! Sending emails from your own domain is supported out-of-the-box. Follow the steps in the section on [Settings up Emails](#setting-up-emails) to get started. + Yes! Sending emails from your own domain is supported out-of-the-box. Follow the steps in the section on [sending emails](#sending-emails) to get started. {" "} diff --git a/platform/events.mdx b/platform/events.mdx index cb3cf0d..27be52a 100644 --- a/platform/events.mdx +++ b/platform/events.mdx @@ -14,15 +14,134 @@ Events represent individual user interactions against [Metrics](/platform/metric When you [integrate metrics](#tracking-metric-events) into your platform, you're setting up your platform to continuously stream events to your Trophy metrics for each user interaction. These interactions then drive all the gamification features you set up around these metrics. -## Key attributes +## Key Attributes -### Metric-backed +Events only have one required attribute, `value`. The value of an event is the numerical amount that will be added to the user's total metric count as a result of the user interaction it relates to. -Each event increases or decreases the total value of a specific metric that you've configured in Trophy for a specific user. +The value can be positive or negative, and can be a whole number or a decimal. -### Value +## Custom Event Attributes -The value of an event is the numerical amount that will be added to the user's total metric count as a result of the user interaction it relates to. The value can be positive or negative, and can be a whole number or a decimal. +You can specify a number of custom event attributes to help you track additional information relevant to your use case against events you send to Trophy. + +For example, a language learning app might have a 'Questions Completed' metric and use a custom event attribute to store wether the answer to each question was correct. + +Similarly a fitness app might use an 'Excercises Completed' metric and use a custom event attribute to store the weight that was used in each excercise and another custom event attribute to store how long the excercise lasted. + +Using custom event attributes in this way allows you to enrich events in Trophy with additional context relevant to your use case and use it to power even more engaging gamification features. + +### Creating Attibutes + +To create a new custom event attribute, head to the metrics page in the Trophy dashboard and hit the _Add Event Attribute_ button. + +Give the attribute a name and a unique key, you'll use the key when referencing the attribute in API calls. + + + + + +### Setting Attributes + +To set the value of a custom attribute on an event, pass its value in the `attributes` object in your metric tracking code. + + + Trophy will only set values of attributes that have first been created + in the dashboard. We do this to help you keep a clean set of attributes and + prevent accidental overwrites. + +If you receive an error similar to the following then you might have miss-spelled the attribute key in the request, or you need to create the attribute first in the Trophy dashboard: + +```json +{ + "error": "Invalid attribute keys: devce. Please ensure all attribute keys match those set up at https://app.trophy.so/metrics." +} +``` + + + +Here's an example of an event payload where the values of two attributes, `device` and `duration`, are set: + +```json {7-10} +{ + "user": { + "id": "18", + "tz": "Europe/London" + }, + "value": 25, + "attributes": { + "device": "ios", + "duration": "120" + } +} +``` + +### Using Attributes + +Custom event attributes can be used to power more advanced triggers for achievements and points and can be used in email templates to customize copy and to control the data shown in charts. + +#### Advanced Feature Triggers + +Custom event attributes can be used to set up achievements or points triggers that only track events with specific attribute values. Follow the links to the relevant pages below to learn more. + + + + Configure achievements that can only be unlocked by events with certain + attribute values. + + + Set up points triggers to only award points from events with specific + attribute values. + + + +#### Email Customization + +If you use any Trophy [Emails](/platform/emails), event attributes can be used to customize the data shown in certain email blocks. + +Firstly, when using metric-based variables in email copy you can use event attributes to further control what data the variable refrences. + +For example here's a case where we use an email variable to tell users what their total number of workouts they've done on different gym equipment is using a metric 'Workouts' and an attribute 'Equipment': + + + + + +Secondly, here's an example where we add a chart to an email that shows users how many workouts they've done on a bike over time: + + + + + +There's a huge number of possibilities here, so get creative! ## Tracking Metric Events diff --git a/platform/points.mdx b/platform/points.mdx index 249a346..69e70e4 100644 --- a/platform/points.mdx +++ b/platform/points.mdx @@ -19,9 +19,45 @@ Points systems are used to reward users for taking actions in your product. When Use Trophy to create sophisticated points systems driven by real user interactions with no custom code. +## Creating Points Systems + +Trophy let's you set up multiple points systems for different use cases within your application. + + + + + +To create a points system, head to the [points page](https://app.trophy.so/points) and follow the steps below. + + + + Give the new points system a name, and a unique key. The key is what you'll + use to reference the points system in APIs and in email templates if + relevant. + + + You can also give the points system a description which is returned from + APIs to be displayed in your application. + + + You can also optionally upload a badge or logo to represent the points + system. A `src` freindly URL to the image is returned from APIs for display + in your application. + + + ## Creating Triggers -Points can be awarded as a result of user interactions tracked by Trophy including: +You can add as many triggers as you like to each points system you set up in Trophy. This let's you create different logic for how points are awarded to users for different points systems. + +Points can be awarded as a result of many different user interactions tracked by Trophy including: - Awarding points as users increment [Metrics](/platform/metrics) e.g. "earn 10 points for every mile ran". - Awarding points for reaching [Streak](/platform/streaks) milestones e.g. reaching 7-day, 14-day and 30-day streaks. @@ -38,7 +74,7 @@ Points can be awarded as a result of user interactions tracked by Trophy includi > -To create a new points trigger, head to the [points](https://app.trophy.so/points/configure/new) page in the Trophy dashboard and follow the steps below: +To create a new points trigger, head to the points system that you want to create a trigger for and follow the steps below: All new points triggers are created as 'Inactive' to allow testing and @@ -68,6 +104,15 @@ To create a new points trigger, head to the [points](https://app.trophy.so/point + + You can assign _attribute filters_ to a points trigger to further restrict when they apply. + +- To limit a **Metric trigger** to only apply to events with specific [custom event attributes](/platform/events#custom-event-attributes), select an attribute and enter a value in the **Event Attribute** section. + +- To limit any type of trigger to only apply to a user with one or more specific [custom user attributes](/platform/users#custom-user-attributes), add attributes and the desired values in the **User Attributes** section. + + + Save the new points trigger. @@ -77,7 +122,7 @@ To create a new points trigger, head to the [points](https://app.trophy.so/point Running an effective points system requires finding the optimal pace at which users earn points. Too fast, and users will get points fatigue, rendering them useless. Too slow, and users may get bored and churn. -Trophy's preview tool can model different scenarios to help you determine how frequently users should earn points. +Trophy's preview tool can model different scenarios to help you determine how frequently users should earn points in each of your points systems.