diff --git a/admin-api/endpoints/streaks/grant-freezes.mdx b/admin-api/endpoints/streaks/grant-freezes.mdx new file mode 100644 index 0000000..7fe477d --- /dev/null +++ b/admin-api/endpoints/streaks/grant-freezes.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /streaks/freezes +--- diff --git a/admin-api/introduction.mdx b/admin-api/introduction.mdx new file mode 100644 index 0000000..51ee942 --- /dev/null +++ b/admin-api/introduction.mdx @@ -0,0 +1,17 @@ +--- +title: Introduction +description: Learn about the Trophy Admin API and how to use it to drive custom workflows using Trophy data. +subtitle: Learn about the Trophy Admin API and how to use it to drive custom workflows using Trophy data. +--- + +The Trophy Admin API is a set of endpoints for building custom gamification workflows. While the [Application API](/api-reference/introduction) models the data and interactions required to deliver the gamification experience in-app, the Admin API models administrative actions that are only performed by your team or business logic outside of your application. + +The Admin API is accessible through **the same SDKs** as the Application API or, for those who manage their own HTTP clients, is available at the following base URL. + +```bash Base URL +https://admin.trophy.so/v1 +``` + +## Get Support + +Want to get in touch with the Trophy team? Reach out to us via [email](mailto:support@trophy.so). We're here to help! diff --git a/api-reference/introduction.mdx b/api-reference/introduction.mdx index 4e67057..433e1a8 100644 --- a/api-reference/introduction.mdx +++ b/api-reference/introduction.mdx @@ -4,10 +4,16 @@ description: Learn about the Trophy API and get started building your integratio subtitle: Learn about the Trophy API and get started building your integration. --- -The Trophy API is a set of endpoints that provide simple interfaces for building gamification experiences, taking care of the tricky bits behind the scenes while being flexible enough to support any gamification use case. +The Trophy Application API is a set of endpoints that provide simple interfaces for building gamification experiences, taking care of the tricky bits behind the scenes while being flexible enough to support any gamification use case. There are no usage limits or paywalls, and everybody has access to the exact same API to build to their hearts content. +The Application API is accessible through [SDKs](/api-reference/client-libraries) available in most major programming languages or, for those who wish manage their own HTTP clients, is available at the following base URL. + +```bash Base URL +https://api.trophy.so/v1 +``` + Securely integrate your applications with the Trophy API using API keys. diff --git a/api-reference/openapi.yml b/api-reference/openapi.yml index 891c983..575db84 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: # APPLICATION API ------------------------------------------------------- @@ -33,14 +33,14 @@ paths: response = client.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: @@ -81,18 +81,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: [] @@ -138,12 +138,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: @@ -155,7 +155,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 @@ -167,31 +167,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: [] @@ -203,7 +203,7 @@ paths: type: object properties: user: - $ref: '#/components/schemas/UpsertedUser' + $ref: "#/components/schemas/UpsertedUser" description: The user that completed the achievement. required: - user @@ -295,12 +295,12 @@ paths: type: string example: e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f responses: - '201': + "201": description: Created event content: application/json: schema: - $ref: '#/components/schemas/EventResponse' + $ref: "#/components/schemas/EventResponse" examples: Successful operation: value: @@ -315,14 +315,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 @@ -334,7 +334,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 @@ -355,28 +355,28 @@ paths: metricName: words written metricKey: words-written threshold: 10 - start: '2025-01-01' + start: "2025-01-01" end: null previousRank: null rank: 100 - '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: [] @@ -388,7 +388,7 @@ paths: type: object properties: user: - $ref: '#/components/schemas/UpsertedUser' + $ref: "#/components/schemas/UpsertedUser" description: The user that triggered the event. value: type: number @@ -414,7 +414,7 @@ paths: user: email: user@example.com tz: Europe/London - id: '18' + id: "18" attributes: department: engineering role: developer @@ -476,15 +476,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: @@ -492,29 +492,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}: servers: - url: https://api.trophy.so @@ -554,12 +554,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: @@ -567,29 +567,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 @@ -645,7 +645,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UpdatedUser' + $ref: "#/components/schemas/UpdatedUser" description: The user object. example: email: user@example.com @@ -654,12 +654,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: @@ -667,26 +667,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 @@ -742,7 +742,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UpdatedUser' + $ref: "#/components/schemas/UpdatedUser" description: The user object. example: id: user-id @@ -752,12 +752,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: @@ -765,32 +765,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: servers: - url: https://api.trophy.so @@ -827,14 +827,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: @@ -849,14 +849,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 @@ -864,24 +864,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: [] @@ -928,12 +928,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: @@ -948,13 +948,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 @@ -962,24 +962,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: [] @@ -1053,7 +1053,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. @@ -1061,9 +1061,9 @@ paths: schema: type: string format: date - example: '2024-01-31' + example: "2024-01-31" responses: - '200': + "200": description: Successful operation content: application/json: @@ -1076,7 +1076,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 @@ -1094,33 +1094,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: [] @@ -1187,17 +1187,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: @@ -1205,7 +1205,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 @@ -1216,7 +1216,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 @@ -1225,28 +1225,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: [] @@ -1296,63 +1296,63 @@ 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" rank: 5 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: [] @@ -1390,38 +1390,38 @@ paths: type: array items: type: string - example: 'user-123,user-456,user-789' + example: "user-123,user-456,user-789" responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/BulkStreakResponse' + $ref: "#/components/schemas/BulkStreakResponse" examples: Successful operation: value: - userId: user-123 streakLength: 15 - extended: '2025-01-01T05:03:00Z' + extended: "2025-01-01T05:03:00Z" - userId: user-456 streakLength: 12 - extended: '2025-01-01T08:43:00Z' + extended: "2025-01-01T08:43:00Z" - userId: user-789 streakLength: 0 extended: null - '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 the streak lengths of a list of users security: - ApiKeyAuth: [] @@ -1472,18 +1472,18 @@ paths: required: false schema: type: string - enum: ['active', 'longest'] - default: 'active' - example: 'active' + enum: ["active", "longest"] + default: "active" + example: "active" responses: - '200': + "200": description: Successful operation content: application/json: schema: type: array items: - $ref: '#/components/schemas/StreakRankingUser' + $ref: "#/components/schemas/StreakRankingUser" examples: Successful operation: value: @@ -1496,18 +1496,18 @@ paths: - userId: user-789 name: Charlie Brown streakLength: 8 - '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 top users by streak length security: - ApiKeyAuth: [] @@ -1562,12 +1562,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: @@ -1579,7 +1579,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 @@ -1587,24 +1587,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: [] @@ -1678,7 +1678,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. @@ -1686,9 +1686,9 @@ paths: schema: type: string format: date - example: '2024-01-31' + example: "2024-01-31" responses: - '200': + "200": description: Successful operation content: application/json: @@ -1701,7 +1701,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 @@ -1719,33 +1719,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: [] @@ -1804,14 +1804,14 @@ paths: schema: type: string format: date - example: '2025-01-15' + example: "2025-01-15" responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/UserLeaderboardResponse' + $ref: "#/components/schemas/UserLeaderboardResponse" examples: Successful operation: value: @@ -1824,7 +1824,7 @@ paths: pointsSystemKey: null pointsSystemName: null description: Compete weekly to see who writes the most words - start: '2025-01-01' + start: "2025-01-01" end: null maxParticipants: 100 runUnit: day @@ -1832,39 +1832,39 @@ paths: rank: 2 value: 4500 history: - - timestamp: '2025-01-15T10:30:00Z' + - timestamp: "2025-01-15T10:30:00Z" previousRank: null rank: 5 previousValue: null value: 1000 - - timestamp: '2025-01-15T14:15:00Z' + - timestamp: "2025-01-15T14:15:00Z" previousRank: 5 rank: 3 previousValue: 1000 value: 3000 - - timestamp: '2025-01-15T18:45:00Z' + - timestamp: "2025-01-15T18:45:00Z" previousRank: 3 rank: 2 previousValue: 3000 value: 4500 - '401': - description: 'Unauthorized' + "401": + description: "Unauthorized" content: application/json: schema: - $ref: '#/components/schemas/ErrorBody' - '404': - description: 'User or leaderboard not found' + $ref: "#/components/schemas/ErrorBody" + "404": + description: "User or leaderboard 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 leaderboard data security: - ApiKeyAuth: [] @@ -1916,12 +1916,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: @@ -1958,24 +1958,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: [] @@ -2015,12 +2015,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: @@ -2044,15 +2044,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 @@ -2062,20 +2062,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: [] @@ -2107,14 +2107,14 @@ paths: response = client.leaderboards.all() responses: - '200': + "200": description: Successful operation content: application/json: schema: type: array items: - $ref: '#/components/schemas/LeaderboardResponse' + $ref: "#/components/schemas/LeaderboardResponse" examples: Successful operation: value: @@ -2128,7 +2128,7 @@ paths: pointsSystemName: null description: Compete weekly to see who writes the most words status: active - start: '2025-01-01' + start: "2025-01-01" end: null maxParticipants: 100 runUnit: day @@ -2143,23 +2143,23 @@ paths: pointsSystemName: Experience Points description: Overall ranking by XP earned status: active - start: '2025-01-01' + start: "2025-01-01" end: null maxParticipants: 50 runUnit: null runInterval: 0 - '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 active leaderboards security: - ApiKeyAuth: [] @@ -2232,21 +2232,21 @@ paths: schema: type: string format: date - example: '2025-01-15' + example: "2025-01-15" - name: userId in: query description: When provided, offset is relative to this user's position on the leaderboard. If the user is not found in the leaderboard, returns empty rankings array. required: false schema: type: string - example: 'user-123' + example: "user-123" responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/LeaderboardResponseWithRankings' + $ref: "#/components/schemas/LeaderboardResponseWithRankings" examples: Successful operation: value: @@ -2260,7 +2260,7 @@ paths: pointsSystemName: null description: Compete weekly to see who writes the most words status: active - start: '2025-01-01' + start: "2025-01-01" end: null maxParticipants: 100 runUnit: day @@ -2278,24 +2278,24 @@ paths: userName: Charlie Brown rank: 3 value: 4200 - '401': - description: 'Unauthorized' + "401": + description: "Unauthorized" content: application/json: schema: - $ref: '#/components/schemas/ErrorBody' - '404': - description: 'Leaderboard not found' + $ref: "#/components/schemas/ErrorBody" + "404": + description: "Leaderboard 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 leaderboard security: - ApiKeyAuth: [] @@ -2350,7 +2350,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CreateStreakFreezesRequest' + $ref: "#/components/schemas/CreateStreakFreezesRequest" examples: Create freezes for multiple users: value: @@ -2359,12 +2359,12 @@ paths: - userId: user-456 - userId: user-123 responses: - '200': + "200": description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/CreateStreakFreezesResponse' + $ref: "#/components/schemas/CreateStreakFreezesResponse" examples: Success with no issues: value: @@ -2384,24 +2384,24 @@ paths: - userId: user-456 level: warning reason: Would exceed maximum freeze limit - '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: Create streak freezes for multiple users security: - ApiKeyAuth: [] @@ -2430,7 +2430,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 @@ -2485,7 +2485,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: @@ -2496,7 +2496,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: @@ -2513,12 +2513,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. @@ -2545,7 +2545,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. @@ -2578,7 +2578,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 @@ -2602,7 +2602,7 @@ components: type: array description: Array of trigger awards that added points. items: - $ref: '#/components/schemas/PointsAward' + $ref: "#/components/schemas/PointsAward" required: - id - name @@ -2627,56 +2627,56 @@ components: example: weekly-words status: type: string - enum: ['active', 'scheduled', 'finished'] + enum: ["active", "scheduled", "finished"] description: The status of the leaderboard. example: active rankBy: type: string - enum: ['points', 'streak', 'metric'] + enum: ["points", "streak", "metric"] description: What the leaderboard ranks by. example: metric metricKey: type: - string - - 'null' + - "null" description: The key of the metric to rank by, if rankBy is 'metric'. example: words-written metricName: type: - string - - 'null' + - "null" description: The name of the metric to rank by, if rankBy is 'metric'. example: Words Written pointsSystemKey: type: - string - - 'null' + - "null" description: The key of the points system to rank by, if rankBy is 'points'. example: xp-system pointsSystemName: type: - string - - 'null' + - "null" description: The name of the points system to rank by, if rankBy is 'points'. example: Experience Points description: type: - string - - 'null' + - "null" description: The user-facing description of the leaderboard. example: Compete weekly to see who writes the most words start: type: string format: date description: The start date of the leaderboard in YYYY-MM-DD format. - example: '2025-01-01' + example: "2025-01-01" end: type: - string - - 'null' + - "null" format: date description: The end date of the leaderboard in YYYY-MM-DD format, or null if it runs forever. - example: '2025-12-31' + example: "2025-12-31" maxParticipants: type: integer description: The maximum number of participants in the leaderboard. @@ -2684,8 +2684,8 @@ components: runUnit: type: - string - - 'null' - enum: ['day', 'month', 'year', null] + - "null" + enum: ["day", "month", "year", null] description: The repetition type for recurring leaderboards, or null for one-time leaderboards. example: day runInterval: @@ -2704,21 +2704,21 @@ components: title: LeaderboardResponseWithRankings type: object allOf: - - $ref: '#/components/schemas/LeaderboardResponse' + - $ref: "#/components/schemas/LeaderboardResponse" - type: object properties: rankings: type: array description: Array of user rankings for the leaderboard. items: - $ref: '#/components/schemas/LeaderboardRanking' + $ref: "#/components/schemas/LeaderboardRanking" required: - rankings MetricEventPointsResponse: title: MetricEventPointsResponse type: object allOf: - - $ref: '#/components/schemas/GetUserPointsResponse' + - $ref: "#/components/schemas/GetUserPointsResponse" - type: object properties: added: @@ -2729,19 +2729,19 @@ components: title: MetricEventLeaderboardResponse type: object allOf: - - $ref: '#/components/schemas/LeaderboardResponse' + - $ref: "#/components/schemas/LeaderboardResponse" - type: object properties: start: type: string format: date description: The start date of the current run of the leaderboard. - example: '2025-01-01' + example: "2025-01-01" end: type: string format: date description: The end date of the current run of the leaderboard, or null if the run never ends. - example: '2025-12-31' + example: "2025-12-31" rank: type: integer description: The user's rank in the leaderboard, or null if the user is not on the leaderboard. @@ -2769,7 +2769,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 @@ -2797,7 +2797,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. @@ -2809,7 +2809,7 @@ components: title: CompletedAchievementResponse type: object allOf: - - $ref: '#/components/schemas/AchievementResponse' + - $ref: "#/components/schemas/AchievementResponse" - type: object properties: achievedAt: @@ -2820,7 +2820,7 @@ components: title: AchievementWithStatsResponse type: object allOf: - - $ref: '#/components/schemas/AchievementResponse' + - $ref: "#/components/schemas/AchievementResponse" - type: object properties: completions: @@ -2879,7 +2879,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 @@ -2889,7 +2889,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. @@ -2923,7 +2923,7 @@ components: items: type: string description: The device token. - example: ['token1', 'token2'] + example: ["token1", "token2"] subscribeToEmails: type: boolean default: true @@ -2942,7 +2942,7 @@ components: type: object description: An object with editable user fields. allOf: - - $ref: '#/components/schemas/UpdatedUser' + - $ref: "#/components/schemas/UpdatedUser" - type: object properties: id: @@ -2956,7 +2956,7 @@ components: type: object description: A user of your application. allOf: - - $ref: '#/components/schemas/UpsertedUser' + - $ref: "#/components/schemas/UpsertedUser" - type: object properties: control: @@ -2967,12 +2967,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 @@ -2990,11 +2990,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: @@ -3020,22 +3020,22 @@ 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. points: type: object additionalProperties: - $ref: '#/components/schemas/MetricEventPointsResponse' + $ref: "#/components/schemas/MetricEventPointsResponse" description: >- A map of points systems by key. leaderboards: type: object additionalProperties: - $ref: '#/components/schemas/MetricEventLeaderboardResponse' + $ref: "#/components/schemas/MetricEventLeaderboardResponse" description: >- A map of leaderboards by key. idempotencyKey: @@ -3070,7 +3070,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 @@ -3080,14 +3080,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 @@ -3167,7 +3167,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 @@ -3184,7 +3184,7 @@ components: name: type: - string - - 'null' + - "null" description: The name of the user. May be null if no name is set. example: Alice Johnson streakLength: @@ -3207,7 +3207,7 @@ components: userName: type: - string - - 'null' + - "null" description: The name of the user. May be null if no name is set. example: Alice Johnson rank: @@ -3232,29 +3232,29 @@ components: type: string format: date-time description: The timestamp when the event occurred. - example: '2025-01-15T10:30:00Z' + example: "2025-01-15T10:30:00Z" previousRank: type: - integer - - 'null' + - "null" description: The user's rank before this event, or null if they were not on the leaderboard. example: 5 rank: type: - integer - - 'null' + - "null" description: The user's rank after this event, or null if they are no longer on the leaderboard. example: 3 previousValue: type: - integer - - 'null' + - "null" description: The user's value before this event, or null if they were not on the leaderboard. example: 1000 value: type: - integer - - 'null' + - "null" description: The user's value after this event, or null if they are no longer on the leaderboard. example: 3000 required: @@ -3268,25 +3268,25 @@ components: type: object description: A user's data for a specific leaderboard including rank, value, and history. allOf: - - $ref: '#/components/schemas/LeaderboardResponse' + - $ref: "#/components/schemas/LeaderboardResponse" - type: object properties: rank: type: - integer - - 'null' + - "null" description: The user's current rank in this leaderboard. Null if the user is not on the leaderboard. example: 2 value: type: - integer - - 'null' + - "null" description: The user's current value in this leaderboard. Null if the user is not on the leaderboard. example: 4500 history: type: array items: - $ref: '#/components/schemas/LeaderboardEvent' + $ref: "#/components/schemas/LeaderboardEvent" description: An array of events showing the user's rank and value changes over time. required: - rank @@ -3321,7 +3321,7 @@ components: issues: type: array items: - $ref: '#/components/schemas/BulkInsertIssue' + $ref: "#/components/schemas/BulkInsertIssue" description: Array of issues encountered during freeze creation. required: - issues diff --git a/assets/platform/streaks/freezes.png b/assets/platform/streaks/freezes.png new file mode 100644 index 0000000..3a47ca2 Binary files /dev/null and b/assets/platform/streaks/freezes.png differ diff --git a/docs.json b/docs.json index b3dd845..40379c3 100644 --- a/docs.json +++ b/docs.json @@ -38,6 +38,7 @@ "tabs": [ { "tab": "Home", + "icon": "house", "groups": [ { "group": "Getting Started", @@ -80,6 +81,7 @@ }, { "tab": "Guides", + "icon": "rocket", "dropdowns": [ { "dropdown": "Tutorials", @@ -106,7 +108,8 @@ ] }, { - "tab": "API Reference", + "tab": "Application API", + "icon": "globe", "groups": [ { "group": "Overview", @@ -170,6 +173,20 @@ ] } ] + }, + { + "tab": "Admin API", + "icon": "globe-lock", + "groups": [ + { + "group": "Overview", + "pages": ["admin-api/introduction"] + }, + { + "group": "Streaks", + "pages": ["admin-api/endpoints/streaks/grant-freezes"] + } + ] } ], "global": { diff --git a/platform/streaks.mdx b/platform/streaks.mdx index ce4cf09..a252a70 100644 --- a/platform/streaks.mdx +++ b/platform/streaks.mdx @@ -19,15 +19,13 @@ A streak is a period of consecutive days, weeks or months that a user has perfor Streaks are **global** to your platform, meaning that each user has a single streak across all interactions. You can decide which [Metrics](/platform/metrics) should contribute a user's streak on the [streaks configure](https://staging-app.trophy.so/streaks/configure) page. -## Key Attributes - -### Streak Frequency +## Streak Frequency Streaks can be configured to be daily, weekly or monthly. This means that a user must increment a metric at least once every calendar day, week or month to maintain their streak. Trophy will automatically compute streak data for all streak frequencies, which means you can change the frequency at any time while maintaining users' streaks. Just note that changing the frequency may be confusing for users, so best to communicate any changes ahead of time. -### Streak Metrics +## Streak Metrics You can choose which metrics should contribute to a user's streak @@ -40,6 +38,42 @@ For example, if your platform is a language learning app, you might want to trac for as long as you've been using Trophy. +## Streak Freezes + +Streak freezes help users keep their streaks for longer by allowing them to miss periods without it resetting to zero. This helps keep streaks motivating even if users don't maintain a perfect usage habit. + + + + + +Streak freezes are optional in Trophy but can be configured on the [streaks page](https://app.trophy.so/streaks) of the Trophy dashboard. + +### Granting Initial Freezes + +You can configure any number of arbitrary freezes to grant to new users when you first identify them with Trophy. + +Giving users too many freezes may decrease their perceived value, but granting too few freezes might result it a higher number of lost streaks. + + + As a general rule of thumb, aim for the average user to have one or two + freezes in their account in any given period to create a balanced experience. + + +### Freeze Accumulation + +As users use up streak freezes, they'll need a continuous supply of new ones to keep them going. To facilitate this, Trophy can automatically grant streak freezes to users over time. You can choose an arbitrary number of days over which to grant an arbitrary number of freezes to each user. + +If you've [configured time zones](/platform/users#param-tz) for your users, Trophy will automatically consume freezes at midnight in the user's time zone when necessary to extend their streak, and if any new freezes are due to be greatned to a user, they will be granted up to ten minutes later. + +### Maximum Freeze Count + +In Trophy you also configure the maxiumum number of freezes that each user can have, up to a limit of 100. [Freeze accumulation](#freeze-accumulation) will only ever grant freezes up to this limit. + ## Tracking Streaks Trophy automatically calculates streaks for all users when users