diff --git a/account/branding.mdx b/account/branding.mdx
index c84a8126..caa81393 100644
--- a/account/branding.mdx
+++ b/account/branding.mdx
@@ -10,6 +10,8 @@ icon: palette
The [branding page](https://app.trophy.so/branding) in the Trophy dashboard allows you to configure the following account-level settings. These setting will be used in any communications you configure Trophy to send to users, like [Emails](/features/emails).
+You can also get and update branding, experimentation, and aggregation settings with the [organization settings Admin API](/admin-api/endpoints/settings/get-organization-settings).
+
diff --git a/admin-api/endpoints/achievements/create-achievements.mdx b/admin-api/endpoints/achievements/create-achievements.mdx
new file mode 100644
index 00000000..fd32dadc
--- /dev/null
+++ b/admin-api/endpoints/achievements/create-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Create achievements
+openapi: "/openapi/admin.json POST /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/achievements/delete-achievements.mdx b/admin-api/endpoints/achievements/delete-achievements.mdx
new file mode 100644
index 00000000..1e7d7e90
--- /dev/null
+++ b/admin-api/endpoints/achievements/delete-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Delete achievements
+openapi: "/openapi/admin.json DELETE /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/achievements/get-an-achievement.mdx b/admin-api/endpoints/achievements/get-an-achievement.mdx
new file mode 100644
index 00000000..edd22b25
--- /dev/null
+++ b/admin-api/endpoints/achievements/get-an-achievement.mdx
@@ -0,0 +1,10 @@
+---
+title: Get an achievement by ID
+openapi: "/openapi/admin.json GET /achievements/{id}"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/achievements/list-achievements.mdx b/admin-api/endpoints/achievements/list-achievements.mdx
new file mode 100644
index 00000000..aebc6369
--- /dev/null
+++ b/admin-api/endpoints/achievements/list-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: List achievements
+openapi: "/openapi/admin.json GET /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/achievements/update-achievements.mdx b/admin-api/endpoints/achievements/update-achievements.mdx
new file mode 100644
index 00000000..a027c4f9
--- /dev/null
+++ b/admin-api/endpoints/achievements/update-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Update achievements
+openapi: "/openapi/admin.json PATCH /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/attributes/get-an-attribute.mdx b/admin-api/endpoints/attributes/get-an-attribute.mdx
index a4359335..0ec89d89 100644
--- a/admin-api/endpoints/attributes/get-an-attribute.mdx
+++ b/admin-api/endpoints/attributes/get-an-attribute.mdx
@@ -1,5 +1,5 @@
---
-title: Get an attribute
+title: Get an attribute by ID
openapi: "/openapi/admin.json GET /attributes/{id}"
---
diff --git a/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx b/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
index 55fb17f5..25da5517 100644
--- a/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
+++ b/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
@@ -1,5 +1,5 @@
---
-title: Get a leaderboard
+title: Get a leaderboard by ID
openapi: "/openapi/admin.json GET /leaderboards/{id}"
---
diff --git a/admin-api/endpoints/settings/get-organization-settings.mdx b/admin-api/endpoints/settings/get-organization-settings.mdx
new file mode 100644
index 00000000..0ed3726c
--- /dev/null
+++ b/admin-api/endpoints/settings/get-organization-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Get organization settings
+openapi: "/openapi/admin.json GET /settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/settings/update-organization-settings.mdx b/admin-api/endpoints/settings/update-organization-settings.mdx
new file mode 100644
index 00000000..62e739db
--- /dev/null
+++ b/admin-api/endpoints/settings/update-organization-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Update organization settings
+openapi: "/openapi/admin.json PATCH /settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/streaks/get-streak-settings.mdx b/admin-api/endpoints/streaks/get-streak-settings.mdx
new file mode 100644
index 00000000..41b8ded1
--- /dev/null
+++ b/admin-api/endpoints/streaks/get-streak-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Get streak settings
+openapi: "/openapi/admin.json GET /streaks/settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/streaks/update-streak-settings.mdx b/admin-api/endpoints/streaks/update-streak-settings.mdx
new file mode 100644
index 00000000..cace2a3b
--- /dev/null
+++ b/admin-api/endpoints/streaks/update-streak-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Update streak settings
+openapi: "/openapi/admin.json PATCH /streaks/settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Rate Limits**
+
+
diff --git a/admin-api/endpoints/tenants/get-a-tenant.mdx b/admin-api/endpoints/tenants/get-a-tenant.mdx
index 84c83cb5..c2666300 100644
--- a/admin-api/endpoints/tenants/get-a-tenant.mdx
+++ b/admin-api/endpoints/tenants/get-a-tenant.mdx
@@ -1,5 +1,5 @@
---
-title: Get a tenant
+title: Get a tenant by ID
openapi: "/openapi/admin.json GET /tenants/{id}"
---
diff --git a/docs.json b/docs.json
index 07ef75ce..e3d001c5 100644
--- a/docs.json
+++ b/docs.json
@@ -256,9 +256,21 @@
"admin-api/endpoints/attributes/delete-attributes"
]
},
+ {
+ "group": "Achievements",
+ "pages": [
+ "admin-api/endpoints/achievements/list-achievements",
+ "admin-api/endpoints/achievements/get-an-achievement",
+ "admin-api/endpoints/achievements/update-achievements",
+ "admin-api/endpoints/achievements/create-achievements",
+ "admin-api/endpoints/achievements/delete-achievements"
+ ]
+ },
{
"group": "Streaks",
"pages": [
+ "admin-api/endpoints/streaks/get-streak-settings",
+ "admin-api/endpoints/streaks/update-streak-settings",
"admin-api/endpoints/streaks/grant-freezes",
"admin-api/endpoints/streaks/create-pauses",
"admin-api/endpoints/streaks/delete-pauses",
@@ -316,6 +328,13 @@
"admin-api/endpoints/application-api-keys/create-application-api-keys",
"admin-api/endpoints/application-api-keys/delete-application-api-keys"
]
+ },
+ {
+ "group": "Settings",
+ "pages": [
+ "admin-api/endpoints/settings/get-organization-settings",
+ "admin-api/endpoints/settings/update-organization-settings"
+ ]
}
]
},
@@ -644,9 +663,21 @@
"es/admin-api/endpoints/attributes/delete-attributes"
]
},
+ {
+ "group": "Logros",
+ "pages": [
+ "es/admin-api/endpoints/achievements/list-achievements",
+ "es/admin-api/endpoints/achievements/get-an-achievement",
+ "es/admin-api/endpoints/achievements/update-achievements",
+ "es/admin-api/endpoints/achievements/create-achievements",
+ "es/admin-api/endpoints/achievements/delete-achievements"
+ ]
+ },
{
"group": "Rachas",
"pages": [
+ "es/admin-api/endpoints/streaks/get-streak-settings",
+ "es/admin-api/endpoints/streaks/update-streak-settings",
"es/admin-api/endpoints/streaks/grant-freezes",
"es/admin-api/endpoints/streaks/create-pauses",
"es/admin-api/endpoints/streaks/delete-pauses",
@@ -704,6 +735,13 @@
"es/admin-api/endpoints/application-api-keys/create-application-api-keys",
"es/admin-api/endpoints/application-api-keys/delete-application-api-keys"
]
+ },
+ {
+ "group": "Ajustes",
+ "pages": [
+ "es/admin-api/endpoints/settings/get-organization-settings",
+ "es/admin-api/endpoints/settings/update-organization-settings"
+ ]
}
]
},
diff --git a/es/account/branding.mdx b/es/account/branding.mdx
index 31caf6b7..744ed5e3 100644
--- a/es/account/branding.mdx
+++ b/es/account/branding.mdx
@@ -1,26 +1,28 @@
---
title: Marca
-description: Configure su logotipo y los colores de marca utilizados en las
+description: Configura tu logotipo y colores de marca utilizados en las
funciones creadas con Trophy.
-og:description: Aprenda cómo Trophy rastrea el uso según la cantidad de usuarios
- que utilizan su producto.
+og:description: Descubre cómo Trophy rastrea el uso según el número de usuarios
+ que utilizan tu producto.
icon: palette
---
-## Configurar la Marca {#configure-branding}
+## Configurar la marca {#configure-branding}
-La [página de marca](https://app.trophy.so/branding) en el panel de Trophy le permite configurar los siguientes ajustes a nivel de cuenta. Estos ajustes se utilizarán en cualquier comunicación que configure Trophy para enviar a los usuarios, como [Correos electrónicos](/es/features/emails).
+La [página de marca](https://app.trophy.so/branding) en el panel de Trophy te permite configurar los siguientes ajustes a nivel de cuenta. Estos ajustes se utilizarán en cualquier comunicación que configures para que Trophy envíe a los usuarios, como [correos electrónicos](/es/features/emails).
+
+También puedes obtener y actualizar los ajustes de marca, experimentación y agregación con la [API de administración de configuración de organización](/es/admin-api/endpoints/settings/get-organization-settings).
-- **Logotipo**: Cargue el logotipo de su marca para mostrarlo en el encabezado de los correos electrónicos de Trophy. Recomendamos utilizar un logotipo horizontal con fondo transparente o un color de fondo sólido con esquinas redondeadas.
+- **Logotipo**: Sube el logotipo de tu marca para mostrarlo en el encabezado de los correos electrónicos de Trophy. Recomendamos usar un logotipo horizontal con fondo transparente o un color de fondo liso con esquinas redondeadas.
- **Fuente**: La fuente predeterminada utilizada en los correos electrónicos de Trophy.
-- **Color de Marca**: Elija un color primario para su marca. Trophy utilizará este color para botones y otros elementos en sus correos electrónicos.
-- **Nombre de la Aplicación**: Ingrese el nombre de su aplicación o servicio. Trophy utilizará este nombre en varios lugares de sus correos electrónicos.
-- **URL de la Aplicación**: Ingrese una URL predeterminada para usar cuando no se sobrescriba caso por caso en cada correo electrónico. Por lo general, esta es la URL de la página de inicio de sesión de su aplicación o servicio.
+- **Color de marca**: Elige un color principal para tu marca. Trophy utilizará este color para botones y otros elementos en tus correos electrónicos.
+- **Nombre de la aplicación**: Introduce el nombre de tu aplicación o servicio. Trophy utilizará este nombre en varios lugares de tus correos electrónicos.
+- **URL de la aplicación**: Introduce una URL predeterminada para usar cuando no se anule por correo electrónico. Normalmente, esta es la URL de la página de inicio de sesión de tu aplicación o servicio.
-## Obtener Soporte {#get-support}
+## Obtener soporte {#get-support}
-¿Desea ponerse en contacto con el equipo de Trophy? Comuníquese con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudar!
+¿Quieres contactar con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
diff --git a/es/admin-api/endpoints/achievements/create-achievements.mdx b/es/admin-api/endpoints/achievements/create-achievements.mdx
new file mode 100644
index 00000000..4323685d
--- /dev/null
+++ b/es/admin-api/endpoints/achievements/create-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Crear logros
+openapi: "/openapi/admin.json POST /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/achievements/delete-achievements.mdx b/es/admin-api/endpoints/achievements/delete-achievements.mdx
new file mode 100644
index 00000000..3d18efe5
--- /dev/null
+++ b/es/admin-api/endpoints/achievements/delete-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Eliminar logros
+openapi: "/openapi/admin.json DELETE /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/achievements/get-an-achievement.mdx b/es/admin-api/endpoints/achievements/get-an-achievement.mdx
new file mode 100644
index 00000000..c781c13f
--- /dev/null
+++ b/es/admin-api/endpoints/achievements/get-an-achievement.mdx
@@ -0,0 +1,10 @@
+---
+title: Obtener un logro por ID
+openapi: "/openapi/admin.json GET /achievements/{id}"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/achievements/list-achievements.mdx b/es/admin-api/endpoints/achievements/list-achievements.mdx
new file mode 100644
index 00000000..f66361da
--- /dev/null
+++ b/es/admin-api/endpoints/achievements/list-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Listar logros
+openapi: "/openapi/admin.json GET /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/achievements/update-achievements.mdx b/es/admin-api/endpoints/achievements/update-achievements.mdx
new file mode 100644
index 00000000..2f23da30
--- /dev/null
+++ b/es/admin-api/endpoints/achievements/update-achievements.mdx
@@ -0,0 +1,10 @@
+---
+title: Actualizar logros
+openapi: "/openapi/admin.json PATCH /achievements"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/attributes/get-an-attribute.mdx b/es/admin-api/endpoints/attributes/get-an-attribute.mdx
index c16a97ec..dbb19703 100644
--- a/es/admin-api/endpoints/attributes/get-an-attribute.mdx
+++ b/es/admin-api/endpoints/attributes/get-an-attribute.mdx
@@ -1,5 +1,5 @@
---
-title: Obtener un atributo
+title: Obtener un atributo por ID
openapi: "/openapi/admin.json GET /attributes/{id}"
---
diff --git a/es/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx b/es/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
index 2130d259..de989018 100644
--- a/es/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
+++ b/es/admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
@@ -1,5 +1,5 @@
---
-title: Obtener una clasificación
+title: Obtener una clasificación por ID
openapi: "/openapi/admin.json GET /leaderboards/{id}"
---
diff --git a/es/admin-api/endpoints/settings/get-organization-settings.mdx b/es/admin-api/endpoints/settings/get-organization-settings.mdx
new file mode 100644
index 00000000..62c5e36f
--- /dev/null
+++ b/es/admin-api/endpoints/settings/get-organization-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Obtener configuración de la organización
+openapi: "/openapi/admin.json GET /settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/settings/update-organization-settings.mdx b/es/admin-api/endpoints/settings/update-organization-settings.mdx
new file mode 100644
index 00000000..62a58839
--- /dev/null
+++ b/es/admin-api/endpoints/settings/update-organization-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Actualizar configuración de la organización
+openapi: "/openapi/admin.json PATCH /settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/streaks/get-streak-settings.mdx b/es/admin-api/endpoints/streaks/get-streak-settings.mdx
new file mode 100644
index 00000000..1d4d0d05
--- /dev/null
+++ b/es/admin-api/endpoints/streaks/get-streak-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Obtener configuración de racha
+openapi: "/openapi/admin.json GET /streaks/settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/streaks/update-streak-settings.mdx b/es/admin-api/endpoints/streaks/update-streak-settings.mdx
new file mode 100644
index 00000000..6f523d29
--- /dev/null
+++ b/es/admin-api/endpoints/streaks/update-streak-settings.mdx
@@ -0,0 +1,10 @@
+---
+title: Actualizar la configuración de racha
+openapi: "/openapi/admin.json PATCH /streaks/settings"
+---
+
+import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
+
+**Límites de velocidad**
+
+
diff --git a/es/admin-api/endpoints/tenants/get-a-tenant.mdx b/es/admin-api/endpoints/tenants/get-a-tenant.mdx
index 7d559706..7609ebbd 100644
--- a/es/admin-api/endpoints/tenants/get-a-tenant.mdx
+++ b/es/admin-api/endpoints/tenants/get-a-tenant.mdx
@@ -1,5 +1,5 @@
---
-title: Obtener un cliente
+title: Obtener un cliente por ID
openapi: "/openapi/admin.json GET /tenants/{id}"
---
diff --git a/es/features/achievements.mdx b/es/features/achievements.mdx
index 7b6820b6..ac653da5 100644
--- a/es/features/achievements.mdx
+++ b/es/features/achievements.mdx
@@ -1,9 +1,9 @@
---
title: Logros
description: Aprende a usar Logros en una experiencia de producto gamificada con Trophy.
-og:description: Utiliza logros de métrica, API, racha, aniversario y compuestos
- para recompensar a los usuarios por su progreso continuo y animarlos a
- descubrir nuevas partes de tu aplicación.
+og:description: Usa logros de métrica, API, racha, aniversario y compuestos para
+ recompensar a los usuarios por su progreso continuo y animarlos a descubrir
+ nuevas partes de tu aplicación.
icon: trophy
---
@@ -12,19 +12,19 @@ import AllAchievementsResponseBlock from "../../snippets/all-achievements-respon
## ¿Qué son los Logros? {#what-are-achievements}
-Los logros son recompensas que los usuarios pueden desbloquear al usar tu plataforma. Se pueden usar para recompensar a los usuarios por hacer un progreso continuo en los recorridos principales del usuario, o para motivarlos a explorar funciones más nuevas.
+Los logros son recompensas que los usuarios pueden desbloquear mientras usan tu plataforma. Se pueden utilizar para recompensar a los usuarios por el progreso continuo en los recorridos principales del usuario, o para motivarlos a explorar funcionalidades más recientes.
-Los logros funcionan mejor cuando están diseñados para incentivar a los usuarios a realizar acciones que probablemente aumenten la retención.
+Los logros funcionan mejor cuando están diseñados para incentivar a los usuarios a realizar acciones que probablemente conduzcan a un aumento de la retención.
- Usa las [analíticas de métrica](/es/features/metrics#metric-analytics) de Trophy para comparar
- la retención de cada interacción de usuario, luego configura logros en torno a
+ Usa las [analíticas de métricas](/es/features/metrics#metric-analytics) de Trophy para comparar
+ la retención de cada interacción del usuario, luego configura logros en torno a
estas interacciones para maximizar el impacto en la retención.
-Aquí revisaremos los tipos de logros que puedes construir con Trophy, las diferentes formas de usarlos y cómo integrarlos en tu plataforma.
+Aquí examinaremos los tipos de logros que puedes crear con Trophy, las diferentes formas de usarlos y cómo integrarlos en tu plataforma.
-Mira a Charlie ejecutar un recorrido usando logros en una aplicación NextJS:
+Mira a Charlie mientras explica el uso de logros en una aplicación NextJS:
@@ -69,48 +69,52 @@ Los logros de API solo se pueden completar una vez y son útiles para recompensa
Ejemplos comunes incluyen:
-- Un usuario completando su perfil después de registrarse
-- Un usuario vinculando su cuenta de redes sociales a una plataforma
-- Un usuario compartiendo su experiencia con el producto en redes sociales
+- Un usuario que completa su perfil después de registrarse
+- Un usuario que vincula su cuenta de redes sociales a una plataforma
+- Un usuario que comparte su experiencia con el producto en redes sociales
-Los logros de API sirven como una forma sencilla de recompensar a los usuarios por completar cualquier acción que consideres importante para la retención.
+Los logros de API sirven como una manera fácil de recompensar a los usuarios por completar cualquier acción que consideres importante para la retención.
-Al igual que los logros de métricas, los logros de API también pueden activar [Correos de Logros](/es/features/emails#achievement-emails) automatizados si está configurado.
+Al igual que los logros de métrica, los logros de API también pueden activar [Emails de Logros](/es/features/emails#achievement-emails) automatizados si están configurados.
### Logros de Racha {#streak-achievements}
-Los logros de racha están directamente vinculados a la [Racha](/es/features/streaks) de un usuario y se desbloquean automáticamente cuando los usuarios alcanzan una longitud de racha específica.
+Los logros de racha están directamente vinculados a la [Racha](/es/features/streaks) de un usuario y se desbloquean automáticamente cuando los usuarios alcanzan una duración de racha particular.
-Puedes crear tantos logros de racha como desees para longitudes de racha crecientes, por ejemplo 7 días, 30 días y 365 días para motivar a los usuarios a usar tu aplicación cada vez más.
+Puedes crear tantos logros de racha como desees para duraciones de racha cada vez mayores, por ejemplo 7 días, 30 días y 365 días para motivar a los usuarios a usar tu aplicación cada vez más.
-Al igual que los logros de métricas y API, puedes agregar un nombre personalizado y asignar una insignia a los logros de racha.
+Al igual que los logros de métrica y API, puedes agregar un nombre personalizado y asignar una insignia a los logros de racha.
### Logros de Aniversario {#anniversary-achievements}
Los logros de aniversario se desbloquean automáticamente cuando un usuario alcanza un aniversario específico de su fecha de registro.
-Crea un logro para cada año que desees celebrar, por ejemplo 1 año, 2 años y 5 años. Trophy desbloquea cada logro cuando se alcanza el [`signUpDate`](/es/features/users#optional-attributes) del usuario más ese número de años.
+Crea un logro para cada año que quieras celebrar, por ejemplo 1 año, 2 años y 5 años. Trophy desbloquea cada logro cuando se alcanza el [`signUpDate`](/es/features/users#optional-attributes) del usuario más ese número de años.
Los usuarios sin `signUpDate` no son elegibles. Establece `signUpDate` cuando [identifiques](/es/features/users#identifying-users) o [actualices](/es/features/users#keeping-users-up-to-date) usuarios para que Trophy pueda detectar aniversarios.
-Trophy evalúa el aniversario en el día calendario según el [`tz`](/es/features/users#optional-attributes) del usuario. Establece `tz` para que el logro se desbloquee en el día local correcto.
+Trophy evalúa el aniversario en el día calendario según la [`tz`](/es/features/users#optional-attributes) del usuario. Establece `tz` para que el logro se desbloquee en el día local correcto.
Al igual que otros tipos de logros, los logros de aniversario pueden activar [Correos de Logros](/es/features/emails#achievement-emails) cuando se desbloquean.
### Logros Compuestos {#composite-achievements}
-Los logros compuestos se desbloquean automáticamente cuando un usuario ha completado todos los logros prerequisito que selecciones. Son ideales para crear recompensas por niveles o de maestría que reconocen a los usuarios que han logrado un conjunto específico de hitos.
+Los logros compuestos se desbloquean automáticamente cuando un usuario ha completado todos los logros prerequisito que selecciones. Son ideales para crear recompensas por niveles o maestría que reconocen a los usuarios que han alcanzado un conjunto específico de hitos.
Por ejemplo, podrías crear un logro compuesto "Maestro del Estudio" que se desbloquea cuando un usuario ha completado:
-- 1,000 tarjetas de memoria
+- 1,000 tarjetas de estudio
- Racha de 7 días
- Completar la incorporación
-Los logros compuestos son útiles para crear rutas de progresión y animar a los usuarios a interactuar en diferentes áreas de tu aplicación. Al igual que otros tipos de logros, pueden activar [Correos de Logros](/es/features/emails#achievement-emails) cuando se desbloquean.
+Los logros compuestos son útiles para crear rutas de progresión y fomentar que los usuarios interactúen en diferentes áreas de tu aplicación. Al igual que otros tipos de logros, pueden activar [Correos de Logros](/es/features/emails#achievement-emails) cuando se desbloquean.
+
+## Crear Logros {#creating-achievements}
-## Creación de Logros {#creating-achievements}
+Para crear nuevos logros, dirígete a la [página de logros](https://app.trophy.so/achievements) en el panel de Trophy y haz clic en el botón **Nuevo Logro**:
-Para crear nuevos logros, dirígete a la [página de logros](https://app.trophy.so/achievements) en el panel de Trophy y pulsa el botón **Nuevo Logro**:
+
+También puedes crear, actualizar y eliminar logros mediante programación con la [API de administración](/es/admin-api/endpoints/achievements/create-achievements).
+
-Puedes asignar una insignia a cualquier logro subiendo una imagen—Trophy la sirve y devuelve la URL—o proporcionando tu propia URL de imagen. Las respuestas relevantes de la API incluyen ese valor en `badgeUrl` para usar como el `src` en etiquetas `
`.
+Puedes asignar una insignia a cualquier logro cargando una imagen—Trophy la sirve y devuelve la URL—o proporcionando tu propia URL de imagen. Las respuestas de API relevantes incluyen ese valor en `badgeUrl` para usarlo como `src` en las etiquetas `
`.
```json Response {8}
{
@@ -318,16 +322,16 @@ Puedes asignar una insignia a cualquier logro subiendo una imagen—Trophy la si
## Mostrar Logros {#displaying-achievements}
-Trophy cuenta con varias APIs que permiten mostrar logros dentro de tus aplicaciones. Aquí veremos las diferentes formas de usarlas y los tipos de interfaces de usuario que puedes construir.
+Trophy cuenta con varias APIs que permiten mostrar logros dentro de tus aplicaciones. Aquí veremos las diferentes formas de usarlas y los tipos de interfaces que puedes construir.
Consulta nuestra [guía completa](/es/guides/how-to-build-an-achievements-feature) sobre
- cómo agregar una funcionalidad de logros a tu aplicación para obtener más detalles.
+ cómo agregar una funcionalidad de logros a tu app para más detalles.
### Todos los Logros {#all-achievements}
-Para mostrar una vista general de alto nivel de todos los logros que los usuarios pueden completar, utiliza el [endpoint de todos los logros](/es/api-reference/endpoints/achievements/all-achievements). Usa estos datos para construir interfaces de usuario que den a los usuarios una idea de las vías de progresión dentro de tu aplicación.
+Para mostrar una vista general de alto nivel de todos los logros que los usuarios pueden completar, utiliza el [endpoint de todos los logros](/es/api-reference/endpoints/achievements/all-achievements). Usa estos datos para construir una interfaz que dé a los usuarios una idea de las rutas de progresión dentro de tu aplicación.
-El endpoint de todos los logros devuelve una lista de todos los logros dentro de tu cuenta de Trophy. Cada logro devuelto también incluye `completions` (el número de usuarios que han completado el logro) y `rarity` (el porcentaje de usuarios que han completado el logro) de la siguiente manera:
+El endpoint de todos los logros devuelve una lista de todos los logros dentro de tu cuenta de Trophy. Cada logro devuelto también incluye `completions` (el número de usuarios que han completado el logro) y `rarity` (el porcentaje de usuarios que han completado el logro) como sigue:
### Logros de Usuario {#user-achievements}
-Si en cambio estás construyendo elementos de interfaz de usuario específicos para usuarios, utiliza el [endpoint de logros de usuario](/es/api-reference/endpoints/users/get-a-users-completed-achievements) para devolver los logros que un usuario específico ha completado.
+Si en cambio estás construyendo elementos de interfaz específicos para usuarios, entonces utiliza el [endpoint de logros de usuario](/es/api-reference/endpoints/users/get-a-users-completed-achievements) para devolver los logros que un usuario específico ha completado.
- También puedes incluir logros que un usuario aún no ha completado agregando
+ También puedes incluir logros que un usuario aún no ha completado al incluir
el parámetro de consulta `includeIncomplete=true`.
@@ -361,9 +365,9 @@ Si en cambio estás construyendo elementos de interfaz de usuario específicos p
/>
-## Análisis de Logros {#achievement-analytics}
+## Analíticas de Logros {#achievement-analytics}
-Si tienes logros configurados para cualquiera de tus [Métricas](/es/features/metrics), entonces la página de análisis de métricas muestra un gráfico que te indica el progreso actual de todos los usuarios de la siguiente manera:
+Si tienes logros configurados para cualquiera de tus [Métricas](/es/features/metrics), entonces la página de analíticas de métricas muestra un gráfico que te presenta el progreso actual de todos los Usuarios de la siguiente manera:
- Utiliza logros de métricas para recompensar a los usuarios por realizar la misma acción una y otra vez, y para incentivarlos a hacerlo más.
+ Usa logros de métricas para recompensar a los usuarios por realizar la misma acción una y otra vez, y para incentivarlos a hacerlo más.
Usa logros de racha para recompensar a los usuarios por mantener su racha.
@@ -390,14 +394,14 @@ Si tienes logros configurados para cualquiera de tus [Métricas](/es/features/me
- Los logros, como toda gamificación, ofrecen la mejor retención cuando están estrechamente alineados con la razón principal del usuario para usar tu plataforma.
+ Los logros, como toda la gamificación, ofrecen la mejor retención cuando están estrechamente alineados con la razón principal por la que el usuario usa tu plataforma.
- Usa el [análisis de métricas](/es/features/metrics#metric-analytics) de Trophy para comparar la retención de cada interacción de usuario, luego configura logros alrededor de estas interacciones para maximizar el impacto en la retención.
+ Usa los [análisis de métricas](/es/features/metrics#metric-analytics) de Trophy para comparar la retención de cada interacción del usuario, luego configura logros en torno a estas interacciones para maximizar el impacto en la retención.
-## Obtén Soporte {#get-support}
+## Obtener soporte {#get-support}
-¿Quieres ponerte en contacto con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
+¿Quieres contactar con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
diff --git a/es/features/emails.mdx b/es/features/emails.mdx
index a3bccf66..9ce7c252 100644
--- a/es/features/emails.mdx
+++ b/es/features/emails.mdx
@@ -1,21 +1,21 @@
---
-title: Correos electrónicos
-description: Aprende a utilizar correos electrónicos en una experiencia de
- producto gamificada con Trophy.
-og:description: Usa flujos de correo automatizados para extender tu experiencia
- de gamificación fuera de tu aplicación y recordar a los usuarios que vuelvan.
+title: Emails
+description: Aprende a usar emails en una experiencia de producto gamificada con Trophy.
+og:description: Utiliza flujos de email automatizados para extender tu
+ experiencia de gamificación fuera de tu aplicación y recordar a los usuarios
+ que sigan regresando.
icon: mail
---
-import { PlanBadge } from "../../es/components/plan-badge.jsx";
+import { PlanBadge } from "../components/plan-badge.jsx";
-Trophy puede enviar correos electrónicos automatizados a los usuarios según activadores clave sin requerir código. Aquí veremos cuáles son estos activadores y cómo pueden formar parte de la experiencia de gamificación de tu producto.
+Trophy puede enviar emails automatizados a los usuarios basados en activadores clave sin requerir código. Aquí veremos cuáles son estos activadores y cómo pueden formar parte de la experiencia de gamificación de tu producto.
-## Tipos de correos electrónicos {#types-of-emails}
+## Tipos de Emails {#types-of-emails}
-Trophy admite 4 tipos de correos electrónicos, cada uno diseñado para adaptarse a un escenario común en la construcción de experiencias de gamificación.
+Trophy soporta 4 tipos de emails, cada uno diseñado para adaptarse a un escenario común en la construcción de experiencias de gamificación.
-Todos los correos electrónicos son opcionales, pero los cuatro pueden usarse simultáneamente y pueden controlarse desde la página [Emails](https://app.trophy.so/emails/configure) en el panel de Trophy.
+Todos los emails son opcionales, pero los cuatro pueden usarse simultáneamente y controlarse desde la página de [Emails](https://app.trophy.so/emails/configure) en el panel de Trophy.
-- **Correos de logros** se envían a los usuarios cada vez que desbloquean un [Logro](/es/features/achievements).
-- **Correos de resumen** se envían a los usuarios con una frecuencia predefinida para resumir el progreso. Los correos de resumen pueden configurarse para enviarse diaria, semanal, mensual o anualmente según tu caso de uso.
-- **Correos de reactivación** se envían a los usuarios después de que se vuelven inactivos con el objetivo de traerlos de vuelta a tu aplicación.
-- **Correos de racha** se envían automáticamente a los usuarios recordándoles que extiendan su [Racha](/es/features/streaks).
+- **Emails de logros** se envían a los usuarios cada vez que desbloquean un [Logro](/es/features/achievements).
+- **Emails de resumen** se envían a los usuarios con una frecuencia predefinida para resumir el progreso. Los emails de resumen pueden configurarse para enviarse diaria, semanal, mensual o anualmente según tu caso de uso.
+- **Emails de reactivación** se envían a los usuarios después de que se vuelven inactivos con el objetivo de traerlos de vuelta a tu aplicación.
+- **Emails de rachas** se envían automáticamente a los usuarios recordándoles extender su [Racha](/es/features/streaks).
-## Envío de correos electrónicos {#sending-emails}
+## Envío de Emails {#sending-emails}
-Para comenzar a enviar correos electrónicos con Trophy, necesitarás verificar tu dominio y agregar y activar plantillas de correo para los tipos que deseas enviar.
+Para comenzar a enviar emails con Trophy, necesitarás verificar tu dominio y añadir y activar plantillas de email para los tipos que deseas enviar.
- Los usuarios pueden controlar qué notificaciones por correo electrónico reciben a través del
+ Los usuarios pueden controlar qué notificaciones por email reciben a través del
[API de preferencias de usuario](/es/features/users#notification-preferences) de Trophy. Esto te permite
- construir un centro de preferencias en tu aplicación donde los usuarios puedan optar por recibir o no
- tipos específicos de correos electrónicos.
+ construir un centro de preferencias en tu aplicación donde los usuarios pueden activar o
+ desactivar tipos específicos de emails.
### Verificación de dominio {#domain-verification}
-Trophy permite enviar correos electrónicos desde tu propio dominio de forma nativa. Hay dos formas de configurar esto: Verificación del remitente y Verificación DNS.
+Trophy admite el envío de correos electrónicos desde tu propio dominio desde el primer momento. Hay dos formas de configurar esto: Verificación del remitente y Verificación DNS.
-Todos los ajustes de dominio se pueden encontrar en la página [Dominios](https://app.trophy.so/emails/domains) en el panel de Trophy.
+Todas las configuraciones de dominio se pueden encontrar en la página [Dominios](https://app.trophy.so/emails/domains) del panel de Trophy.
- Si buscas configurarlo rápidamente, recomendamos comenzar con Verificación del remitente y luego configurar la Verificación DNS cuando estés listo para pasar a producción.
+ Si buscas configurarte rápidamente, te recomendamos comenzar con la
+ Verificación del remitente y luego configurar la Verificación DNS cuando estés
+ listo para pasar a producción.
@@ -60,18 +62,18 @@ Todos los ajustes de dominio se pueden encontrar en la página [Dominios](https:
icon="check"
href="#sender-verification-basic"
>
- Verifica rápidamente una única dirección de correo electrónico
+ Verifica rápidamente una sola dirección de correo electrónico
Recomendado para uso en producción
-#### Verificación del remitente (Básica) {#sender-verification-basic}
+#### Verificación del remitente (básica) {#sender-verification-basic}
-Durante la incorporación se te pedirá configurar la Verificación del remitente. Esta es una forma muy sencilla de verificar rápidamente una única dirección de correo electrónico que deseas usar con Trophy sin necesidad de cambiar código ni configuraciones de DNS.
+Durante la incorporación, se te pedirá que configures la Verificación del remitente. Esta es una forma muy sencilla de verificar rápidamente una única dirección de correo electrónico que deseas usar con Trophy sin necesidad de cambiar código ni configuraciones DNS.
-Se te pedirá ingresar la dirección de correo electrónico, el nombre del remitente y el correo de respuesta que deseas que Trophy use al enviar correos:
+Se te pedirá que ingreses la dirección de correo electrónico, el nombre del remitente y el correo de respuesta que deseas que Trophy utilice al enviar correos:
-Trophy enviará un correo de verificación a esa dirección. Simplemente haz clic en el enlace del correo para informarle a Trophy que eres propietario de la dirección y estarás listo.
+Trophy enviará un correo de verificación a esa dirección. Simplemente haz clic en el enlace del correo para que Trophy sepa que eres el propietario de la dirección y estarás listo.
- El correo que recibas provendrá de nuestro proveedor de correo electrónico, Postmark. ¡Así que busca 'Postmark Support' en tu bandeja de entrada!
+ El correo que recibas provendrá de nuestro proveedor de correo, Postmark. ¡Así
+ que estate atento a 'Postmark Support' en tu bandeja de entrada!
-La Verificación del remitente es excelente para comenzar, pero tiene la limitación de que no aprovecharás tu reputación de correo existente y solo podrás enviar correos desde una dirección.
+La Verificación del remitente es excelente para comenzar, pero tiene la limitación de que no te beneficiarás de tu reputación de correo existente y solo podrás enviar correos desde una dirección.
-Además, si deseas cambiar la dirección en el futuro, tendrás que pasar por Verificación del remitente nuevamente, lo cual puedes hacer en la [pantalla de configuración](https://app.trophy.so/integration?tab=domains).
+Además, si deseas cambiar la dirección en el futuro, tendrás que realizar la Verificación del remitente nuevamente, lo cual puedes hacer en la [pantalla de configuración](https://app.trophy.so/integration?tab=domains).
#### Verificación DNS (Avanzado) {#dns-verification-advanced}
@@ -98,23 +101,23 @@ Además, si deseas cambiar la dirección en el futuro, tendrás que pasar por Ve
Esta función está disponible en el plan [Starter](/es/account/billing#starter-plan).
-Para uso en producción recomendamos la Verificación DNS. Una vez configurada, esto te permite configurar Trophy para enviar correos desde cualquier dirección de tu dominio. Así que si deseas cambiar la dirección en el futuro, no necesitarás verificar nuevamente.
+Para uso en producción, recomendamos la verificación DNS. Una vez configurada, esto te permite configurar Trophy para enviar correos electrónicos desde cualquier dirección en tu dominio. Así que si deseas cambiar la dirección en el futuro, no necesitarás verificar nuevamente.
-Completar la verificación DNS también te brinda todos los beneficios de cualquier reputación de dominio existente y es la mejor manera de asegurar que tus correos eviten la carpeta de spam.
+Completar la verificación DNS también te brinda todos los beneficios de cualquier reputación de dominio existente y es la mejor manera de asegurarte de que tus correos electrónicos eviten la carpeta de spam.
-Sin embargo, esto requiere agregar un par de entradas nuevas a tu DNS para permitir que Trophy verifique que eres propietario del dominio.
+Sin embargo, esto requiere agregar un par de nuevas entradas en tu DNS para permitir que Trophy verifique que eres propietario del dominio.
Sigue los pasos a continuación para configurar la verificación DNS:
-
- Dentro de la página de Correos, encontrarás la pestaña [Dominios](https://app.trophy.so/emails/domains) que es donde configurarás todo lo relacionado con el dominio de correo que Trophy utilizará para enviar correos en tu nombre.
+
+ Dentro de la página de Correos electrónicos, encontrarás la pestaña [Dominios](https://app.trophy.so/emails/domains), que es donde configurarás todo lo relacionado con el dominio de correo electrónico que Trophy utilizará para enviar correos en tu nombre.
- Desplázate hacia abajo hasta la sección de Verificación DNS e ingresa el dominio que deseas configurar con Trophy.
+ Dirígete a la sección de Verificación DNS e ingresa el dominio que deseas configurar con Trophy.
- También puedes configurar una Ruta de Retorno personalizada. Aquí es donde Trophy reenviará las notificaciones de correos rebotados para ayudarte a investigar problemas de entregabilidad:
+ También puedes configurar una Ruta de retorno personalizada. Aquí es donde Trophy reenviará las notificaciones de correos rebotados para ayudarte a investigar problemas de entregabilidad:
- Una vez que hayas ingresado tu dominio de correo, Trophy te proporcionará los detalles de dos nuevos registros DNS que necesitarás agregar a tu proveedor de DNS.
+ Una vez que hayas ingresado tu dominio de correo electrónico, Trophy te proporcionará los detalles de dos nuevos registros DNS que necesitarás agregar a tu proveedor de DNS.
- - Primero está el registro **DKIM**, que los proveedores de buzones de correo como Google utilizan para verificar la autenticidad de los emails. Introduce el nombre y el valor proporcionados como un nuevo registro **TXT** en tu proveedor de DNS.
- - Segundo está el registro **Return Path**. Este se utiliza para reenviar notificaciones de rebotes de email a tu dominio. Introduce el nombre y el valor proporcionados como un nuevo registro **CNAME** en tu proveedor de DNS.
+ - Primero está el registro **DKIM** que utilizan los proveedores de correo como Google para verificar la autenticidad de los correos electrónicos. Ingresa el nombre y el valor proporcionados como un nuevo registro **TXT** en tu proveedor de DNS.
+ - Segundo está el registro **Return Path**. Este se utiliza para reenviar notificaciones de rebotes de correo electrónico a tu dominio. Ingresa el nombre y el valor proporcionados como un nuevo registro **CNAME** en tu proveedor de DNS.
Estas son las páginas de los proveedores de DNS más comunes sobre cómo configurar nuevos registros:
@@ -165,11 +168,11 @@ Sigue los pasos a continuación para configurar la verificación DNS:
- Una vez que hayas agregado los dos registros en tu configuración de DNS, pulsa el ícono de actualización y Trophy intentará verificar los registros por ti.
+ Una vez que hayas agregado los dos registros en tu configuración de DNS, pulsa el ícono de actualizar y Trophy intentará verificar los registros por ti.
- Normalmente Trophy puede verificar los registros en unos minutos, pero ten en cuenta que los cambios de DNS pueden tardar hasta unas horas en propagarse completamente.
+ Normalmente Trophy puede verificar los registros en unos pocos minutos, pero ten en cuenta que los cambios de DNS pueden tardar hasta unas horas en propagarse completamente.
- Si ves la siguiente alerta, puede que los registros aún no se hayan propagado, o puede haber un problema con tu configuración.
+ Si ves la siguiente alerta, es posible que los registros aún no se hayan propagado o que haya un problema con tu configuración.
-### Disparadores de Email {#email-triggers}
+### Activadores de correo electrónico {#email-triggers}
-En la página de [configuración de email](https://app.trophy.so/emails/configure), cada tipo de email tiene su propia sección. Agrega plantillas bajo el tipo relevante y activa una para comenzar a enviar.
+En la página de [configuración de correo electrónico](https://app.trophy.so/emails/configure), cada tipo de correo tiene su propia sección. Agrega plantillas bajo el tipo correspondiente y activa una para comenzar a enviar.
-#### Emails de Resumen {#recap-emails}
+#### Correos de resumen {#recap-emails}
-Los emails de **Resumen** envían informes de progreso semanales o mensuales a los usuarios. Puedes cambiar la frecuencia de estos emails en la página de [integración](https://app.trophy.so/integration/configure) usando la configuración de **Período de Agregación**.
+Los correos de **resumen** envían reportes de progreso semanales o mensuales a los usuarios. Puedes cambiar la frecuencia de estos correos en la página de [integración](https://app.trophy.so/integration/configure) usando la configuración de **Período de agregación**, o con la [Admin API de configuración de organización](/es/admin-api/endpoints/settings/update-organization-settings).
-#### Emails de Reactivación {#reactivation-emails}
+#### Correos de Reactivación {#reactivation-emails}
-Los emails de **Reactivación** envían mensajes de recuperación a los usuarios después de que se vuelven inactivos. Estos emails se envían según el siguiente cronograma:
+Los correos de **Reactivación** envían mensajes de recuperación a los usuarios después de que se vuelven inactivos. Estos correos se envían según el siguiente cronograma:
- Después de 3 días de inactividad
- Después de 5 días de inactividad
@@ -250,9 +253,9 @@ Los emails de **Reactivación** envían mensajes de recuperación a los usuarios
/>
-#### Emails de Rachas {#streak-emails}
+#### Correos de Racha {#streak-emails}
-Los emails de **Rachas** recuerdan a los usuarios extender su racha antes de que expire. Estos emails se envían según la frecuencia de racha que configuraste en la [página de rachas](https://app.trophy.so/streaks):
+Los correos de **Racha** recuerdan a los usuarios extender su racha antes de que expire. Estos correos se envían según la frecuencia de racha que configuraste en la [página de rachas](https://app.trophy.so/streaks):
- Si tu aplicación usa una **racha diaria**, este correo se enviará cuatro horas antes del final del día (en la zona horaria de cada usuario).
- Para **rachas semanales**, se enviará el viernes por la mañana.
@@ -269,7 +272,7 @@ Los emails de **Rachas** recuerdan a los usuarios extender su racha antes de que
#### Correos de Logros {#achievement-emails}
-Los correos de **logros** felicitan a los usuarios cuando completan un [logro](/es/features/achievements) que has configurado en Trophy. Estos correos se envían entre las 5-9 PM el día en que se completa el logro, o al día siguiente a las 5 PM si ya han pasado las 9 PM cuando el usuario completa el logro.
+Los correos de **Logro** felicitan a los usuarios cuando completan un [logro](/es/features/achievements) que hayas configurado en Trophy. Estos correos se envían entre las 5 y las 9 PM el día en que se completa el logro, o al día siguiente a las 5 PM si es después de las 9 PM cuando el usuario completa el logro.
- Si envías los correos tú mismo a partir de estos webhooks, asegúrate de que las plantillas de correo correspondientes estén desactivadas en Trophy. Los webhooks de correo siguen disparándose cuando los triggers corresponden incluso si las plantillas están deshabilitadas, pero si las plantillas siguen habilitadas Trophy también enviará sus propios correos, lo que resultará en entregas duplicadas.
+ Si estás enviando correos electrónicos tú mismo desde estos webhooks, asegúrate de que las plantillas de correo electrónico correspondientes estén desactivadas en Trophy. Los webhooks de correo electrónico se activan cuando se cumplen los disparadores incluso si las plantillas están deshabilitadas, pero si las plantillas permanecen habilitadas, Trophy también enviará sus propios correos electrónicos, lo que resultará en una entrega duplicada.
-## Diseño de Correos {#designing-emails}
+## Diseño de correos electrónicos {#designing-emails}
-Trophy cuenta con un editor de correos basado en bloques completamente funcional que te permite diseñar plantillas, controlando todo el texto del correo y las líneas de asunto. En la página de [correos](https://app.trophy.so/emails/configure), agrega plantillas en cada sección de [tipo de correo](#email-triggers) que desees usar.
+Trophy tiene un editor de correo electrónico basado en bloques con todas las funciones que te permite diseñar plantillas, controlando todo el texto del correo electrónico y las líneas de asunto. En la página de [correos electrónicos](https://app.trophy.so/emails/configure), añade plantillas en cada sección de [tipo de correo electrónico](#email-triggers) que desees utilizar.
-### Plantillas Predeterminadas {#default-templates}
+### Plantillas predeterminadas {#default-templates}
-Por defecto, Trophy proporciona una plantilla para cada [tipo de correo electrónico](#types-of-emails) como punto de partida. Las plantillas predeterminadas no se pueden modificar, pero puedes duplicarlas y personalizarlas como desees.
+Por defecto, Trophy proporciona una plantilla para cada [tipo de correo electrónico](#types-of-emails) como un buen punto de partida. Las plantillas predeterminadas no se pueden cambiar, pero puedes duplicarlas y personalizarlas como desees.
- También puedes crear plantillas en blanco si prefieres empezar desde cero.
+ También puedes crear plantillas en blanco si solo quieres empezar desde cero.
-### Crear una Nueva Plantilla {#creating-a-new-template}
+### Crear una nueva plantilla {#creating-a-new-template}
Para crear una nueva plantilla de correo electrónico, sigue los pasos a continuación.
-
- Dentro de la página de Correos Electrónicos, encontrarás la pestaña
+
+ En la página de correos electrónicos, encontrarás la pestaña
[Configurar](https://app.trophy.so/emails/configure), donde cada sección de tipo de correo contiene sus plantillas.
- Haz clic en el botón *Añadir Plantilla* dentro de la sección del tipo de correo electrónico para el que deseas crear una plantilla.
+ Haz clic en el botón *Añadir plantilla* dentro de la sección del tipo de correo para el que deseas crear una plantilla.
- Usa el editor basado en bloques para diseñar tu plantilla de correo electrónico.
+ Utiliza el editor basado en bloques para diseñar tu plantilla de correo electrónico.
-### Tipos de Bloques {#block-types}
+### Tipos de bloques {#block-types}
-El constructor de correos electrónicos de Trophy admite varios tipos de bloques diferentes que cumplen distintos propósitos. Todos los componentes básicos que esperarías encontrar en un editor de correo electrónico, como párrafos, encabezados e imágenes, se denominan [Bloques Básicos](#basic-blocks). También existe un conjunto de componentes más potentes, como gráficos y rachas, que aprovechan los datos de actividad del usuario y las funciones de gamificación de Trophy. Estos se denominan [Bloques Inteligentes](#smart-blocks).
+El editor de correos electrónicos de Trophy admite varios tipos de bloques diferentes que sirven para distintos propósitos. Todos los componentes básicos que esperarías encontrar en un editor de correos como párrafos, encabezados e imágenes se denominan [Bloques básicos](#basic-blocks). También existe un conjunto de componentes más potentes como gráficos y rachas que aprovechan los datos de actividad de usuario y las funciones de gamificación de Trophy. Estos se denominan [Bloques inteligentes](#smart-blocks).
-#### Bloques Básicos {#basic-blocks}
+#### Bloques básicos {#basic-blocks}
Aquí está la lista completa de bloques básicos sin opinión que Trophy admite:
-- **Párrafo** - Ideal para fragmentos de texto cortos o largos.
-- **H1, H2, H3** - Útil para encabezados de diferentes tamaños.
-- **Botón** - Crea una llamada a la acción para que los usuarios interactúen en los correos electrónicos.
-- **Tarjeta** - Puede anidar otros bloques, enfocando la atención.
-- **Divisor** - Ideal para separar contenido en secciones lógicas.
+- **Párrafo** - Útil para fragmentos de texto cortos o largos.
+- **H1, H2, H3** - Útiles para encabezados de distintos tamaños.
+- **Botón** - Crea una llamada a la acción para que los usuarios la realicen en los correos electrónicos.
+- **Tarjeta** - Puede anidar otros bloques, centrando la atención.
+- **Divisor** - Útil para separar el contenido en secciones lógicas.
- **Emoji** - Incluye cualquier emoji compatible, controlando el tamaño.
- **Imagen** - Sube cualquier imagen y Trophy la renderizará en los correos electrónicos.
-- **Espaciador** - Ideal para dar espacio a los bloques y que destaquen.
-- **Columnas** - Útil para crear diseños de hasta 3 columnas con cualquier contenido.
+- **Espaciador** - Útil para dar espacio a los bloques y que destaquen.
+- **Columnas** - Útiles para crear diseños de hasta 3 columnas con cualquier contenido.
- **Logo** - Renderizará el logo de tu organización, configurado en la página de [Marca](https://app.trophy.so/branding).
-#### Bloques Condicionales {#conditional-blocks}
+#### Bloques condicionales {#conditional-blocks}
-Trophy también cuenta con un potente sistema de renderizado condicional impulsado por el tipo de bloque _Condicional_.
+Trophy también cuenta con un potente sistema de renderizado condicional basado en el tipo de bloque _Conditional_.
-Al anidar cualquier otro bloque dentro de un bloque condicional y configurar la lógica de condiciones, puedes crear prácticamente cualquier diseño de correo electrónico que mostrará diferentes bloques según la evaluación de las condiciones en el momento del envío.
+Al anidar cualquier otro bloque dentro de un bloque condicional y configurar la lógica de condiciones, puedes crear prácticamente cualquier diseño de email que muestre diferentes bloques en los correos según la evaluación de condiciones en el momento del envío.
Si estás familiarizado con los operadores lógicos `if/else`, esto te resultará muy familiar. De lo contrario, aquí tienes un diagrama rápido para explicar cómo funciona.
@@ -430,7 +433,7 @@ flowchart LR
D-- No --->F
```
-Un caso de uso común para el bloque condicional es mostrar condicionalmente a un usuario su racha (uno de los [Bloques Inteligentes](#smart-blocks) integrados de Trophy) y texto motivacional relacionado con la racha solo si tiene una racha activa. Si el destinatario no tiene una racha en el momento en que se envía el correo electrónico, se muestra un mensaje simple en su lugar.
+Un caso de uso común para el bloque condicional es mostrar condicionalmente a un usuario su racha (uno de los [Smart Blocks](#smart-blocks) integrados de Trophy) y algún texto motivacional relacionado con la racha solo si tiene una racha activa. Si el destinatario no está en una racha en el momento en que se envía el email, se muestra un mensaje simple en su lugar.
-Esto crea un marco poderoso para diseñar correos electrónicos basados en datos de usuario altamente relevantes y personalizados, y puede utilizarse para crear una amplia gama de correos para casos de uso comunes de gamificación.
+Esto crea un marco potente para diseñar emails basados en datos de usuario altamente relevantes y personalizados, y se puede usar para crear una amplia gama de emails para casos de uso comunes de gamificación.
-#### Bloques Inteligentes {#smart-blocks}
+#### Smart Blocks {#smart-blocks}
-Los bloques inteligentes son componentes potentes diseñados para soportar casos de uso comunes de gamificación e integrarse con todas las funcionalidades de Trophy, incluyendo métricas, logros y rachas.
+Los smart blocks son componentes potentes diseñados para admitir casos de uso comunes de gamificación e integrarse con todas las funcionalidades de Trophy, incluyendo métricas, logros y rachas.
-Puedes encontrar todos los bloques inteligentes en la sección _Bloques Recomendados_, y siempre son reconocibles por el icono .
+Puedes encontrar todos los smart blocks en la sección _Recommended Blocks_, y siempre son reconocibles por el icono .
-Mira a Charlie explicar los bloques inteligentes y cómo funcionan:
+Mira a Charlie explicar los smart blocks y cómo funcionan:
-Lee más sobre el caso de uso de cada bloque inteligente:
+Lea más sobre el caso de uso de cada bloque inteligente:
-
- El bloque de gráfico de progreso de logros muestra un gráfico con barras para hasta cinco logros de una métrica particular, destacando aquellos que el destinatario ha desbloqueado.
+
+ El bloque de gráfico de progreso de logros muestra un gráfico con barras para hasta cinco logros de una métrica en particular, destacando los que el destinatario ha desbloqueado.
- Elige la métrica para mostrar logros usando el selector de métrica.
+ Elija la métrica para mostrar logros usando el selector de métrica.
-### Variables de Email {#email-variables}
+### Variables de correo electrónico {#email-variables}
-Trophy proporciona un amplio conjunto de variables de email que pueden utilizarse para insertar texto altamente relevante y personalizado en el cuerpo de los correos electrónicos y las líneas de asunto.
+Trophy proporciona un amplio conjunto de variables de correo electrónico que se pueden usar para insertar texto altamente relevante y personalizado en el cuerpo de los correos electrónicos y líneas de asunto.
-Las variables aportan contexto desde tu cuenta de Trophy, los datos de progreso del destinatario y la configuración específica del email a tus plantillas de correo electrónico.
+Las variables aportan contexto de tu cuenta de Trophy, los datos de progreso del destinatario y la configuración específica del correo a tus plantillas de email.
-Las variables de email pueden insertarse escribiendo `@` en cualquier bloque que admita texto enriquecido, como encabezados, párrafos y botones, y buscando la variable deseada.
+Las variables de email se pueden insertar escribiendo `@` en cualquier bloque que admita texto enriquecido, como encabezados, párrafos y botones, y buscando la variable deseada.
-Esto abrirá la ventana del editor de variables donde podrás configurar las variables como se muestra en la demostración a continuación.
+Esto abrirá la ventana del editor de variables donde puedes configurar las variables como en la demostración a continuación.
-También puedes usar variables en las líneas de asunto del email.
+También puedes usar variables en las líneas de asunto de los correos.
-Consulta a continuación la lista completa de todas las variables de email compatibles con el generador de correos electrónicos, organizadas por categoría.
+A continuación, consulta la lista completa de todas las variables de email compatibles con el creador de correos, desglosadas por categoría.
-Variables relacionadas con el destinatario del email.
+Variables relacionadas con el destinatario del correo.
- **Nombre**: El nombre del destinatario, si está configurado
-Además, todos los [atributos personalizados de usuario](/es/features/users#custom-user-attributes) están disponibles como variables de email.
+Adicionalmente, todos los [atributos de usuario personalizados](/es/features/users#custom-user-attributes) están disponibles como variables de email.
- Variables relacionadas con los datos de eventos rastreados de los destinatarios contra métricas.
+ Variables relacionadas con los datos de eventos rastreados del destinatario en las métricas.
-Cada métrica de Trophy admite las siguientes variables de correo electrónico:
+Cada métrica de Trophy admite las siguientes variables de email:
-- **Nombre de la Métrica**: El nombre de la métrica
-- **Unidades de la Métrica**: Las unidades de la métrica
-- **Total Actual**: La suma de todos los valores de eventos del destinatario hasta la fecha
-- **Cambio en Este Periodo**: Cambio absoluto en el total actual del destinatario en el periodo de agregación actual
-- **Cambio en Este Periodo (%)**: Cambio porcentual en el total actual del destinatario en el periodo de agregación actual
-- **Percentil (Todo el Tiempo)**: El total actual del destinatario comparado con todos los demás usuarios de todo el tiempo
-- **Percentil (Este Periodo)**: El total actual del destinatario comparado con todos los demás usuarios en el periodo de agregación actual
+- **Nombre de la métrica**: El nombre de la métrica
+- **Unidades de la métrica**: Las unidades de la métrica
+- **Total actual**: La suma de todos los valores de eventos del destinatario hasta la fecha
+- **Cambio en este periodo**: Cambio absoluto en el total actual del destinatario en el periodo de agregación actual
+- **Cambio en este periodo (%)**: Cambio porcentual en el total actual del destinatario en el periodo de agregación actual
+- **Percentil (Histórico)**: El total actual del destinatario comparado con todos los demás usuarios de todos los tiempos
+- **Percentil (Este periodo)**: El total actual del destinatario comparado con todos los demás usuarios en el periodo de agregación actual
-Además, los alias dinámicos **Highest** y **Lowest** admiten el mismo conjunto de variables. Al usar estos alias, Trophy seleccionará la métrica donde el destinatario tenga el total actual más alto o más bajo en el momento del envío.
+Adicionalmente, los alias dinámicos **Más alto** y **Más bajo** admiten el mismo conjunto de variables. Al usar estos alias, Trophy seleccionará la métrica donde el destinatario tenga el total actual más alto o más bajo en el momento del envío.
-Al usar variables de métricas, también tiene la opción de filtrar los datos que cualquiera de las variables anteriores referencian mediante un [atributo de evento personalizado](/es/features/events#custom-event-attributes).
+Al usar variables de métricas, también tienes la opción de filtrar los datos a los que hacen referencia cualquiera de las variables anteriores mediante un [atributo de evento personalizado](/es/features/events#custom-event-attributes).
@@ -596,26 +599,26 @@ Al usar variables de métricas, también tiene la opción de filtrar los datos q
De manera similar a las métricas, cada sistema de puntos tiene las siguientes variables que se pueden usar para agregar datos dinámicos al contenido del correo electrónico:
-- **Total Actual**: Los puntos totales del destinatario
-- **Cambio en Este Periodo**: Cambio absoluto en los puntos totales del destinatario en el periodo de agregación actual
-- **Cambio en Este Periodo (%)**: Cambio porcentual en los puntos totales del destinatario en el periodo de agregación actual
-- **Percentil (Todo el Tiempo)**: Los puntos totales del destinatario comparados con todos los demás usuarios de todo el tiempo
-- **Percentil (Este Periodo)**: Los puntos totales del destinatario comparados con todos los demás usuarios en el periodo de agregación actual
+- **Total Actual**: El total de puntos del destinatario
+- **Cambio Este Período**: Cambio absoluto en el total de puntos del destinatario en el período de agregación actual
+- **Cambio Este Período (%)**: Cambio porcentual en el total de puntos del destinatario en el período de agregación actual
+- **Percentil (Todo el Tiempo)**: El total de puntos del destinatario comparado con todos los demás usuarios de todos los tiempos
+- **Percentil (Este Período)**: El total de puntos del destinatario comparado con todos los demás usuarios en el período de agregación actual
.
- Estas variables solo son relevantes para [correos de logros](#achievement-emails).
+ Estas variables solo son relevantes para [correos electrónicos de logros](#achievement-emails).
-Al configurar una plantilla para usar con correos de logros, están disponibles las siguientes variables:
+Al configurar una plantilla para usar con correos electrónicos de logros, las siguientes variables están disponibles:
-- **Es el Logro Final**: Si el logro que desencadena el correo es parte de una serie de logros de métricas, esto es verdadero cuando el logro es el último de la serie
-- **Porcentaje Hasta el Próximo Logro**: Si el logro que desencadena el correo es parte de una serie de logros de métricas, este es el porcentaje hasta que el usuario desbloquee el siguiente logro de la serie
-- **Nombre del Logro**: El nombre del logro que desencadenó el correo
-- **Descripción del Logro**: La descripción del logro que desencadenó el correo
+- **Es Logro Final**: Si el logro que activa el correo electrónico es parte de una serie de logros de métricas, esto es verdadero cuando el logro es el logro final de la serie
+- **Porcentaje Hasta el Siguiente Logro**: Si el logro que activa el correo electrónico es parte de una serie de logros de métricas, este es el porcentaje hasta que el usuario desbloquee el siguiente logro de la serie
+- **Nombre del Logro**: El nombre del logro que activó el correo electrónico
+- **Descripción del Logro**: La descripción del logro que activó el correo electrónico
.
@@ -623,10 +626,10 @@ Al configurar una plantilla para usar con correos de logros, están disponibles
Variables relacionadas con la racha del destinatario.
-- **Tiene Racha Activa**: Verdadero si el destinatario tiene una racha activa al momento de enviar el correo, falso en caso contrario
+- **Tiene Racha Activa**: Verdadero si el destinatario tiene una racha activa al momento de enviar el correo electrónico, falso en caso contrario
- **Longitud de la Racha**: La longitud de la racha actual del destinatario
-- **Racha Extendida**: Verdadero si la racha del destinatario se extendió, falso en caso contrario
-- **Días Desde la Última Extensión**: El número de días desde que el usuario extendió su racha por última vez
+- **Racha Extendida**: Verdadero si la racha del destinatario fue extendida, falso en caso contrario
+- **Días Desde la Última Extensión**: El número de días desde que el usuario extendió por última vez su racha
.
@@ -643,7 +646,7 @@ Al configurar una plantilla para usar con correos de logros, están disponibles
- Estas variables solo son relevantes para [correos de resumen](#recap-emails).
+ Estas variables solo son relevantes para [correos resumen](#recap-emails).
- **Rango de Fechas del Período Actual**: Las fechas de inicio y fin del período de agregación actual
@@ -657,9 +660,9 @@ Al configurar una plantilla para usar con correos de logros, están disponibles
Hay un par de opciones adicionales a considerar al usar variables de correo.
-**Prefijo y sufijo**
+**Prefijo y Sufijo**
-Puedes proporcionar un prefijo y un sufijo para variables de texto como el nombre del destinatario o el nombre de una métrica en particular.
+Puede proporcionar un prefijo y sufijo para variables de texto como el nombre del destinatario o el nombre de una métrica en particular.
-Si el valor de la variable no se renderiza cuando se envía el correo electrónico, Trophy no mostrará la variable ni el prefijo ni el sufijo para mantener los correos limpios.
+Si el valor de la variable no se renderiza cuando se envía el correo, Trophy no mostrará la variable ni el prefijo o sufijo para mantener los correos limpios.
-**Singular y plural**
+**Singular y Plural**
-Al usar variables numéricas como el total de puntos actual del destinatario o el total de métricas, también puedes proporcionar un sufijo singular y plural para acompañarlo.
+Al usar variables numéricas como el total actual de puntos del destinatario o el total de métricas, también puede proporcionar un sufijo singular y plural que lo acompañe.
-### Variaciones de texto {#text-variations}
+### Variaciones de Texto {#text-variations}
-Las variaciones se pueden usar para agregar aleatoriedad al texto dentro de los correos electrónicos enviados por Trophy. Esto evita que los correos se vuelvan aburridos y ayuda a mejorar las tasas de apertura y clics.
+Las variaciones se pueden usar para agregar aleatoriedad al texto dentro de los correos enviados por Trophy. Esto evita que los correos se vuelvan aburridos y ayuda a mejorar las tasas de apertura y clics.
-Cualquier bloque que admita entrada de texto, incluyendo H1, H2, H3 y párrafo, admite variaciones.
+Cualquier bloque que admita entrada de texto, incluidos H1, H2, H3 y párrafo, admite variaciones.
-También puedes usar variaciones para agregar aleatoriedad a las líneas de asunto del correo electrónico.
+También puede usar variaciones para agregar aleatoriedad a los asuntos de correo.
-Para crear una variación, haz clic en el botón _Agregar variación_ en cualquier bloque que las admita.
+Para crear una variación, haga clic en el botón _Agregar Variación_ en cualquier bloque que las admita.
- Las variaciones aún no admiten pruebas A/B, pero esto está en nuestra hoja de ruta, así que mantente atento...
+ Las variaciones aún no admiten pruebas A/B, pero esto está en nuestra hoja de ruta, así que permanece atento...
### Uso del editor {#using-the-editor}
-El editor de plantillas de correo electrónico es un lienzo en blanco para diseñar correos electrónicos que se vean genial en la bandeja de entrada. El uso de [Bloques](#block-types) preconfigurados hace que sea realmente fácil crear plantillas de correo electrónico que se adapten a casos de uso comunes de gamificación. Aquí te explicaremos cómo usar mejor el editor para crear correos electrónicos con un aspecto increíble.
+El editor de plantillas de correo electrónico es un lienzo en blanco para diseñar correos que se vean geniales en la bandeja de entrada. Usar [bloques](#block-types) preconfigurados facilita enormemente la creación de plantillas de correo electrónico que se adapten a casos de uso comunes de gamificación. Aquí te explicaremos cómo utilizar mejor el editor para crear correos electrónicos con un aspecto increíble.
-#### Agregar bloques {#adding-blocks}
+#### Añadir bloques {#adding-blocks}
-Para agregar un nuevo bloque a una plantilla de correo electrónico, presiona la tecla . Esto abrirá el cuadro de diálogo de selección de bloques donde puedes elegir el bloque que deseas agregar.
+Para añadir un nuevo bloque a una plantilla de correo electrónico, presiona la tecla . Esto abrirá el diálogo de selección de bloques donde puedes elegir el bloque que deseas añadir.
-O si deseas agregar un bloque inmediatamente después de otro bloque, usa el menú de bloques.
+O si quieres añadir un bloque inmediatamente después de otro bloque, utiliza el menú de bloques.
- El mensaje se leerá de la siguiente manera: Está recibiendo este correo electrónico porque está suscrito a informes de progreso y correos de logros. Si ya no desea recibir estos correos electrónicos, puede cancelar la suscripción.
+ El mensaje se leerá de la siguiente manera: Estás recibiendo este correo electrónico porque
+ estás suscrito a informes de progreso y correos de logros. Si ya no
+ deseas recibir estos correos, puedes cancelar tu suscripción.
-Cualquier destinatario que haga clic en este enlace será dirigido a una página con marca que le permite controlar qué notificaciones por correo electrónico recibe.
+Cualquier destinatario que haga clic en este enlace será redirigido a una página con tu marca que le permite controlar qué notificaciones por correo electrónico recibe.
- Como alternativa al enlace de cancelación de suscripción, también puedes construir un centro
- de preferencias en tu aplicación usando la [API de preferencias de usuario
- ](/es/features/users#notification-preferences) de Trophy. Esto ofrece a los usuarios un control más granular
- sobre qué tipos de correos electrónicos reciben.
+ Como alternativa al enlace de cancelación de suscripción, también puedes crear un centro de
+ preferencias en tu aplicación usando la [API de preferencias de
+ usuario](/es/features/users#notification-preferences) de Trophy. Esto brinda a los usuarios un control más
+ granular sobre qué tipos de correos electrónicos reciben.
-## Analíticas de Email {#email-analytics}
+## Analíticas de correo electrónico {#email-analytics}
Trophy tiene analíticas integradas para todos los correos electrónicos que envía. Esto incluye:
- Destinatarios (El número total de personas que recibieron el correo electrónico)
- Tasa de apertura (El porcentaje de destinatarios que abrieron el correo electrónico)
-- Tasa de clics (El porcentaje de destinatarios que hicieron clic en al menos un enlace en el correo electrónico)
+- Tasa de clics (El porcentaje de destinatarios que hicieron clic en al menos un enlace del correo electrónico)
- Tasa de retención (El porcentaje de usuarios que abrieron el correo electrónico y regresaron a usar tu plataforma después de al menos 2 días)
@@ -836,22 +841,22 @@ Trophy tiene analíticas integradas para todos los correos electrónicos que env
>
-## Preguntas Frecuentes {#frequently-asked-questions}
+## Preguntas frecuentes {#frequently-asked-questions}
- ¡Sí! El envío de correos electrónicos desde tu propio dominio está soportado de forma nativa. Sigue los pasos en la sección sobre [envío de correos electrónicos](#sending-emails) para comenzar.
+ ¡Sí! El envío de correos electrónicos desde tu propio dominio es compatible de forma inmediata. Sigue los pasos en la sección sobre [envío de correos electrónicos](#sending-emails) para comenzar.
{" "}
- No, no limitamos la cantidad de correos electrónicos que puedes enviar. Sin embargo, monitoreamos
- el uso para prevenir abusos.
+ No, no limitamos la cantidad de correos electrónicos que puedes enviar. Sin embargo, monitoreamos el uso
+ para prevenir abusos.
## Obtener Soporte {#get-support}
-¿Quieres ponerte en contacto con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
+¿Quieres ponerte en contacto con el equipo de Trophy? Contáctanos por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
diff --git a/es/features/streaks.mdx b/es/features/streaks.mdx
index d58b40fa..7636881b 100644
--- a/es/features/streaks.mdx
+++ b/es/features/streaks.mdx
@@ -2,7 +2,7 @@
title: Rachas
description: Aprende a usar rachas en una experiencia de producto gamificada con Trophy.
og:description: Usa rachas diarias, semanales o mensuales para crear patrones de
- uso habituales y mantener a los usuarios regresando a tu aplicación.
+ uso habitual y mantener a los usuarios regresando a tu aplicación.
icon: flame
---
@@ -10,23 +10,23 @@ import MetricChangeResponseBlock from "../../snippets/metric-change-response-blo
## ¿Qué son las Rachas? {#what-are-streaks}
-Una racha es un período de días, semanas o meses consecutivos en los que un usuario ha realizado una acción clave en tu plataforma. Se ha demostrado que las rachas aumentan significativamente la retención, particularmente cuando la acción del usuario que se rastrea se alinea con el valor central de tu producto.
+Una racha es un período de días, semanas o meses consecutivos en el que un usuario ha realizado una acción clave en tu plataforma. Se ha demostrado que las rachas aumentan significativamente la retención, especialmente cuando la acción del usuario que se rastrea se alinea con el valor central de tu producto.
-## Frecuencia de Rachas {#streak-frequency}
+## Frecuencia de Racha {#streak-frequency}
-Las rachas en Trophy pueden ser **diarias, semanales o mensuales**. Esto significa que un usuario debe cumplir sus [condiciones de racha](#streak-conditions) al menos una vez cada día calendario, semana o mes para mantener su racha.
+Las rachas en Trophy pueden ser **diarias, semanales o mensuales**. Esto significa que un usuario debe cumplir sus [condiciones de racha](#streak-conditions) al menos una vez cada día, semana o mes calendario para mantener su racha.
Si has [configurado zonas horarias](/es/features/users#param-tz) para tus usuarios, Trophy rastreará automáticamente la racha de cada usuario en su zona horaria local (incluyendo cuando los usuarios cambian de zona horaria) y mantendrá las rachas intactas.
-Trophy calcula automáticamente los datos de rachas para cada frecuencia de racha, lo que significa que puedes cambiar en cualquier momento.
+Trophy calcula automáticamente los datos de racha para cada frecuencia de racha, lo que significa que puedes cambiar en cualquier momento.
## Condiciones de Racha {#streak-conditions}
En Trophy puedes establecer los umbrales que un usuario debe cumplir para extender su racha basándote en tus [Métricas](/es/features/metrics) configuradas.
-Puedes elegir qué métricas deben formar parte de tu racha, y para aquellas que elijas, puedes establecer un umbral personalizado que los usuarios deben cumplir.
+Puedes elegir qué métricas deben ser parte de tu racha y, para las que elijas, puedes establecer un umbral personalizado que los usuarios deben cumplir.
Al combinar métricas, puedes elegir entre dos modos de evaluación:
-- `ALL` significa que un usuario debe cumplir todos los umbrales de métricas para extender su racha
-- `OR` significa que un usuario solo tiene que cumplir uno de tus umbrales de métricas para extender su racha
+- `ALL` significa que un usuario debe cumplir cada umbral de métrica para extender su racha
+- `OR` significa que un usuario solo tiene que cumplir uno de tus umbrales de métrica para extender su racha
De esta manera puedes diseñar tu lógica de racha para que coincida con el caso de uso de tu aplicación.
-### Días libres {#days-off}
+### Días Libres {#days-off}
Para rachas diarias, puedes marcar días específicos de la semana como días libres en la [página de rachas](https://app.trophy.so/streaks) del panel de Trophy. Esos días no cuentan para la racha: los usuarios aún pueden extender su racha si están activos, pero perder un día libre no la romperá.
@@ -60,23 +60,23 @@ Debes dejar al menos un día que cuente para la racha. Las rachas semanales y me
A diferencia de las [congelaciones de racha](#streak-freezes), los días libres no se consumen. Se aplican cada semana hasta que los cambies.
-Si has habilitado la [personalización de racha](#streak-personalization), los usuarios pueden anular los días libres predeterminados a través de las [preferencias de usuario](/es/features/users#streak-preferences).
+Si has habilitado la [personalización de racha](#streak-personalization), los usuarios pueden anular los días libres predeterminados mediante las [preferencias de usuario](/es/features/users#streak-preferences).
-## Congelaciones de racha {#streak-freezes}
+## Congelaciones de Racha {#streak-freezes}
-Las congelaciones de racha ayudan a los usuarios a mantener sus rachas por más tiempo al permitirles perder un número determinado de períodos sin que se reinicie a cero. Esto ayuda a mantener las rachas motivadoras incluso si los usuarios no mantienen un hábito de uso perfecto.
+Las congelaciones de racha ayudan a los usuarios a mantener sus rachas por más tiempo al permitirles perder un número determinado de períodos sin que se restablezca a cero. Esto ayuda a mantener las rachas motivadoras incluso si los usuarios no mantienen un hábito de uso perfecto.
-Las congelaciones de racha son opcionales y pueden configurarse en la [página de rachas](https://app.trophy.so/streaks) del panel de Trophy.
+Las congelaciones de racha son opcionales y se pueden configurar en la [página de rachas](https://app.trophy.so/streaks) del panel de Trophy.
-Cuando se habilitan, tú decides cuántas congelaciones puede tener un usuario y cuántas se le otorgan con el tiempo. Cuando un usuario pierde un período, se consume una congelación. Las congelaciones se consumen hasta que los usuarios no tengan más congelaciones disponibles, momento en el cual la racha del usuario se reinicia a cero.
+Cuando están habilitadas, decides cuántas congelaciones puede tener un usuario y cuántas se le otorgan con el tiempo. Cuando un usuario pierde un período, se consume una congelación. Las congelaciones se consumen hasta que los usuarios no tienen congelaciones restantes, momento en el cual la racha del usuario se restablece a cero.
-Las congelaciones de racha son diferentes de las [pausas de racha](#streak-pauses) en que las congelaciones permiten a los usuarios perder un número determinado de períodos sin romper su racha, independientemente del motivo, mientras que las pausas de racha protegen específicamente una racha durante un rango de fechas conocido y predefinido, como unas vacaciones programadas o un descanso. Las congelaciones se consumen automáticamente cuando el usuario pierde una actividad requerida, mientras que las pausas se crean manualmente con anticipación para cubrir ausencias planificadas.
+Las congelaciones de racha son diferentes de las [pausas de racha](#streak-pauses) en que las congelaciones permiten a los usuarios perder un número determinado de períodos sin romper su racha, independientemente del motivo, mientras que las pausas de racha protegen específicamente una racha durante un rango de fechas conocido y predefinido, como unas vacaciones o descanso programado. Las congelaciones se consumen automáticamente cuando el usuario pierde una actividad requerida, mientras que las pausas se crean manualmente con anticipación para cubrir ausencias planificadas.
-### Concesión de congelaciones {#granting-freezes}
+### Concesión de congelamientos {#granting-freezes}
-Puedes configurar cualquier cantidad de congelaciones arbitrarias para conceder a nuevos usuarios cuando los identificas por primera vez con Trophy. Para configurar esto, habilita la concesión de congelaciones y establece el recuento inicial de congelaciones en la página de rachas del panel de Trophy.
+Puede configurar cualquier número de congelamientos arbitrarios para otorgar a los nuevos usuarios cuando los identifique por primera vez con Trophy. Para configurar esto, habilite las concesiones de congelamiento y establezca el recuento inicial de congelamientos en la página de rachas del panel de Trophy.
-Trophy también puede conceder automáticamente congelaciones de racha a los usuarios con el tiempo. Puedes elegir una cantidad arbitraria de días durante los cuales conceder una cantidad arbitraria de congelaciones a cada usuario.
+Trophy también puede otorgar automáticamente congelamientos de racha a los usuarios con el tiempo. Puede elegir un número arbitrario de días durante los cuales otorgar un número arbitrario de congelamientos a cada usuario.
-Para configurar esto, establece el número de días durante los cuales conceder congelaciones y el número de congelaciones a conceder en la página de rachas del panel de Trophy. Aquí también puedes establecer el número máximo de congelaciones que cada usuario puede tener, hasta un límite de 100.
+Para configurar esto, establezca el número de días durante los cuales otorgar congelamientos y el número de congelamientos a otorgar en la página de rachas del panel de Trophy. Aquí también puede establecer el número máximo de congelamientos que cada usuario puede tener, hasta un límite de 100.
-Si has configurado zonas horarias para tus usuarios, Trophy consumirá automáticamente congelaciones a medianoche en la zona horaria del usuario cuando sea necesario para extender su racha, y si hay nuevas congelaciones que deban concederse a un usuario, se concederán hasta diez minutos después.
+Si ha configurado zonas horarias para sus usuarios, Trophy consumirá automáticamente los congelamientos a medianoche en la zona horaria del usuario cuando sea necesario para extender su racha, y si se deben otorgar nuevos congelamientos a un usuario, se otorgarán hasta diez minutos después.
## Pausas de racha {#streak-pauses}
-Las pausas de racha protegen la racha de un usuario durante un rango de fechas conocido, como unas vacaciones u otro descanso planificado. Mientras una pausa cubre un período, Trophy mantiene la duración de la racha del usuario en lugar de finalizar la racha si no cumplen sus [condiciones de racha](#streak-conditions).
+Las pausas de racha protegen la racha de un usuario durante un rango de fechas conocido, como unas vacaciones u otro descanso planificado. Mientras una pausa cubre un período, Trophy mantiene la duración de la racha del usuario en lugar de finalizar la racha si no cumple con sus [condiciones de racha](#streak-conditions).
-Las pausas de racha son diferentes de las [congelaciones de racha](#streak-freezes) en que las pausas protegen específicamente la racha de un usuario durante un rango de fechas conocido y predefinido, como unas vacaciones o descanso programado, mientras que las congelaciones permiten a los usuarios perderse un número establecido de días (o períodos) sin romper su racha, independientemente del motivo. Las pausas se crean manualmente con antelación para cubrir ausencias planificadas, mientras que las congelaciones se consumen automáticamente cuando el usuario pierde una actividad requerida.
+Las pausas de racha son diferentes de los [congelamientos de racha](#streak-freezes) en que las pausas protegen específicamente la racha de un usuario durante un rango de fechas conocido y predefinido, como unas vacaciones programadas o un descanso, mientras que los congelamientos permiten a los usuarios perder un número establecido de días (o períodos) sin romper su racha, independientemente del motivo. Las pausas se crean manualmente con anticipación para cubrir ausencias planificadas, mientras que los congelamientos se consumen automáticamente cuando el usuario pierde una actividad requerida.
### Crear pausas {#creating-pauses}
@@ -119,37 +119,39 @@ Crea pausas con la [API de administración para crear pausas de rachas](/es/admi
Cada pausa requiere:
-- `userId`: el usuario para el cual crear la pausa
+- `userId`: el usuario para el que crear una pausa
- `start`: la primera fecha que cubre la pausa
- `end`: la última fecha que cubre la pausa
-Las fechas de inicio en el pasado se rechazan. Si has [configurado zonas horarias](/es/features/users#param-tz) para tus usuarios, Trophy evalúa `start` contra hoy en la zona horaria local de cada usuario.
+Las fechas de inicio en el pasado son rechazadas. Si has [configurado zonas horarias](/es/features/users#param-tz) para tus usuarios, Trophy evalúa `start` contra el día de hoy en la zona horaria local de cada usuario.
### Eliminar pausas {#deleting-pauses}
-Para evitar que se aplique una pausa, elimínala con la [API de administración para eliminar pausas de rachas](/es/admin-api/endpoints/streaks/delete-pauses).
+Para evitar que una pausa se aplique, elimínala con la [API de administración para eliminar pausas de rachas](/es/admin-api/endpoints/streaks/delete-pauses).
### Leer pausas {#reading-pauses}
La [API de rachas de usuario](/es/api-reference/endpoints/users/get-a-users-streak) devuelve las pausas próximas y actualmente activas en el campo `pauses`. Las pausas pasadas y eliminadas se omiten.
-Cada período en `streakHistory` incluye `usedPause`, que es `true` cuando la racha del usuario estuvo pausada durante ese período.
+Cada período en `streakHistory` incluye `usedPause`, que es `true` cuando la racha del usuario estuvo en pausa durante ese período.
-## Hacer seguimiento de rachas {#tracking-streaks}
+## Seguimiento de rachas {#tracking-streaks}
-Trophy calcula automáticamente las rachas para todos los usuarios según los [eventos de métricas](/es/features/events#tracking-metric-events) que reportas a Trophy.
+Trophy calcula automáticamente las rachas para todos los usuarios según los [eventos de métricas](/es/features/events#tracking-metric-events) que reportes a Trophy.
-No se requiere trabajo adicional para hacer seguimiento de rachas, y puedes empezar a usarlas de inmediato. Solo asegúrate de que las rachas estén habilitadas en el panel de Trophy.
+No se requiere trabajo adicional para hacer seguimiento de las rachas, y puedes comenzar a usarlas de inmediato. Solo asegúrate de que las rachas estén habilitadas en el panel de Trophy.
+
+También puedes leer y actualizar la configuración de rachas de la organización — frecuencia, modo de evaluación, métricas, días libres, personalización y congelamientos — con la [API de administración de configuración de rachas](/es/admin-api/endpoints/streaks/update-streak-settings).
-Para una guía completa sobre cómo configurar una funcionalidad de rachas usando Trophy, consulta nuestra [guía oficial](/es/guides/how-to-build-a-streaks-feature).
+Para un recorrido completo sobre cómo configurar una funcionalidad de rachas usando Trophy, consulta nuestra [guía oficial](/es/guides/how-to-build-a-streaks-feature).
## Personalización de rachas {#streak-personalization}
Trophy puede permitir que los usuarios personalicen cómo funciona su racha dentro de los límites que establezcas para ellos. Para hacer esto, activa la personalización de rachas en la [página de rachas](https://app.trophy.so/streaks) del panel de Trophy.
-Una vez habilitado, los usuarios podrán personalizar las [condiciones de racha](#streak-conditions) que deben cumplir para extender su racha, incluido el modo de evaluación de racha, el umbral para cada métrica y [días libres](#days-off), a través de preferencias de usuario.
+Una vez habilitado, los usuarios podrán personalizar las [condiciones de racha](#streak-conditions) que deben cumplir para extender su racha, incluyendo el modo de evaluación de racha, el umbral para cada métrica y [días libres](#days-off), a través de las preferencias de usuario.
Para obtener más información sobre cómo establecer las preferencias de usuario para un usuario específico, consulta la documentación dedicada sobre [preferencias de usuario](/es/features/users#streak-preferences).
@@ -178,7 +180,7 @@ Esta sección describe algunas de las operaciones que puedes realizar para gesti
Para restaurar la racha de un usuario, dirígete a la página de detalles del usuario y utiliza la acción 'Restaurar Racha'. Restaurar la racha de un usuario la establece a la longitud que tenía cuando la perdió por última vez.
-También puedes utilizar la [API de administración para restaurar rachas](/es/admin-api/endpoints/streaks/restore-streaks) para restaurar rachas de forma programática.
+También puedes usar la [API de administración para restaurar rachas](/es/admin-api/endpoints/streaks/restore-streaks) para restaurar rachas de forma programática.
@@ -192,13 +194,13 @@ También puedes utilizar la [API de administración para restaurar rachas](/es/a
>
-## Visualización de Rachas {#displaying-streaks}
+## Mostrar Rachas {#displaying-streaks}
-Trophy expone los datos de rachas de dos formas, que pueden utilizarse para crear elementos de interfaz dentro de tus aplicaciones y mostrar rachas a los usuarios.
+Trophy expone los datos de rachas de dos formas, que pueden utilizarse para construir elementos de interfaz dentro de tus aplicaciones y mostrar las rachas a los usuarios.
- Consulta nuestra [guía completa](/es/guides/how-to-build-a-streaks-feature) sobre cómo añadir una
- función de rachas a tu aplicación para obtener más detalles.
+ Consulta nuestra [guía completa](/es/guides/how-to-build-a-streaks-feature) sobre cómo agregar una
+ funcionalidad de rachas a tu aplicación para obtener más detalles.
### Respuesta de Evento de Métrica {#metric-event-response}
@@ -207,14 +209,14 @@ Cuando [incrementas una métrica](/es/features/events#tracking-metric-events) pa
-Esto puede utilizarse para activar de forma transaccional elementos de interfaz/experiencia de usuario que incluyen:
+Esto puede utilizarse para activar de forma transaccional elementos de UI/UX incluyendo:
-- Mostrar ventanas emergentes dentro de la aplicación
+- Mostrar ventanas emergentes en la aplicación
- Reproducir efectos de sonido
### API de Rachas de Usuario {#user-streaks-api}
-La [API de rachas de usuario](/es/api-reference/endpoints/users/get-a-users-streak) devuelve la racha actual de un solo usuario, junto con su historial reciente de rachas y cualquier [pausa de racha](#streak-pauses) próxima o activa. Utiliza el parámetro de consulta `historyPeriods` para controlar cuántos períodos devolver.
+La [API de rachas de usuario](/es/api-reference/endpoints/users/get-a-users-streak) devuelve la racha actual de un solo usuario, junto con su historial reciente de rachas y cualquier [pausa de racha](#streak-pauses) próxima o activa. Usa el parámetro de consulta `historyPeriods` para controlar cuántos períodos devolver.
{/* vale off */}
@@ -293,9 +295,9 @@ Utiliza estos datos para mostrar el historial de rachas de un usuario dentro de
/>
-### Listar Rachas de Múltiples Usuarios {#list-multiple-users-streaks}
+### Listar las Rachas de Múltiples Usuarios {#list-multiple-users-streaks}
-Si deseas mostrar rachas para múltiples usuarios a la vez, por ejemplo para admitir una función de racha de amigos o grupo de usuarios, utiliza la [API de listar rachas de usuarios](/es/api-reference/endpoints/streaks/get-streaks).
+Si deseas mostrar rachas para múltiples usuarios a la vez, por ejemplo para admitir una racha de amigos o una función de grupo de usuarios, entonces utiliza la [API de listar rachas de usuario](/es/api-reference/endpoints/streaks/get-streaks).
```json [expandable]
[
@@ -319,4 +321,4 @@ Si deseas mostrar rachas para múltiples usuarios a la vez, por ejemplo para adm
## Obtener Soporte {#get-support}
-¿Quieres ponerte en contacto con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
+¿Quieres ponerte en contacto con el equipo de Trophy? Contáctanos por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
diff --git a/es/features/users.mdx b/es/features/users.mdx
index 0304aaf6..501d226e 100644
--- a/es/features/users.mdx
+++ b/es/features/users.mdx
@@ -1,8 +1,8 @@
---
title: Usuarios
-description: Aprende a rastrear interacciones en tu base de usuarios usando Trophy.
-og:description: Los usuarios son las personas que usan tu plataforma. Aprende a
- informarle a Trophy sobre ellos.
+description: Aprende a rastrear las interacciones en tu base de usuarios utilizando Trophy.
+og:description: Los usuarios son las personas que utilizan tu plataforma.
+ Aprende cómo informar a Trophy sobre ellos.
icon: users
---
@@ -14,9 +14,9 @@ import UserStreakPreferencesResponseBlock from "../../snippets/user-streak-prefe
## ¿Qué son los Usuarios? {#what-are-users}
-Los usuarios son las personas individuales que usan tu producto. Le informas a Trophy sobre tus usuarios a través de APIs y usas el panel de control para diseñar experiencias de gamificación en torno a ellos.
+Los usuarios son las personas individuales que utilizan tu producto. Le informas a Trophy sobre tus usuarios a través de APIs y utilizas el panel de control para diseñar experiencias de gamificación en torno a ellos.
-Los usuarios deben ser individuos, no pueden ser empresas u organizaciones. Para crear estructuras organizacionales o agrupaciones de usuarios, considera usar un [atributo de usuario personalizado](#custom-user-attributes).
+Los usuarios deben ser individuos, no pueden ser empresas u organizaciones. Para crear estructuras organizacionales o agrupaciones de usuarios, considera utilizar un [atributo de usuario personalizado](#custom-user-attributes).
## Atributos Clave {#key-attributes}
@@ -31,28 +31,30 @@ Trophy solo requiere un atributo clave, `id`. Cada usuario sobre el que informes
- Para simplificar las cosas, Trophy te permite usar tu propio `id` que ya tienes
+ Para simplificar las cosas, Trophy te permite utilizar tu propio `id` que ya tienes
en tu base de datos en lugar de necesitar gestionar otro solo para Trophy.
### Atributos Opcionales {#optional-attributes}
-Además, puedes informarle a Trophy sobre cualquiera de los siguientes atributos clave opcionales y los pondrá a tu disposición como parte de tu experiencia de gamificación:
+Además, puedes informar a Trophy sobre cualquiera de los siguientes atributos clave opcionales y los pondrá a tu disposición como parte de tu experiencia de gamificación:
- El nombre completo del usuario. Es accesible en plantillas de correo electrónico y otras áreas
- donde quieras dirigirte al usuario por su nombre.
+ El nombre completo del usuario. Este está accesible en plantillas de correo electrónico y otras áreas
+ donde puedas querer dirigirte al usuario por su nombre.
La dirección de correo electrónico del usuario. Esta dirección se utilizará en cualquier
- [Email](/es/features/emails) que configures como parte de tu
- experiencia de gamificación con Trophy.
+ [correo electrónico](/es/features/emails) que configures como parte de tu experiencia
+ de gamificación con Trophy.
- La zona horaria del usuario. Debe especificarse como un [identificador de zona horaria IANA](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- Se utiliza para rachas, clasificaciones de leaderboard y para enviar correos electrónicos a los usuarios de acuerdo con su hora local.
+ La zona horaria del usuario. Debe especificarse como un [identificador de zona horaria
+ IANA](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+ Se utiliza para rachas, clasificaciones del ranking y envío de correos electrónicos a los usuarios de
+ acuerdo con su hora local.
En JavaScript, puedes obtener la zona horaria del usuario usando este fragmento:
@@ -64,25 +66,25 @@ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
- Si has configurado algún [Email](/es/features/emails) de Trophy, solo se
- enviará a un usuario cuando este campo sea true. Nota: Si no proporcionas un
- `email`, intentar establecer este campo en true resultará en un error.
+ Si has configurado algún [correo electrónico](/es/features/emails) de Trophy, solo se
+ enviarán a un usuario cuando este campo sea true. Nota: Si no proporcionas un
+ `email`, intentar establecer este campo como true generará un error.
- La fecha en que el usuario se registró en tu plataforma, como `YYYY-MM-DD`. Se aceptan y almacenan fechas ISO 8601
- como su día calendario UTC. No debe ser
- posterior a hoy en la zona horaria del usuario. Este campo es independiente de
- `created`, que es la fecha en que Trophy conoció al usuario por primera vez.
+ La fecha en que el usuario se registró en tu plataforma, como `YYYY-MM-DD`. Se aceptan
+ fechas-hora ISO 8601 y se almacenan como su día de calendario UTC. No debe ser
+ posterior al día de hoy en la zona horaria del usuario. Este campo es independiente de
+ `created`, que es la fecha en que Trophy tuvo conocimiento del usuario por primera vez.
- La lista de tokens de dispositivo para asociar con el usuario. Si has configurado alguna
+ La lista de tokens de dispositivo que se asociarán con el usuario. Si has configurado
[Notificaciones push](/es/features/push-notifications) de Trophy, solo se
enviarán a un usuario cuando se proporcione este campo.
-## Atributos de Usuario Personalizados {#custom-user-attributes}
+## Atributos de usuario personalizados {#custom-user-attributes}
Esta función está disponible en el plan [Pro](/es/account/billing#pro-plan)
@@ -96,17 +98,17 @@ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
/>
-Los atributos de usuario personalizados son gestionados por ti y pueden ser cualquier cosa que desees según tu caso de uso.
+Los atributos de usuario personalizados son gestionados por ti y pueden ser cualquier cosa que necesites según tu caso de uso.
-Por ejemplo, una aplicación de aprendizaje de idiomas podría usar un atributo de usuario personalizado para el idioma que está aprendiendo un usuario, o una plataforma de estudio podría usar uno para la materia favorita del usuario.
+Por ejemplo, una aplicación de aprendizaje de idiomas podría usar un atributo de usuario personalizado para el idioma que un usuario está aprendiendo, o una plataforma de estudio podría usar uno para la materia favorita del usuario.
Los atributos de usuario personalizados te permiten informar a Trophy sobre esta información contextual y usarla para personalizar las funciones de gamificación.
-### Crear Atributos {#creating-attributes}
+### Crear atributos {#creating-attributes}
-Para crear un nuevo atributo de usuario personalizado, dirígete a la [pestaña de atributos](https://app.trophy.so/users/attributes) de la página de usuarios en el panel de Trophy y haz clic en el botón _Agregar Atributo de Usuario_.
+Para crear un nuevo atributo de usuario personalizado, dirígete a la [pestaña de atributos](https://app.trophy.so/users/attributes) de la página de usuarios en el panel de Trophy y pulsa el botón _Agregar atributo de usuario_.
-Dale al atributo un nombre y una clave única. La clave es lo que usarás para hacer referencia al atributo en las llamadas a la API.
+Asigna al atributo un nombre y una clave única. La clave es lo que usarás para hacer referencia al atributo en las llamadas a la API.
-### Establecer Atributos {#setting-attributes}
+### Establecer atributos {#setting-attributes}
-Los atributos pueden asignarse valores para usuarios específicos usando su clave única, ya sea en línea, cuando los usuarios incrementan métricas a través de la [API de incremento de métricas](/es/api-reference/endpoints/events/submit-a-metric-event), o explícitamente a través de las APIs de [identificación de usuario](/es/api-reference/endpoints/users/identify-a-user), [crear usuario](/es/api-reference/endpoints/users/create-a-user) o [actualizar usuario](/es/api-reference/endpoints/users/update-a-user).
+Los atributos pueden recibir valores para usuarios específicos usando su clave única, ya sea en línea, mientras los usuarios incrementan métricas mediante la [API de incremento de métricas](/es/api-reference/endpoints/events/submit-a-metric-event), o explícitamente a través de las APIs de [identificación de usuario](/es/api-reference/endpoints/users/identify-a-user), [crear usuario](/es/api-reference/endpoints/users/create-a-user) o [actualizar usuario](/es/api-reference/endpoints/users/update-a-user).
- Trophy solo establecerá valores de atributos que se hayan creado primero
- en el panel de control. Hacemos esto para ayudarte a mantener un conjunto limpio de atributos y
+ Trophy solo establecerá valores de atributos que primero hayan sido creados
+ en el panel. Hacemos esto para ayudarte a mantener un conjunto limpio de atributos y
prevenir sobrescrituras accidentales.
-Si recibes un error similar al siguiente, es posible que hayas escrito mal la clave del atributo en la solicitud, o que necesites crear el atributo primero en el panel de control de Trophy:
+Si recibes un error similar al siguiente, es posible que hayas escrito mal la clave del atributo en la solicitud, o que necesites crear primero el atributo en el panel de Trophy:
{/* vale off */}
@@ -142,7 +144,7 @@ Si recibes un error similar al siguiente, es posible que hayas escrito mal la cl
-En todas las APIs, el esquema para establecer valores de atributos es consistente. A continuación, se muestra un ejemplo de un payload de solicitud que establece el valor de dos atributos de usuario personalizados `subject` y `plan`:
+En todas las APIs, el esquema para establecer valores de atributos es consistente. Aquí tienes un ejemplo de una carga útil de solicitud que establece el valor de dos atributos de usuario personalizados `subject` y `plan`:
```json {4-7}
{
@@ -155,13 +157,13 @@ En todas las APIs, el esquema para establecer valores de atributos es consistent
}
```
-### Uso de Atributos {#using-attributes}
+### Usar atributos {#using-attributes}
-Usa atributos de usuario personalizados en Trophy para personalizar funciones de gamificación, agregar y filtrar datos devueltos por las APIs, y segmentar y comparar cohortes de usuarios en análisis.
+Usa atributos de usuario personalizados en Trophy para personalizar funciones de gamificación, agregar y filtrar datos devueltos por las APIs, y para segmentar y comparar cohortes de usuarios en análisis.
#### Personalización de Funciones {#feature-personalization}
-Los atributos de usuario personalizados se pueden usar para personalizar logros, personalizar la forma en que diferentes usuarios ganan puntos y más. Sigue los enlaces a las páginas relevantes a continuación para obtener más información.
+Los atributos personalizados de usuario pueden utilizarse para personalizar logros, customizar la forma en que diferentes usuarios ganan puntos y más. Sigue los enlaces a las páginas relevantes a continuación para obtener más información.
- Personaliza el contenido y las líneas de asunto de correos electrónicos con atributos de usuario personalizados.
+ Personaliza el contenido y las líneas de asunto de los correos electrónicos con atributos personalizados de usuario.
#### Agregación y Filtrado de Datos {#data-aggregation-and-filtering}
-Puedes usar atributos de usuario personalizados para agregar y filtrar datos devueltos por algunas APIs para soportar una amplia gama de casos de uso de gamificación. En todos los casos, los atributos se incluyen en el parámetro de consulta `userAttributes` usando un esquema consistente:
+Puedes usar atributos personalizados de usuario para agregar y filtrar datos devueltos por algunas APIs para soportar una amplia gama de casos de uso de gamificación. En todos los casos, los atributos se incluyen en el parámetro de consulta `userAttributes` usando un esquema consistente:
`?userAttributes=city:london,subscription-plan:pro`
-Aquí está una lista de todas las API que admiten el parámetro de consulta `userAttributes`:
+Aquí está una lista de todas las APIs que soportan el parámetro de consulta `userAttributes`:
- [Resumen de Puntos](/es/api-reference/endpoints/points/get-points-summary)
-#### Analítica Segmentada {#segmented-analytics}
+#### Analíticas Segmentadas {#segmented-analytics}
-Los atributos de usuario personalizados se pueden utilizar para segmentar y comparar gráficos de retención y participación entre grupos de usuarios.
+Los atributos personalizados de usuario pueden utilizarse para segmentar y comparar gráficos de retención y engagement entre grupos de usuarios.
-Esto es útil para entender qué cohortes están aprovechando completamente tus funciones de gamificación, y cuáles tienen dificultades para participar y por lo tanto requieren atención.
+Esto es útil para comprender qué cohortes están haciendo pleno uso de tus funciones de gamificación, y cuáles tienen dificultades para interactuar y por lo tanto requieren atención.
Recomendamos comenzar con la identificación en línea si eres nuevo en
Trophy. Si decides que necesitas más control, prueba la identificación explícita.
-### Identificación en Línea {#inline-identification}
+### Identificación en línea {#inline-identification}
-La identificación en línea es la forma más sencilla de informar a Trophy sobre tus usuarios, ya que no requiere ningún código específico de identificación de usuario. Simplemente le informas a Trophy sobre los usuarios mientras usan normalmente tu plataforma.
+La identificación en línea es la forma más sencilla de informar a Trophy sobre tus usuarios, ya que no requiere ningún código específico de identificación de usuarios. Simplemente le dices a Trophy sobre los usuarios a medida que utilizan tu plataforma de forma normal.
-En la práctica, esto significa que cada vez que uses la [API de Eventos de Métricas](/es/api-reference/endpoints/events/submit-a-metric-event), transmites los detalles completos del usuario que activó el evento.
+En la práctica, esto significa que cada vez que usas la [API de eventos de métricas](/es/api-reference/endpoints/events/submit-a-metric-event), pasas los detalles completos del usuario que activó el evento.
-Aquí hay un ejemplo donde se realiza una llamada a la API de eventos de métricas, y los detalles del usuario que realizó la interacción se transmiten en el cuerpo de la solicitud:
+Aquí hay un ejemplo donde se realiza una llamada a la API de eventos de métricas, y los detalles del usuario que realizó la interacción se pasan en el cuerpo de la solicitud:
En este caso, si esta es la primera interacción del usuario (es decir, es un usuario nuevo), entonces se creará automáticamente un nuevo registro para él en Trophy.
-Sin embargo, si Trophy encuentra un registro existente con el mismo `id`, entonces Trophy actualizará cualquier detalle del usuario que se pase.
+Sin embargo, si Trophy encuentra un registro existente con el mismo `id`, entonces Trophy actualizará los detalles del usuario que se pasen.
-En otras palabras, la identificación inline se realiza mediante una operación `UPSERT`.
+En otras palabras, la identificación en línea se realiza mediante una operación `UPSERT`.
@@ -268,61 +270,61 @@ flowchart LR
Identificar usuarios de esta manera tiene dos beneficios clave:
-- Todos los nuevos usuarios que se registran en tu plataforma e incrementan una métrica se rastrean automáticamente en Trophy sin necesidad de código de identificación explícito escrito por ti
-- Cualquier cambio en las propiedades de usuarios existentes como nombre o dirección de correo electrónico se sincroniza automáticamente con Trophy la próxima vez que el usuario incrementa una métrica
+- Todos los usuarios nuevos que se registren en tu plataforma e incrementen una métrica son rastreados automáticamente en Trophy sin necesidad de que escribas código de identificación explícito
+- Cualquier cambio en las propiedades de usuarios existentes como nombre o dirección de correo electrónico se sincroniza automáticamente con Trophy la próxima vez que el usuario incremente una métrica
-De esta manera, la identificación inline te permite mantener toda tu base de usuarios en constante sincronización con Trophy con la menor cantidad de código requerido por tu parte.
+De esta manera, la identificación en línea te permite mantener toda tu base de usuarios constantemente sincronizada con Trophy con la menor cantidad de código requerido por tu parte.
Por eso recomendamos comenzar primero con la identificación inline y luego explorar la identificación explícita si descubres que necesitas más control.
### Identificación Explícita {#explicit-identification}
-La identificación explícita es cuando escribes código en tu aplicación que le indica explícitamente a Trophy sobre los usuarios de manera separada a cualquier interacción de métricas. Esto es útil si deseas tener control completo sobre cómo y cuándo Trophy se entera de tus usuarios.
+La identificación explícita es cuando escribes código en tu aplicación que le indica explícitamente a Trophy sobre los usuarios de forma separada de cualquier interacción con métricas. Esto es útil si deseas un control completo sobre cómo y cuándo Trophy conoce a tus usuarios.
Los escenarios en los que podrías querer usar la identificación explícita incluyen:
-- Quieres informarle a Trophy sobre nuevos usuarios inmediatamente al registrarse, antes de que incrementen una métrica
-- Rastreas muchas métricas en Trophy y no quieres repetir el código de identificación inline
-- Quieres informarle a Trophy solo sobre un grupo específico de usuarios, del cual tú controlas las condiciones
+- Quieres informar a Trophy sobre nuevos usuarios inmediatamente al registrarse, antes de que incrementen una métrica
+- Rastreas muchas métricas en Trophy y no quieres repetir el código de identificación inline.
+- Quieres informar a Trophy solo sobre un grupo específico de usuarios, del cual controlas las condiciones
-En este caso, puedes informar a Trophy sobre nuevos usuarios usando la [API de Identificación de Usuarios](/es/api-reference/endpoints/users/identify-a-user).
+En este caso, puedes informar a Trophy sobre nuevos usuarios usando el [API de Identificación de Usuarios](/es/api-reference/endpoints/users/identify-a-user).
- Al igual que en la identificación en línea, la identificación explícita también funciona mediante
- una operación `UPSERT`, lo que significa que todos los atributos de usuario se mantienen sincronizados
+ Al igual que en la identificación inline, la identificación explícita también funciona mediante
+ una operación `UPSERT` lo que significa que todos los atributos de usuario se mantienen sincronizados
con Trophy automáticamente.
## Creación de Usuarios {#creating-users}
-Para crear explícitamente un nuevo usuario en Trophy, utiliza la [API de Creación de Usuarios](/es/api-reference/endpoints/users/create-a-user).
+Para crear explícitamente un nuevo usuario en Trophy, usa el [API de Creación de Usuarios](/es/api-reference/endpoints/users/create-a-user).
## Mantener los Usuarios Actualizados {#keeping-users-up-to-date}
-Para informar a Trophy sobre una actualización de un usuario en tu plataforma, puedes usar la [API de Actualización de Usuarios](/es/api-reference/endpoints/users/update-a-user).
+Para informar a Trophy sobre una actualización de un usuario en tu plataforma, puedes usar el [API de Actualización de Usuarios](/es/api-reference/endpoints/users/update-a-user).
Todas las propiedades que pases a Trophy se actualizarán a los nuevos valores que especifiques.
- Como la [identificación de usuarios](#identifying-users) mantiene los registros de usuario actualizados por
- defecto, normalmente no es necesario actualizar explícitamente los usuarios en Trophy cada
- vez que una de sus propiedades cambia en tu aplicación. Sin embargo, la API de actualización de usuarios
- está disponible si realmente la necesitas.
+ Como la [identificación de usuarios](#identifying-users) mantiene los registros de usuarios actualizados por
+ defecto, generalmente no es necesario actualizar explícitamente los usuarios en Trophy cada
+ vez que una de sus propiedades cambia en tu aplicación. Sin embargo, el API de
+ actualización de usuarios está disponible si realmente lo necesitas.
-## Configuración de Preferencias de Usuario {#setting-user-preferences}
+## Configuración de preferencias de usuario {#setting-user-preferences}
-Trophy cuenta con APIs para ayudarte a crear un centro de preferencias que tus usuarios puedan usar para controlar y personalizar cómo interactúan con tus funciones de gamificación.
+Trophy cuenta con API para ayudarte a crear un centro de preferencias que tus usuarios pueden utilizar para controlar y personalizar la forma en que interactúan con tus funcionalidades de gamificación.
-Esta sección recorre todas las preferencias que puedes exponer a tus usuarios y su función.
+Esta sección describe todas las preferencias que puedes exponer a tus usuarios y su función.
-### Preferencias de Notificaciones {#notification-preferences}
+### Preferencias de notificaciones {#notification-preferences}
-Puedes usar Trophy para enviar [Correos electrónicos](/es/features/emails) y [Notificaciones push](/es/features/push-notifications) gamificados a tus usuarios.
+Puedes usar Trophy para enviar [correos electrónicos](/es/features/emails) y [notificaciones push](/es/features/push-notifications) gamificados a tus usuarios.
-La [API de actualización de preferencias](/es/api-reference/endpoints/users/update-user-preferences) de Trophy te permite crear un centro de preferencias dentro de tu aplicación con el que tus usuarios puedan interactuar para controlar qué notificaciones reciben y a través de qué canales.
+La [API de actualización de preferencias](/es/api-reference/endpoints/users/update-user-preferences) de Trophy te permite crear un centro de preferencias dentro de tu aplicación con el que tus usuarios pueden interactuar para controlar qué notificaciones reciben y a través de qué canales.
-La API te permite actualizar las preferencias de notificación de un usuario para diferentes tipos de notificaciones:
+La API te permite actualizar las preferencias de notificación de un usuario para diferentes tipos de notificación:
- **achievement_completed**: Notificaciones enviadas cuando un usuario completa un logro
-- **recap**: Notificaciones periódicas de resumen sobre el progreso del usuario
-- **reactivation**: Notificaciones enviadas para reactivar usuarios inactivos
+- **recap**: Notificaciones de resumen periódico sobre el progreso del usuario
+- **reactivation**: Notificaciones enviadas para volver a interactuar con usuarios inactivos
- **streak_reminder**: Recordatorios para ayudar a los usuarios a mantener sus rachas
Para cada tipo de notificación, puedes especificar en qué canales debe recibir notificaciones el usuario: `email`, `push`, o ambos. Para desactivar un tipo de notificación por completo, pasa un array vacío.
@@ -345,9 +347,9 @@ Por ejemplo, el siguiente fragmento de código actualiza las preferencias de not
-Para construir una interfaz de centro de preferencias en tu aplicación, primero necesitarás obtener las preferencias actuales del usuario utilizando la [API de obtener preferencias](/es/api-reference/endpoints/users/get-user-preferences).
+Para crear una interfaz de centro de preferencias en tu aplicación, primero debes obtener las preferencias actuales del usuario mediante la [API de obtención de preferencias](/es/api-reference/endpoints/users/get-user-preferences).
-Esto devolverá la configuración de notificaciones actual del usuario, que luego podrás mostrar en tu interfaz y permitir que los usuarios la modifiquen.
+Esto devolverá la configuración de notificaciones actual del usuario, que luego podrás mostrar en tu interfaz y permitir que los usuarios modifiquen.
@@ -366,36 +368,37 @@ La API devuelve una respuesta que contiene las preferencias de notificación act
Puedes usar esta respuesta para:
-- **Rellenar controles de formulario**: Preseleccionar casillas de verificación o interruptores en tu interfaz de centro de preferencias según los valores actuales
-- **Mostrar el estado actual**: Mostrar qué notificaciones están habilitadas y a través de qué canales
-- **Gestionar preferencias faltantes**: Si un tipo de notificación no está presente en la respuesta, significa que el usuario aún no ha establecido preferencias para ella, y puedes usar la configuración predeterminada de tu aplicación
+- **Rellenar controles de formulario**: Preselecciona casillas de verificación o conmutadores en la interfaz de tu centro de preferencias según los valores actuales
+- **Mostrar el estado actual**: Muestra qué notificaciones están habilitadas y a través de qué canales
+- **Gestionar preferencias faltantes**: Si un tipo de notificación no está presente en la respuesta, significa que el usuario aún no ha configurado preferencias para ello, y puedes usar la configuración predeterminada de tu aplicación
-Una vez que hayas obtenido y mostrado las preferencias, los usuarios pueden realizar cambios en tu interfaz, y puedes usar la [API de actualizar preferencias](/es/api-reference/endpoints/users/update-user-preferences) para guardar sus selecciones de vuelta en Trophy.
+Una vez que hayas obtenido y mostrado las preferencias, los usuarios pueden realizar cambios en tu interfaz, y puedes usar la [API de actualización de preferencias](/es/api-reference/endpoints/users/update-user-preferences) para guardar sus selecciones de vuelta en Trophy.
### Preferencias de Racha {#streak-preferences}
-Trophy admite preferencias de usuario para rachas, permitiendo a los usuarios personalizar las condiciones que deben cumplir para extender su racha, incluyendo qué días de la semana cuentan para ella.
+Trophy admite preferencias de usuario para rachas, lo que permite a los usuarios personalizar las condiciones que deben cumplir para extender su racha, incluyendo qué días de la semana cuentan para ella.
-Para usar las preferencias de racha, debes tener la [personalización de racha](/es/features/streaks#streak-personalization) habilitada.
+Para usar las preferencias de racha, debes tener la [personalización de rachas](/es/features/streaks#streak-personalization) habilitada.
-Una vez habilitada la personalización de racha, la [API de actualización de preferencias](/es/api-reference/endpoints/users/update-user-preferences) te permitirá anular la configuración de racha predeterminada para un usuario específico.
+Una vez que la personalización de rachas esté habilitada, la [API de actualización de preferencias](/es/api-reference/endpoints/users/update-user-preferences) te permitirá sobrescribir la configuración predeterminada de rachas para un usuario específico.
-Las siguientes configuraciones de racha pueden ser anuladas por las preferencias de usuario:
+Las siguientes configuraciones de racha pueden ser sobrescritas por las preferencias de usuario:
+- `enabled`: Si las rachas se calculan para este usuario. Cuando `false`, la racha del usuario siempre es `0` y no se envían webhooks ni notificaciones de racha.
- `metrics`: Un array de [métricas](/es/features/metrics) con umbrales personalizados requeridos para extender la racha.
- `evaluationMode`: Determina cómo se combinan las métricas para extender la racha. Puede ser `ALL` o `OR`.
-- `daysOff`: Un array de números de días de la semana (`0` = domingo hasta `6` = sábado) que anulan los [días libres](/es/features/streaks#days-off) de la organización. El usuario no perderá su racha si está inactivo en estos días.
+- `daysOff`: Un array de números de días de la semana (`0` = domingo hasta `6` = sábado) que sobrescriben los [días libres](/es/features/streaks#days-off) de la organización. El usuario no perderá su racha si está inactivo en estos días.
-Una vez configuradas las preferencias de racha, la [API de obtención de preferencias](/es/api-reference/endpoints/users/get-user-preferences) devolverá la configuración de racha personalizada del usuario.
+Una vez que se establecen las preferencias de racha, la [API de obtención de preferencias](/es/api-reference/endpoints/users/get-user-preferences) devolverá la configuración de racha personalizada del usuario.
-## Obtener Información del Usuario {#retrieving-user-information}
+## Recuperación de información del usuario {#retrieving-user-information}
-Para obtener los detalles de un usuario que ya has identificado con Trophy, usa la [API de Obtener Usuario](/es/api-reference/endpoints/users/get-a-single-user).
+Para obtener los detalles de un usuario que ya has identificado con Trophy, utiliza la [API Get User](/es/api-reference/endpoints/users/get-a-single-user).
-Esto devolverá los detalles completos del usuario junto con el atributo `control` que puedes usar para inscribir condicionalmente a los usuarios en cualquier característica de gamificación. Obtén más información sobre [Experimentación](/es/platform/experimentation).
+Esto devolverá los detalles completos del usuario junto con el atributo `control` que puedes usar para inscribir condicionalmente a los usuarios en cualquier función de gamificación. Obtén más información sobre [Experimentación](/es/platform/experimentation).
```json Response {3}
{
@@ -411,13 +414,13 @@ Esto devolverá los detalles completos del usuario junto con el atributo `contro
}
```
-## Analíticas de Usuario {#user-analytics}
+## Analítica de usuarios {#user-analytics}
-### Analíticas Básicas {#basic-analytics}
+### Analítica básica {#basic-analytics}
-Por defecto, Trophy incluye analíticas de usuario de alto nivel en la [página de Usuarios](https://app.trophy.so/users), incluyendo:
+Por defecto, Trophy incluye analítica de usuarios de alto nivel en la [página de Usuarios](https://app.trophy.so/users) que incluye:
-- El número total de usuarios sobre los que has informado a Trophy
+- El número total de usuarios que le has indicado a Trophy
- El número de usuarios que están activos diariamente
- El número de usuarios que están activos mensualmente
@@ -427,21 +430,21 @@ Por defecto, Trophy incluye analíticas de usuario de alto nivel en la [página
En esta página también puedes buscar entre todos los usuarios que Trophy ha registrado, lo cual puede ser útil para depuración.
-### Usuarios Principales {#top-users}
+### Usuarios destacados {#top-users}
-Además, en el [Panel de Control](https://app.trophy.so), Trophy muestra una lista de _Usuarios Principales_ con el conjunto de usuarios que han logrado mayor progreso respecto a las métricas de tu plataforma.
+Además, en el [Dashboard](https://app.trophy.so), Trophy muestra una lista de _Usuarios Destacados_ con el conjunto de usuarios que han logrado el mayor progreso contra las Métricas de tu plataforma.
-¡Estos son tus usuarios más comprometidos, por lo que es útil saber quiénes son!
+¡Estos son tus usuarios más comprometidos, así que es útil saber quiénes son!
-## Preguntas Frecuentes {#frequently-asked-questions}
+## Preguntas frecuentes {#frequently-asked-questions}
-
- ¡Tantos como quieras! Trophy solo cobra cada mes por usuarios _activos_, que son los usuarios que interactúan con tu producto al menos una vez en un mes determinado.
+
+ ¡Tantos como quieras! Trophy solo cobra cada mes por los usuarios _activos_, que son los usuarios que interactúan con tu producto al menos una vez en un mes determinado.
Esto es excelente porque significa que si un usuario abandona, no pagarás por él en los meses siguientes.
- Puedes ver el número total de usuarios por los que se te cobrará cada mes dentro de Trophy en la barra lateral:
+ Puedes ver el número total de usuarios que se te cobrarán cada mes dentro de Trophy en la barra lateral:
- Puedes estimar tus costos de uso en nuestra [página de Precios](https://trophy.so/pricing).
+ Puedes estimar los costos de uso en nuestra [página de precios](https://trophy.so/pricing).
-## Obtener Soporte {#get-support}
+## Obtener soporte {#get-support}
¿Quieres ponerte en contacto con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
diff --git a/es/platform/experimentation.mdx b/es/platform/experimentation.mdx
index d8427685..577054f6 100644
--- a/es/platform/experimentation.mdx
+++ b/es/platform/experimentation.mdx
@@ -1,9 +1,9 @@
---
title: Experimentación
description: Aprende a usar Trophy para experimentar con la experiencia de
- gamificación y aumentar la retención y el engagement de usuarios.
+ gamificación y aumentar la retención y el engagement de los usuarios.
og:description: Aprende a usar Trophy para experimentar con la experiencia de
- gamificación y aumentar la retención y el engagement de usuarios.
+ gamificación y aumentar la retención y el engagement de los usuarios.
icon: flask-conical
---
@@ -11,19 +11,22 @@ import ControlFlagBlock from "../../snippets/control-flag-block.mdx";
Trophy proporciona un conjunto básico de primitivas para ayudarte a implementar experiencias de gamificación más rápido. Pero la gamificación no es algo que puedas configurar y olvidar.
-Una parte clave de ejecutar una plataforma gamificada es la experimentación: ajustar y optimizar la experiencia de usuario para asegurar que los usuarios sigan regresando.
+Una parte clave de gestionar una plataforma gamificada es la experimentación: ajustar y optimizar la experiencia del usuario para asegurar que los usuarios sigan regresando.
-Normalmente, tendrías que construir estas herramientas tú mismo, pero con Trophy obtienes un stack de experimentación simple y listo para usar.
+Normalmente, tendrías que construir estas herramientas tú mismo, pero con Trophy obtienes un stack de experimentación simple listo para usar.
- Tenemos planes para extender las capacidades de experimentación de Trophy en el futuro para soportar pruebas A/B más granulares de tus funcionalidades de gamificación.
+ Tenemos planes para extender las capacidades de experimentación de Trophy en el futuro para
+ soportar pruebas A/B más granulares de tus funciones de gamificación.
## Ratio de Control {#control-ratio}
-Trophy tiene una capacidad integrada para realizar pruebas A/B automáticas de funcionalidades de gamificación usando un ratio de control.
+Trophy tiene una capacidad integrada para realizar pruebas A/B automáticas de funciones de gamificación usando un ratio de control.
-Ubicado en la [página de integración](https://app.trophy.so/integration/configure) del panel de Trophy, el ratio de control ajusta el porcentaje de usuarios que se asignan al grupo 'control' versus el grupo 'experimental'.
+Disponible en la [página de integración](https://app.trophy.so/integration/configure) del panel de Trophy, el ratio de control ajusta el porcentaje de usuarios que se asignan al grupo de 'control' frente al grupo 'experimental'.
+
+También puedes leer y actualizar `controlRatio` y `userActivationWindow` con la [API de administración de configuración de organización](/es/admin-api/endpoints/settings/update-organization-settings).
-Trophy devuelve el atributo `control` como `true` o `false` en la mayoría de las APIs relacionadas con datos de usuario, permitiéndote mostrar condicionalmente funcionalidades de gamificación a usuarios que están en el grupo experimental.
+Trophy devuelve el atributo `control` como `true` o `false` en la mayoría de las APIs relacionadas con datos de usuario, permitiéndote mostrar condicionalmente funciones de gamificación a usuarios que están en el grupo experimental.
-Si planeas medir el impacto general de las funcionalidades de gamificación, asegúrate de mostrar esas funcionalidades solo a usuarios con `control` configurado como `false`.
+Si planeas medir el impacto general de las funciones de gamificación, asegúrate de mostrar esas funciones solo a usuarios con `control` establecido en `false`.
- Trophy tampoco envía ningún [Email](/es/features/emails) o [Notificación Push](/es/features/push-notifications) a usuarios que están en el grupo de control.
+ Trophy tampoco envía ningún [Email](/es/features/emails) ni [Notificación Push](/es/features/push-notifications) a los usuarios que están en el grupo de control.
-Los paneles de análisis comparan la retención y el engagement de usuarios entre los grupos de control y experimentales, lo que te permite medir el impacto de las funcionalidades que construyes con Trophy y ajustar las mecánicas cuando sea necesario.
+Los dashboards de analíticas luego comparan la retención y el engagement de usuarios entre los usuarios en los grupos de control y experimental, permitiéndote medir el impacto de las funcionalidades que construyes con Trophy y ajustar las mecánicas cuando sea necesario.
-Tanto la retención como el engagement de usuarios son métricas importantes para medir el impacto de los cambios en la experiencia del usuario. Las siguientes secciones describen qué significa cada una y cómo se relacionan con las funcionalidades que construyes con Trophy.
+Tanto la retención como el engagement de usuarios son métricas importantes a utilizar al medir el impacto de los cambios en la experiencia del usuario. Las siguientes secciones explican qué significa cada una y cómo se relacionan con las funcionalidades que construyes con Trophy.
## ¿Qué es la retención? {#what-is-retention}
La retención de usuarios es el porcentaje de usuarios que siguen utilizando tu producto después de un período determinado.
-Los marcos temporales comunes incluyen retención de 7 días, 14 días y 30 días, donde los períodos más cortos proporcionan información sobre la experiencia inicial del usuario y los períodos más largos ofrecen información sobre el product-market fit a largo plazo.
+Los marcos de tiempo comunes incluyen retención a 7 días, 14 días y 30 días, donde los marcos de tiempo más cortos proporcionan información sobre la experiencia inicial del usuario y los marcos de tiempo más largos ofrecen información sobre el ajuste producto-mercado a largo plazo.
### Analíticas de retención {#retention-analytics}
-Trophy incluye un gráfico de retención para cada métrica en su panel de métricas y un gráfico agregado de retención de usuarios en el panel principal.
+Trophy incluye un gráfico de retención para cada métrica en su dashboard de métricas y un gráfico agregado de retención de usuarios en el dashboard principal.
-La [página de integración](https://app.trophy.so/integration/configure) te permite controlar el período de tiempo durante el cual deseas medir la retención mediante la configuración 'New User Activation Window'.
+La [página de integración](https://app.trophy.so/integration/configure) te permite controlar el marco de tiempo sobre el cual deseas medir la retención a través de la configuración 'Ventana de activación de nuevos usuarios'.
-Trophy también muestra gráficos que presentan la participación de los usuarios durante sus primeros días después de registrarse en tu producto.
+Trophy también muestra gráficos que presentan la participación de usuario dentro de los primeros días después de que los usuarios se registran en tu producto.
-Nos referimos a esto como 'participación temprana' y es la participación del usuario medida por Trophy solo para usuarios dentro del marco de tiempo establecido en la configuración 'Ventana de activación de nuevos usuarios' en la [página de integración](https://app.trophy.so/integration/configure).
+Nos referimos a esto como 'participación temprana' y es la participación de usuario medida por Trophy solo para usuarios dentro del período de tiempo establecido en la configuración 'Ventana de activación de nuevos usuarios' en la [página de integración](https://app.trophy.so/integration/configure).
-Este es un gráfico útil para comprender la participación de los usuarios durante sus primeros días con tu producto y para identificar dónde pueden estar ocurriendo bloqueos en la activación inicial de usuarios.
+Este es un gráfico útil para comprender la participación de los usuarios dentro de sus primeros días con tu producto y para identificar dónde pueden estar ocurriendo obstáculos para la activación inicial del usuario.
## Obtener soporte {#get-support}
diff --git a/features/achievements.mdx b/features/achievements.mdx
index 654f223e..7b5c079f 100644
--- a/features/achievements.mdx
+++ b/features/achievements.mdx
@@ -113,6 +113,10 @@ Composite achievements are useful for creating progression pathways and encourag
To create new achievements, head to the [achievements page](https://app.trophy.so/achievements) in the Trophy dashboard and hit the **New Achievement** button:
+
+You can also create, update, and delete achievements programmatically with the [Admin API](/admin-api/endpoints/achievements/create-achievements).
+
+
For a full walk through on how to set up a streak feature using Trophy, check out our [official guide](/guides/how-to-build-a-streaks-feature).
diff --git a/features/users.mdx b/features/users.mdx
index c84740cc..c7e14999 100644
--- a/features/users.mdx
+++ b/features/users.mdx
@@ -385,6 +385,7 @@ In order to use streak preferences, you must have [streak personalization](/feat
Once streak personalization is enabled, the [update preferences API](/api-reference/endpoints/users/update-user-preferences) will allow you to override default streak settings for a specific user.
The following streak settings can be overridden by user preferences:
+- `enabled`: Whether streaks are calculated for this user. When `false`, the user's streak is always `0` and streak webhooks and notifications are not sent.
- `metrics`: An array of [metrics](/features/metrics) with custom thresholds required to extend the streak.
- `evaluationMode`: Determines how metrics combine to extend the streak. Can be `ALL` or `OR`.
- `daysOff`: An array of weekday numbers (`0` = Sunday through `6` = Saturday) that override the organization [days off](/features/streaks#days-off). The user will not lose their streak if they are inactive on these days.
diff --git a/i18n.json b/i18n.json
index 780bc44f..588ac6a5 100644
--- a/i18n.json
+++ b/i18n.json
@@ -20,6 +20,8 @@
"admin-api/endpoints/leaderboards/*.mdx",
"admin-api/endpoints/tenants/*.mdx",
"admin-api/endpoints/application-api-keys/*.mdx",
+ "admin-api/endpoints/achievements/*.mdx",
+ "admin-api/endpoints/settings/*.mdx",
"api-reference/*.mdx",
"api-reference/endpoints/achievements/*.mdx",
"api-reference/endpoints/leaderboards/*.mdx",
diff --git a/i18n.lock b/i18n.lock
index dff66c1f..27be8e08 100644
--- a/i18n.lock
+++ b/i18n.lock
@@ -53,10 +53,11 @@ checksums:
meta/icon: eb9d4363bef4880ef3c4f9f2647df1af
content/0: e7faed2662792f40c5d1271139ea6126
content/1: 0f5d4b17bed882a4aa1da136161feda3
- content/2: 51b682b74e26954affd9a703881c21b0
- content/3: 5ebe6996a807f210e72b4b035ec84b2d
- content/4: 10e8e9a59847ddd720c6d06b12c7b120
- content/5: 9799b973234bf2d10d5c971b267f55a5
+ content/2: 3013c6cb2ca77389245788d6eb034ed0
+ content/3: 51b682b74e26954affd9a703881c21b0
+ content/4: 5ebe6996a807f210e72b4b035ec84b2d
+ content/5: 10e8e9a59847ddd720c6d06b12c7b120
+ content/6: 9799b973234bf2d10d5c971b267f55a5
2f2c47cb4b33537fb421f031fc18671b:
meta/title: 0932e80cba1e3e0a7f52bb67ff31da32
meta/description: 62e872aca21095216284276335fd7ef9
@@ -2381,7 +2382,7 @@ checksums:
content/1: 264d832bc605beaf5168c080bfed567c
content/2: 580af53aa9812f2ec29a632e145669a5
738b59e21fdab2928556ce570256b3d0:
- meta/title: 4a0417878be2b69b372844870758e18d
+ meta/title: fcea899265e846c4bfb9bb2774f72f1b
meta/openapi: 8fb82df671ba1dd34f65d7e15cf8d098
content/0: c3d96e3528a55b20b8fbcae10af25b02
content/1: 264d832bc605beaf5168c080bfed567c
@@ -2411,7 +2412,7 @@ checksums:
content/1: 264d832bc605beaf5168c080bfed567c
content/2: 580af53aa9812f2ec29a632e145669a5
b8af879dacafc5fd3abdd5d560e6eedf:
- meta/title: cb6eee9d29302e212aa7c84375d9e183
+ meta/title: f030a0c1cf7a6e43182fac4ff29ed0f6
meta/openapi: 2c16f530b0e0509d411da6bd34add9dd
content/0: c3d96e3528a55b20b8fbcae10af25b02
content/1: 264d832bc605beaf5168c080bfed567c
@@ -2674,7 +2675,7 @@ checksums:
content/1: 264d832bc605beaf5168c080bfed567c
content/2: 580af53aa9812f2ec29a632e145669a5
d08dac3a954b395aa154a46e23dc9456:
- meta/title: bd0215a6587ed15a35293cdfb5fb6f04
+ meta/title: 3cc6f91d57cca53cf63fd42d5063b150
meta/openapi: bbb2d9800a873a257c3ac977d175ff01
content/0: c3d96e3528a55b20b8fbcae10af25b02
content/1: 264d832bc605beaf5168c080bfed567c
@@ -3006,7 +3007,7 @@ checksums:
content/107: 95efbad0a7da9f018cff696e876e8e92
content/108: 6fa651ab619439507ee78deb16347c6d
content/109: d9189f8b7c2e8275377389cc5efd839c
- content/110: 2b3232bbb15e2156a1ffec4e52fd31e0
+ content/110: 407b561956cd0f044d59f720f91a19d3
content/111: b88cecdd3a61d8f53c77b70133480726
content/112: 2bba6a2c111fd7e0f359988d29dbfbe4
content/113: 60d936cc4d94cd2641f179a3d581fb84
@@ -3083,38 +3084,39 @@ checksums:
content/43: 2b47756439adf8f9b38b04085a709a03
content/44: b6f909922cc9e10746ea84ce96827b16
content/45: 0b45597750a093259a241cf3c4da862e
- content/46: d6facb51881f25f097fe04dbf2e5103f
- content/47: 43ad0b6ea6fbeef69ece943e165a168e
- content/48: d46604b7106ba86b7a3ae607bdd4caa0
- content/49: 1b74535bea8880d2eba99cea305770dd
- content/50: 20bdf64fd91ed2bc4687a1657bbfae8a
- content/51: 2214e876e97977bf5cebec45dcdcd1c8
- content/52: 2dacfcc9d13a93d2965ca6051ee62fde
- content/53: 4caecadc2bf024da1773cf2b612aa8cb
- content/54: 91ffb03304d0dc66f9fc2357aa39346f
- content/55: 9e4d09a957ca66f58d4248300fbe2662
- content/56: 758ecef4a7a0b5d55fb97febe4184ec2
- content/57: 9aec72901fcecb0cdf45f729387b9742
- content/58: 71d6882b2ae9220e3bb0c6abc98fc236
- content/59: bfa82570db14cd44d636f90e20080898
- content/60: 59f82b2e0dbec73340a007cb020ab2ce
- content/61: 54e6b1cb90e203d05d06a5d188238cd4
- content/62: 4f72e470a0dbe75e396f57952f29901a
- content/63: 380be3ed5af370f2d36a66f4c55f7f0b
- content/64: 5a5f6f25f2b2cf4ebbb5f018bb0d5824
- content/65: ed7cd0fb6f61c823f39fe089a7f62e1f
- content/66: b3bc9605c19967a6162e1c72333251a9
- content/67: ac3267698b45c30fea7622d6f38767b5
- content/68: 40a3888d076524edcb9716f64683c5b3
- content/69: f8bc90b1b7d0108fdfad2e3bd7641dbf
- content/70: 98200505f691d3dcb12fa6833d0e88ad
- content/71: df90d3b6267199a3dd86d820374aa785
- content/72: 286a2716711641435b4b996d8b22e881
- content/73: 29e769123cc029c8c9657dcd8d384b83
- content/74: 08345a94bd6f9b9539d128e5db15184a
- content/75: 47770b5654a1f47d56eba81273ff08d9
- content/76: 10e8e9a59847ddd720c6d06b12c7b120
- content/77: 9799b973234bf2d10d5c971b267f55a5
+ content/46: f2634056fff83ae168b67425a49db97d
+ content/47: d6facb51881f25f097fe04dbf2e5103f
+ content/48: 43ad0b6ea6fbeef69ece943e165a168e
+ content/49: d46604b7106ba86b7a3ae607bdd4caa0
+ content/50: 1b74535bea8880d2eba99cea305770dd
+ content/51: 20bdf64fd91ed2bc4687a1657bbfae8a
+ content/52: 2214e876e97977bf5cebec45dcdcd1c8
+ content/53: 2dacfcc9d13a93d2965ca6051ee62fde
+ content/54: 4caecadc2bf024da1773cf2b612aa8cb
+ content/55: 91ffb03304d0dc66f9fc2357aa39346f
+ content/56: 9e4d09a957ca66f58d4248300fbe2662
+ content/57: 758ecef4a7a0b5d55fb97febe4184ec2
+ content/58: 9aec72901fcecb0cdf45f729387b9742
+ content/59: 71d6882b2ae9220e3bb0c6abc98fc236
+ content/60: bfa82570db14cd44d636f90e20080898
+ content/61: 59f82b2e0dbec73340a007cb020ab2ce
+ content/62: 54e6b1cb90e203d05d06a5d188238cd4
+ content/63: 4f72e470a0dbe75e396f57952f29901a
+ content/64: 380be3ed5af370f2d36a66f4c55f7f0b
+ content/65: 5a5f6f25f2b2cf4ebbb5f018bb0d5824
+ content/66: ed7cd0fb6f61c823f39fe089a7f62e1f
+ content/67: b3bc9605c19967a6162e1c72333251a9
+ content/68: ac3267698b45c30fea7622d6f38767b5
+ content/69: 40a3888d076524edcb9716f64683c5b3
+ content/70: f8bc90b1b7d0108fdfad2e3bd7641dbf
+ content/71: 98200505f691d3dcb12fa6833d0e88ad
+ content/72: df90d3b6267199a3dd86d820374aa785
+ content/73: 286a2716711641435b4b996d8b22e881
+ content/74: 29e769123cc029c8c9657dcd8d384b83
+ content/75: 08345a94bd6f9b9539d128e5db15184a
+ content/76: 47770b5654a1f47d56eba81273ff08d9
+ content/77: 10e8e9a59847ddd720c6d06b12c7b120
+ content/78: 9799b973234bf2d10d5c971b267f55a5
9f5464896b543cfd1d607b30a9997155:
meta/title: e771f23130f9aab4f3e2e99acacf5d5a
meta/description: 8539ebe90ff733bef6498db1933f3a57
@@ -3658,7 +3660,7 @@ checksums:
content/57: 6fb10904ed0f3f4a59ad18d2029a2281
content/58: baa86d1c09371a07fb8b8f843e01d6f7
content/59: 19e423f1c9380680e8527c4a65ffd114
- content/60: e13a6d53be2fc8fdd8aad8b7357b657a
+ content/60: 28246ddcc14f82de139fb775620cb00c
content/61: 98afb03d2a39b85d1619082fc10948e0
content/62: 606082a0f1fbe2e04c8c9a16d1abbd66
content/63: c0b0f1453346c2c9eafcd0c462cf6b72
@@ -3860,92 +3862,93 @@ checksums:
content/37: 6eb955db1077750aabebbba41a7222e9
content/38: fd1a0e20852eb79c0d23d1d28b4bf4bb
content/39: ea99714c8b9c66c96074a0ff8a980218
- content/40: c25866a6ab2f45fae6eabd6e8ae78c96
- content/41: d35cc94bd5ff7f9a8a7b1b266904456f
- content/42: 77d7e5c72141fcd4398d079f1de0a6b5
- content/43: 973b136d6944704b1aa40878b4084812
- content/44: 1dd92f7bd1ab3b72167fa64f9971e7db
- content/45: e33ced9321d254db63b7099959879b7c
- content/46: a832fdbe52a9b63059d7bedf20c4590f
- content/47: 04441e88d59a1c1a8d824ff19439156d
- content/48: d9a475aa7d87fef54806bcb5e46395b7
- content/49: 640d0b31f6faa54914d25c81f5dbf413
- content/50: dc935e05d07a9d4f92666bd327321f3a
- content/51: c4582dd57904671f21a9168d46e083af
- content/52: d2ca11a833c6014fae2195e45b2741e4
- content/53: 7b85995586cab414ddb40939e288631c
- content/54: 1eccf545d3bbd6a450348ee11bf1fc13
- content/55: 6e12b58d5a6d92e53d56ecb9168bacc3
- content/56: 640d0b31f6faa54914d25c81f5dbf413
- content/57: a3b1e396e4d757d9f716937605f6c513
- content/58: 561fb5d6d9965a731b99ba68b6d493b6
- content/59: c2c40b4001762023a42bbe17a4c95132
- content/60: 42facdcb08b410e8073ea13de4db8541
- content/61: 640d0b31f6faa54914d25c81f5dbf413
- content/62: 07658aa358af3ef9d173c3f75751a176
- content/63: 88894d9a6f1d49cb0329825bb76e5a17
- content/64: 25b662df6a87d36e4925a6af4247888d
- content/65: 374b1eb956e935cf3f51c46af62831ac
- content/66: ad94b06eaa66c2fd263362b6af04b9c0
- content/67: c6906582420cbe603d1bb135d7cdc13a
- content/68: e6d0829ea90222582df021491c834609
- content/69: c6b7171acaf9ea0be21b408e4beb6c73
- content/70: bbfc8b8ec96997b3e589802f18424196
- content/71: a57adc8d19410c1974f8d59a2e2e1cb9
- content/72: f83c5cc385540bbff0ce0280e31d703d
- content/73: 8040541596306a73329cc1f4c375d616
- content/74: bec0c223723733b84c83e6d13b637855
- content/75: 1c526016dbe08ff63980dc829cc327f7
- content/76: 7a28532a6fea4655fe26554b42ff57bb
- content/77: 61f4238f95cc209302563fe0d66aea20
- content/78: a8d041efa094c2ed92fdf6b98bac93d3
- content/79: dd256e45824b048778e81a0e80a3a6cf
- content/80: e52eac7d854a85c3f6a777d736f831d9
- content/81: b384ef84f794014c78bd7232f18d3b5f
- content/82: 19f49f0312ddc4ded8f6737083673edf
- content/83: 9572e0cb99536535c176db24863ce217
- content/84: 40a3888d076524edcb9716f64683c5b3
- content/85: 041645f33a12c870680e713dc7b8d78a
- content/86: 98200505f691d3dcb12fa6833d0e88ad
- content/87: 6fecb4eaca40bae0bb37fbe65ff6a637
- content/88: 4455b21dd9cea4b18d0d3991c010eacb
- content/89: 61b6140fd37b3d64ac6cf6a5529119a8
- content/90: 3238f9be2abc7e4a60a82285a538339c
- content/91: 539769066341e46b743c0cfda822f3f9
- content/92: c66f09fe4fa88a9e016ebe4f0a2ed9b0
- content/93: ff156aee000c5c5a8315a6e6eefd77a8
- content/94: 7f85a8c7e5217b02244281defb8e8592
- content/95: 8e740237c4c0f42095ee3e87bd1f9130
- content/96: 43e6ec093695c83476ddafd3674f8ec0
- content/97: 5425ae9feefbe5a5ce28290afc321625
- content/98: 853f6a32a56f50b2366cc2e9bfe30cef
- content/99: 54dcc7d2d5e4c5ed2c9303950e89ab0d
- content/100: aa1e5bc107219b8f73778df6a2eaf649
- content/101: 3898b08aad245d481c00759bba165827
- content/102: 5a26c709955575918c0b6c9093f47410
- content/103: 655cdcfa96c0268d19fdc3ab68dc0239
- content/104: 080834714f41b28fa5e15cc6139d4346
- content/105: 2c595c5d764fd8e4bc386193ea202888
- content/106: 083e769853a4074246e3b140c55e2778
- content/107: a24eeda297d1c1e30583069309251316
- content/108: d860fb4c61d9774d524a4136c86cb598
- content/109: 49f4d4d4682844d287bd156d5902b096
- content/110: 29c9df71eb3d97cd840e59bfa6d65acc
- content/111: 39015ba77832b5dacd6e87e6c26d7ab5
- content/112: 6796a141f343079b9b3d89771d346d3b
- content/113: 79524f874744893afda00224a0203ea6
- content/114: 656598f8d7330171f0a3f1f73e884e9f
- content/115: eb7a29fcbea23aeecc0192229112e275
- content/116: 24d2d94ddb5fce97b0836d69a6ee5297
- content/117: 25d2f401cdd79bd9c1e761535eb145ce
- content/118: 1c813fba4719c7b29863b4944f3dc074
- content/119: 450ad7f99b79b12599856f813b9ef758
- content/120: 39f313714117fbf6ed7b64076ffe1498
- content/121: c825a2eba8d1174bd1f191adc0c4cd48
- content/122: aae63d8bf6b6da4ac6fb501e13691e4d
- content/123: 7a451aee1061c1cf2a4108f13acbafff
- content/124: 10e8e9a59847ddd720c6d06b12c7b120
- content/125: 9799b973234bf2d10d5c971b267f55a5
+ content/40: e9dbb646483e244688241781feca4622
+ content/41: c25866a6ab2f45fae6eabd6e8ae78c96
+ content/42: d35cc94bd5ff7f9a8a7b1b266904456f
+ content/43: 77d7e5c72141fcd4398d079f1de0a6b5
+ content/44: 973b136d6944704b1aa40878b4084812
+ content/45: 1dd92f7bd1ab3b72167fa64f9971e7db
+ content/46: e33ced9321d254db63b7099959879b7c
+ content/47: a832fdbe52a9b63059d7bedf20c4590f
+ content/48: 04441e88d59a1c1a8d824ff19439156d
+ content/49: d9a475aa7d87fef54806bcb5e46395b7
+ content/50: 640d0b31f6faa54914d25c81f5dbf413
+ content/51: dc935e05d07a9d4f92666bd327321f3a
+ content/52: c4582dd57904671f21a9168d46e083af
+ content/53: d2ca11a833c6014fae2195e45b2741e4
+ content/54: 7b85995586cab414ddb40939e288631c
+ content/55: 1eccf545d3bbd6a450348ee11bf1fc13
+ content/56: 6e12b58d5a6d92e53d56ecb9168bacc3
+ content/57: 640d0b31f6faa54914d25c81f5dbf413
+ content/58: a3b1e396e4d757d9f716937605f6c513
+ content/59: 561fb5d6d9965a731b99ba68b6d493b6
+ content/60: c2c40b4001762023a42bbe17a4c95132
+ content/61: 42facdcb08b410e8073ea13de4db8541
+ content/62: 640d0b31f6faa54914d25c81f5dbf413
+ content/63: 07658aa358af3ef9d173c3f75751a176
+ content/64: 88894d9a6f1d49cb0329825bb76e5a17
+ content/65: 25b662df6a87d36e4925a6af4247888d
+ content/66: 374b1eb956e935cf3f51c46af62831ac
+ content/67: ad94b06eaa66c2fd263362b6af04b9c0
+ content/68: c6906582420cbe603d1bb135d7cdc13a
+ content/69: e6d0829ea90222582df021491c834609
+ content/70: c6b7171acaf9ea0be21b408e4beb6c73
+ content/71: bbfc8b8ec96997b3e589802f18424196
+ content/72: a57adc8d19410c1974f8d59a2e2e1cb9
+ content/73: f83c5cc385540bbff0ce0280e31d703d
+ content/74: 8040541596306a73329cc1f4c375d616
+ content/75: bec0c223723733b84c83e6d13b637855
+ content/76: 1c526016dbe08ff63980dc829cc327f7
+ content/77: 7a28532a6fea4655fe26554b42ff57bb
+ content/78: 61f4238f95cc209302563fe0d66aea20
+ content/79: a8d041efa094c2ed92fdf6b98bac93d3
+ content/80: dd256e45824b048778e81a0e80a3a6cf
+ content/81: e52eac7d854a85c3f6a777d736f831d9
+ content/82: b384ef84f794014c78bd7232f18d3b5f
+ content/83: 19f49f0312ddc4ded8f6737083673edf
+ content/84: 9572e0cb99536535c176db24863ce217
+ content/85: 40a3888d076524edcb9716f64683c5b3
+ content/86: 041645f33a12c870680e713dc7b8d78a
+ content/87: 98200505f691d3dcb12fa6833d0e88ad
+ content/88: 6fecb4eaca40bae0bb37fbe65ff6a637
+ content/89: 4455b21dd9cea4b18d0d3991c010eacb
+ content/90: 61b6140fd37b3d64ac6cf6a5529119a8
+ content/91: 3238f9be2abc7e4a60a82285a538339c
+ content/92: 539769066341e46b743c0cfda822f3f9
+ content/93: c66f09fe4fa88a9e016ebe4f0a2ed9b0
+ content/94: ff156aee000c5c5a8315a6e6eefd77a8
+ content/95: 7f85a8c7e5217b02244281defb8e8592
+ content/96: 8e740237c4c0f42095ee3e87bd1f9130
+ content/97: 43e6ec093695c83476ddafd3674f8ec0
+ content/98: 5425ae9feefbe5a5ce28290afc321625
+ content/99: 853f6a32a56f50b2366cc2e9bfe30cef
+ content/100: 54dcc7d2d5e4c5ed2c9303950e89ab0d
+ content/101: aa1e5bc107219b8f73778df6a2eaf649
+ content/102: 3898b08aad245d481c00759bba165827
+ content/103: 5a26c709955575918c0b6c9093f47410
+ content/104: 655cdcfa96c0268d19fdc3ab68dc0239
+ content/105: 080834714f41b28fa5e15cc6139d4346
+ content/106: 2c595c5d764fd8e4bc386193ea202888
+ content/107: 083e769853a4074246e3b140c55e2778
+ content/108: a24eeda297d1c1e30583069309251316
+ content/109: d860fb4c61d9774d524a4136c86cb598
+ content/110: 49f4d4d4682844d287bd156d5902b096
+ content/111: 29c9df71eb3d97cd840e59bfa6d65acc
+ content/112: 39015ba77832b5dacd6e87e6c26d7ab5
+ content/113: 6796a141f343079b9b3d89771d346d3b
+ content/114: 79524f874744893afda00224a0203ea6
+ content/115: 656598f8d7330171f0a3f1f73e884e9f
+ content/116: eb7a29fcbea23aeecc0192229112e275
+ content/117: 24d2d94ddb5fce97b0836d69a6ee5297
+ content/118: 25d2f401cdd79bd9c1e761535eb145ce
+ content/119: 1c813fba4719c7b29863b4944f3dc074
+ content/120: 450ad7f99b79b12599856f813b9ef758
+ content/121: 39f313714117fbf6ed7b64076ffe1498
+ content/122: c825a2eba8d1174bd1f191adc0c4cd48
+ content/123: aae63d8bf6b6da4ac6fb501e13691e4d
+ content/124: 7a451aee1061c1cf2a4108f13acbafff
+ content/125: 10e8e9a59847ddd720c6d06b12c7b120
+ content/126: 9799b973234bf2d10d5c971b267f55a5
b9a22377f64ce5d4d2ac7d00ec52b19b:
meta/title: 19a9b6e09543581b42781bab0a65e59b
meta/description: d1d27c1ea0a6ce57cfa668f6bbe01093
@@ -3959,37 +3962,38 @@ checksums:
content/5: 5aabefbcf94472b569508be72751f801
content/6: 644b8db865c9d2016b83beb88e5847af
content/7: 0c47c590f0986f47c0a30100d9cc96e6
- content/8: 8fbcb95c4393b3f3433fd9ea219ebf92
- content/9: 1a8ed7a346c65c805b498a5d439a1523
- content/10: ecd8ed7d2c86d0ec3cc46ba315b0b5ef
- content/11: c42f8f8cb27636b5d91b9be3dcbbffcf
- content/12: 9bff18420c6aab89523002efb5c1d81c
- content/13: cd7d3c9bb150e7bb11fdec03bd998e5c
- content/14: 4c0d83480a443bc4c0c593c51894a240
- content/15: 27f9f487a4253758f7bf13eae193a07f
- content/16: 12a12e60e2f7494adf0350f88a8e56fc
- content/17: 8fe266a3394614b4e71610cf62b1d0d2
- content/18: d99183b387b18a0b5468464ee1ea0f95
- content/19: a5ebfbcb63e9da91ee398bdb9c68aa66
- content/20: 655d0dfd51e81616c9458f5bcf74d306
- content/21: 8f62929e6a367180a914de15466e7666
- content/22: 117dddac1874594a761a1b86501e6cd4
- content/23: 72458c98d2c77308300b720212a2a095
- content/24: 80c154790daeeb91cf75f883af9ceec4
- content/25: eafd4303afc235466d99a8ed4483e2c6
- content/26: 079f6a062d7984e09e24742febd098ff
- content/27: acb714163b0db26a38430616d595b533
- content/28: 83f83f6e590cd1b01077206252813eb0
- content/29: f195d9148880b2c125cf6a0ff808c1e0
- content/30: feb4ae88307da01a5268ee8b5636da4f
- content/31: f2a49df0ae5aab09a7567b67e9e3a2ca
- content/32: d083637554cef632486d6f56fec5650a
- content/33: 07521d724b00591287a1b5cdc1901fcb
- content/34: 02f4a73dee90169dca0edf03ff80e79f
- content/35: 72458c98d2c77308300b720212a2a095
- content/36: 11d9354aad0938839619ea2cd6bfc84e
- content/37: 10e8e9a59847ddd720c6d06b12c7b120
- content/38: 9799b973234bf2d10d5c971b267f55a5
+ content/8: 73b4999e615c1112321b43ce5ed9edfa
+ content/9: 8fbcb95c4393b3f3433fd9ea219ebf92
+ content/10: 1a8ed7a346c65c805b498a5d439a1523
+ content/11: ecd8ed7d2c86d0ec3cc46ba315b0b5ef
+ content/12: c42f8f8cb27636b5d91b9be3dcbbffcf
+ content/13: 9bff18420c6aab89523002efb5c1d81c
+ content/14: cd7d3c9bb150e7bb11fdec03bd998e5c
+ content/15: 4c0d83480a443bc4c0c593c51894a240
+ content/16: 27f9f487a4253758f7bf13eae193a07f
+ content/17: 12a12e60e2f7494adf0350f88a8e56fc
+ content/18: 8fe266a3394614b4e71610cf62b1d0d2
+ content/19: d99183b387b18a0b5468464ee1ea0f95
+ content/20: a5ebfbcb63e9da91ee398bdb9c68aa66
+ content/21: 655d0dfd51e81616c9458f5bcf74d306
+ content/22: 8f62929e6a367180a914de15466e7666
+ content/23: 117dddac1874594a761a1b86501e6cd4
+ content/24: 72458c98d2c77308300b720212a2a095
+ content/25: 80c154790daeeb91cf75f883af9ceec4
+ content/26: eafd4303afc235466d99a8ed4483e2c6
+ content/27: 079f6a062d7984e09e24742febd098ff
+ content/28: acb714163b0db26a38430616d595b533
+ content/29: 83f83f6e590cd1b01077206252813eb0
+ content/30: f195d9148880b2c125cf6a0ff808c1e0
+ content/31: feb4ae88307da01a5268ee8b5636da4f
+ content/32: f2a49df0ae5aab09a7567b67e9e3a2ca
+ content/33: d083637554cef632486d6f56fec5650a
+ content/34: 07521d724b00591287a1b5cdc1901fcb
+ content/35: 02f4a73dee90169dca0edf03ff80e79f
+ content/36: 72458c98d2c77308300b720212a2a095
+ content/37: 11d9354aad0938839619ea2cd6bfc84e
+ content/38: 10e8e9a59847ddd720c6d06b12c7b120
+ content/39: 9799b973234bf2d10d5c971b267f55a5
f88bb06e37f2be82f58b7d21aea2fe12:
meta/title: 2b3d02ff56b5f77b272637252681667c
content/0: 1555401e851bd6d479e2e36e6687a71d
@@ -7074,3 +7078,57 @@ checksums:
content/0: c3d96e3528a55b20b8fbcae10af25b02
content/1: 264d832bc605beaf5168c080bfed567c
content/2: 580af53aa9812f2ec29a632e145669a5
+ c5b207d69e4e7a29639c4efa395e73dc:
+ meta/title: 955760f80a5b2185eb05fea6a4e78a5b
+ meta/openapi: 4c95424aa430564ea3150e0a6208d698
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 6e496abffecd35c862be4e25a099e57d:
+ meta/title: 3704761060603dc8ae06179246a2793e
+ meta/openapi: 1d219866924ff19cf7c0f4d94a6b132b
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 400cd75e5ba47c4362668108ad02e0a3:
+ meta/title: 05694e440e584d3bded9f5930f634c50
+ meta/openapi: dd247c3dca74400410c0b715edde1803
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 74bfc4b1c7fd4b1dbf76e33d03c26735:
+ meta/title: c9ba5b45bbdc36846b2fa6a76c3f818a
+ meta/openapi: 0f877f1aea24db5b25fecffd8a646e9a
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 4c1802c31904e82291b0f2ea2cb45fa2:
+ meta/title: 27be7c6b9ba752dab1bae3b69ee09709
+ meta/openapi: 98bbab8ec692c6d1a42ef81e024fdc82
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 21486a74e5cfe4335371b304fb8abf7d:
+ meta/title: c233ef1a8491b33c9faa1ba2a22efaee
+ meta/openapi: 712e9a10956ff77b9e90de8134d3939b
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 03b1f41c04a9f6e3e59bb92629552902:
+ meta/title: fc96ea4f9de4667d8408c4a33e981a7b
+ meta/openapi: 26552e3fcdbd181a1e6bcb1a7babd1ec
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 560306f2647b1f12db6e039fb2a27f3a:
+ meta/title: e61dde98d98136b3cef1e6b109f12687
+ meta/openapi: e0da5f4144959c99026664c2c3cf733e
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
+ 60cb9bea695797dae212faf77f775ca5:
+ meta/title: 156c45bf0c1efef69c51074c61d56662
+ meta/openapi: 4a1ef774e4b57a8b8933b8ccc1d3e904
+ content/0: c3d96e3528a55b20b8fbcae10af25b02
+ content/1: 264d832bc605beaf5168c080bfed567c
+ content/2: 580af53aa9812f2ec29a632e145669a5
diff --git a/openapi/admin.json b/openapi/admin.json
index 293e28c5..56c5456c 100644
--- a/openapi/admin.json
+++ b/openapi/admin.json
@@ -2,13 +2,13 @@
"openapi": "3.1.0",
"info": {
"title": "Trophy",
- "version": "1.21.1"
+ "version": "1.24.0"
},
"x-fern-global-headers": [
{
"header": "X-SDK-VERSION",
"name": "sdkVersion",
- "x-fern-default": "1.21.1"
+ "x-fern-default": "1.24.0"
}
],
"paths": {
@@ -633,7 +633,7 @@
}
}
},
- "summary": "Get an attribute",
+ "summary": "Get an attribute by ID",
"security": [
{
"ApiKeyAuth": []
@@ -641,7 +641,7 @@
]
}
},
- "/metrics": {
+ "/achievements": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -654,12 +654,12 @@
}
],
"get": {
- "description": "List metrics.",
- "operationId": "admin_metrics_list",
+ "description": "List achievements.",
+ "operationId": "admin_achievements_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "metrics"
+ "achievements"
],
"x-fern-sdk-method-name": "list",
"tags": [
@@ -668,15 +668,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst metrics = await trophy.admin.metrics.list({\n limit: 10,\n skip: 0\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst achievements = await trophy.admin.achievements.list({\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nmetrics = client.admin.metrics.list(\n limit=10,\n skip=0\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nachievements = client.admin.achievements.list(\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.List(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Achievements.List(context.TODO(), nil)\n"
}
],
"parameters": [
@@ -712,24 +712,32 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ListMetricsResponse"
+ "$ref": "#/components/schemas/ListAchievementsResponse"
},
"examples": {
- "Metrics list": {
+ "Achievements list": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Oldest Metric",
- "key": "oldest-metric",
- "unitType": "number",
- "units": ""
+ "name": "First Workout",
+ "description": "Complete your first workout",
+ "trigger": "metric",
+ "status": "active",
+ "badge": null,
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1,
+ "eventAttributes": []
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Revenue",
- "key": "revenue",
- "unitType": "currency",
- "units": "USD"
+ "name": "Week Warrior",
+ "description": "Maintain a 7-day streak",
+ "trigger": "streak",
+ "status": "inactive",
+ "badge": null,
+ "userAttributes": [],
+ "streakLength": 7
}
]
}
@@ -758,7 +766,7 @@
}
}
},
- "summary": "List metrics",
+ "summary": "List achievements",
"security": [
{
"ApiKeyAuth": []
@@ -766,12 +774,12 @@
]
},
"post": {
- "description": "Create metrics.",
- "operationId": "admin_metrics_create",
+ "description": "Create achievements. Trigger-specific fields are required based on `trigger`.",
+ "operationId": "admin_achievements_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "metrics"
+ "achievements"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -780,37 +788,38 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.create([\n {\n name: 'Invites Sent',\n key: 'invites-sent'\n },\n {\n name: 'Revenue',\n key: 'revenue',\n unitType: 'currency',\n units: 'USD'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.achievements.create([\n {\n name: 'First Workout',\n trigger: 'metric',\n metricId: '660f9500-f30c-42e5-b827-557766550001',\n metricValue: 1\n },\n {\n name: 'Custom Unlock',\n trigger: 'api',\n key: 'custom-unlock'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.create([\n {\n \"name\": \"Invites Sent\",\n \"key\": \"invites-sent\"\n },\n {\n \"name\": \"Revenue\",\n \"key\": \"revenue\",\n \"unitType\": \"currency\",\n \"units\": \"USD\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.achievements.create([\n {\n \"name\": \"First Workout\",\n \"trigger\": \"metric\",\n \"metric_id\": \"660f9500-f30c-42e5-b827-557766550001\",\n \"metric_value\": 1\n },\n {\n \"name\": \"Custom Unlock\",\n \"trigger\": \"api\",\n \"key\": \"custom-unlock\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Create(context.TODO(), api.CreateMetricsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Achievements.Create(context.TODO(), api.CreateAchievementsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of metrics to create. Maximum 100 metrics per request.",
+ "description": "Array of achievements to create. Maximum 100 achievements per request.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateMetricsRequest"
+ "$ref": "#/components/schemas/CreateAchievementsRequest"
},
"examples": {
- "Create number and currency metrics": {
+ "Create metric and API achievements": {
"value": [
{
- "name": "Invites Sent",
- "key": "invites-sent"
+ "name": "First Workout",
+ "trigger": "metric",
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1
},
{
- "name": "Revenue",
- "key": "revenue",
- "unitType": "currency",
- "units": "USD"
+ "name": "Custom Unlock",
+ "trigger": "api",
+ "key": "custom-unlock"
}
]
}
@@ -820,11 +829,11 @@
},
"responses": {
"200": {
- "description": "Successful operation (no metrics created)",
+ "description": "Successful operation (no achievements created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateMetricsResponse"
+ "$ref": "#/components/schemas/CreateAchievementsResponse"
},
"examples": {
"All requests had errors": {
@@ -839,7 +848,7 @@
{
"index": 1,
"severity": "error",
- "message": "Key already in use by another metric"
+ "message": "metricId is required for metric achievements"
}
]
}
@@ -849,11 +858,11 @@
}
},
"201": {
- "description": "Created (at least one metric created)",
+ "description": "Created (at least one achievement created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateMetricsResponse"
+ "$ref": "#/components/schemas/CreateAchievementsResponse"
},
"examples": {
"Success with no issues": {
@@ -861,17 +870,25 @@
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Invites Sent",
- "key": "invites-sent",
- "unitType": "number",
- "units": ""
+ "name": "First Workout",
+ "description": null,
+ "trigger": "metric",
+ "status": "inactive",
+ "badge": null,
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1,
+ "eventAttributes": []
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Revenue",
- "key": "revenue",
- "unitType": "currency",
- "units": "USD"
+ "name": "Custom Unlock",
+ "description": null,
+ "trigger": "api",
+ "status": "inactive",
+ "badge": null,
+ "userAttributes": [],
+ "key": "custom-unlock"
}
],
"issues": []
@@ -882,17 +899,20 @@
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440002",
- "name": "Signups",
- "key": "signups",
- "unitType": "number",
- "units": ""
+ "name": "Week Warrior",
+ "description": null,
+ "trigger": "streak",
+ "status": "inactive",
+ "badge": null,
+ "userAttributes": [],
+ "streakLength": 7
}
],
"issues": [
{
"index": 0,
"severity": "error",
- "message": "Key already in use by another metric"
+ "message": "Key already in use by another achievement"
}
]
}
@@ -922,7 +942,7 @@
}
}
},
- "summary": "Create metrics",
+ "summary": "Create achievements",
"security": [
{
"ApiKeyAuth": []
@@ -930,12 +950,12 @@
]
},
"patch": {
- "description": "Update metrics by ID.",
- "operationId": "admin_metrics_update",
+ "description": "Update achievements by ID. Maximum 100 achievements per request. Only provided fields are updated; omitted fields are preserved.",
+ "operationId": "admin_achievements_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "metrics"
+ "achievements"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -944,37 +964,32 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Invites Completed',\n units: 'invites'\n },\n {\n id: '550e8400-e29b-41d4-a716-446655440001',\n unitType: 'number',\n units: 'dollars'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.achievements.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'First Workout Completed',\n status: 'active'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Invites Completed\",\n \"units\": \"invites\"\n },\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"unitType\": \"number\",\n \"units\": \"dollars\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.achievements.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"First Workout Completed\",\n \"status\": \"active\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Update(context.TODO(), api.UpdateMetricsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Achievements.Update(context.TODO(), api.UpdateAchievementsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of metrics to update. Each item must include an ID and may include any subset of mutable metric fields except `key`.",
+ "description": "Array of achievements to update. Each item must include an ID and may include any subset of mutable achievement fields.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdateMetricsRequest"
+ "$ref": "#/components/schemas/UpdateAchievementsRequest"
},
"examples": {
- "Update metric fields": {
+ "Update achievement fields": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Invites Completed",
- "units": "invites"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "unitType": "number",
- "units": "dollars"
+ "name": "First Workout Completed",
+ "status": "active"
}
]
}
@@ -988,7 +1003,7 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdateMetricsResponse"
+ "$ref": "#/components/schemas/UpdateAchievementsResponse"
},
"examples": {
"Success with no issues": {
@@ -996,10 +1011,15 @@
"updated": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Invites Completed",
- "key": "invites-sent",
- "unitType": "number",
- "units": "invites"
+ "name": "First Workout Completed",
+ "description": null,
+ "trigger": "metric",
+ "status": "active",
+ "badge": null,
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1,
+ "eventAttributes": []
}
],
"issues": []
@@ -1009,18 +1029,23 @@
"value": {
"updated": [
{
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Revenue",
- "key": "revenue",
- "unitType": "number",
- "units": "dollars"
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "First Workout Completed",
+ "description": null,
+ "trigger": "metric",
+ "status": "active",
+ "badge": null,
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1,
+ "eventAttributes": []
}
],
"issues": [
{
"id": "550e8400-e29b-41d4-a716-446655440999",
"severity": "error",
- "message": "Metric not found by ID"
+ "message": "Achievement not found by ID"
}
]
}
@@ -1050,7 +1075,7 @@
}
}
},
- "summary": "Update metrics",
+ "summary": "Update achievements",
"security": [
{
"ApiKeyAuth": []
@@ -1058,12 +1083,12 @@
]
},
"delete": {
- "description": "Delete metrics by ID.",
- "operationId": "admin_metrics_delete",
+ "description": "Delete achievements by ID.",
+ "operationId": "admin_achievements_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "metrics"
+ "achievements"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -1072,22 +1097,22 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.achievements.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.achievements.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Achievements.Delete(context.TODO(), nil)\n"
}
],
"parameters": [
{
"name": "ids",
"in": "query",
- "description": "Metric IDs to delete. Repeat the query param or provide a comma-separated list.",
+ "description": "Achievement IDs to delete. Repeat the query param or provide a comma-separated list.",
"required": true,
"schema": {
"type": "array",
@@ -1116,7 +1141,7 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeleteMetricsResponse"
+ "$ref": "#/components/schemas/DeleteAchievementsResponse"
},
"examples": {
"Success with no issues": {
@@ -1145,7 +1170,7 @@
{
"id": "550e8400-e29b-41d4-a716-446655440999",
"severity": "error",
- "message": "Metric not found by ID"
+ "message": "Achievement not found by ID"
}
]
}
@@ -1175,7 +1200,7 @@
}
}
},
- "summary": "Delete metrics",
+ "summary": "Delete achievements",
"security": [
{
"ApiKeyAuth": []
@@ -1183,7 +1208,7 @@
]
}
},
- "/metrics/{id}": {
+ "/achievements/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -1196,12 +1221,12 @@
}
],
"get": {
- "description": "Get a metric by ID.",
- "operationId": "admin_metrics_get",
+ "description": "Get an achievement by ID.",
+ "operationId": "admin_achievements_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "metrics"
+ "achievements"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -1210,22 +1235,22 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst metric = await trophy.admin.metrics.get(\n '550e8400-e29b-41d4-a716-446655440000'\n);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst achievement = await trophy.admin.achievements.get(\n '550e8400-e29b-41d4-a716-446655440000'\n);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nmetric = client.admin.metrics.get(\n \"550e8400-e29b-41d4-a716-446655440000\"\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nachievement = client.admin.achievements.get(\n \"550e8400-e29b-41d4-a716-446655440000\"\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Achievements.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
}
],
"parameters": [
{
"name": "id",
"in": "path",
- "description": "The UUID of the metric to retrieve.",
+ "description": "The UUID of the achievement to retrieve.",
"required": true,
"schema": {
"type": "string",
@@ -1240,25 +1265,21 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatedMetric"
+ "$ref": "#/components/schemas/AdminAchievement"
},
"examples": {
- "Number metric": {
+ "Metric achievement": {
"value": {
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Invites Sent",
- "key": "invites-sent",
- "unitType": "number",
- "units": ""
- }
- },
- "Currency metric": {
- "value": {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Revenue",
- "key": "revenue",
- "unitType": "currency",
- "units": "USD"
+ "name": "First Workout",
+ "description": "Complete your first workout",
+ "trigger": "metric",
+ "status": "active",
+ "badge": null,
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricValue": 1,
+ "eventAttributes": []
}
}
}
@@ -1296,7 +1317,7 @@
}
}
},
- "summary": "Get a metric by ID",
+ "summary": "Get an achievement by ID",
"security": [
{
"ApiKeyAuth": []
@@ -1304,7 +1325,7 @@
]
}
},
- "/metrics/events": {
+ "/metrics": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -1316,60 +1337,90 @@
"$ref": "#/components/parameters/TenantId"
}
],
- "post": {
- "description": "Submit up to 1,000 metric events for asynchronous processing.\n",
- "operationId": "admin_metrics_batch_events",
+ "get": {
+ "description": "List metrics.",
+ "operationId": "admin_metrics_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"metrics"
],
- "x-fern-sdk-method-name": "batchEvents",
+ "x-fern-sdk-method-name": "list",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.batchEvents([\n {\n key: 'words-written',\n user: {\n id: 'user-id',\n email: 'user@example.com',\n tz: 'Europe/London'\n },\n value: 750,\n idempotencyKey: 'e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f',\n attributes: {\n category: 'writing'\n }\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst metrics = await trophy.admin.metrics.list({\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.batch_events(\n [\n {\n \"key\": \"words-written\",\n \"user\": {\n \"id\": \"user-id\",\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\"\n },\n \"value\": 750,\n \"idempotencyKey\": \"e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f\",\n \"attributes\": {\n \"category\": \"writing\"\n }\n }\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nmetrics = client.admin.metrics.list(\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.BatchEvents(\n context.TODO(),\n []*api.BatchMetricEvent{\n {\n Key: \"words-written\",\n User: &api.BatchMetricEventUser{Id: \"user-id\"},\n Value: 750,\n Attributes: map[string]string{\n \"category\": \"writing\",\n },\n },\n },\n)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.List(context.TODO(), nil)\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "Number of records to return.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10
+ },
+ "example": 10
+ },
+ {
+ "name": "skip",
+ "in": "query",
+ "description": "Number of records to skip from the start of the list.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "example": 0
}
],
"responses": {
- "202": {
- "description": "Events accepted into the processing queue",
+ "200": {
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/BatchEventsResponse"
+ "$ref": "#/components/schemas/ListMetricsResponse"
},
"examples": {
- "Successful operation": {
- "value": {
- "accepted": 1
- }
+ "Metrics list": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "Oldest Metric",
+ "key": "oldest-metric",
+ "unitType": "number",
+ "units": ""
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Revenue",
+ "key": "revenue",
+ "unitType": "currency",
+ "units": "USD"
+ }
+ ]
}
}
}
}
},
- "400": {
- "description": "Bad Request",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"401": {
"description": "Unauthorized",
"content": {
@@ -1380,16 +1431,6 @@
}
}
},
- "404": {
- "description": "Metric not found",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -1401,181 +1442,20 @@
}
}
},
- "summary": "Submit a batch of metric events",
+ "summary": "List metrics",
"security": [
{
"ApiKeyAuth": []
}
- ],
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "minItems": 1,
- "maxItems": 1000,
- "items": {
- "$ref": "#/components/schemas/BatchMetricEvent"
- }
- },
- "examples": {
- "Successful operation": {
- "value": [
- {
- "key": "words-written",
- "user": {
- "email": "user@example.com",
- "tz": "Europe/London",
- "id": "18",
- "attributes": {
- "department": "engineering",
- "role": "developer"
- }
- },
- "value": 750,
- "idempotencyKey": "e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f",
- "attributes": {
- "category": "writing",
- "source": "mobile-app"
- }
- }
- ]
- }
- }
- }
- }
- }
- }
- },
- "/points": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "parameters": [
- {
- "$ref": "#/components/parameters/TenantId"
- }
- ],
- "get": {
- "description": "List points systems.",
- "operationId": "admin_points_systems_list",
- "x-fern-server-name": "admin",
- "x-fern-sdk-group-name": [
- "admin",
- "points",
- "systems"
- ],
- "x-fern-sdk-method-name": "list",
- "tags": [
- "Admin"
- ],
- "x-codeSamples": [
- {
- "lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst systems = await trophy.admin.points.systems.list({\n limit: 10,\n skip: 0\n});\n"
- },
- {
- "lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsystems = client.admin.points.systems.list(\n limit=10,\n skip=0\n)\n"
- },
- {
- "lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.List(context.TODO(), nil)\n"
- }
- ],
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "description": "Number of records to return.",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 1,
- "maximum": 100,
- "default": 10
- },
- "example": 10
- },
- {
- "name": "skip",
- "in": "query",
- "description": "Number of records to skip from the start of the list.",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "example": 0
- }
- ],
- "responses": {
- "200": {
- "description": "Successful operation",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ListPointsSystemsResponse"
- },
- "examples": {
- "Systems list": {
- "value": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "XP",
- "key": "xp",
- "description": "Experience points",
- "status": "active",
- "badge": null,
- "maxPoints": null
- }
- ]
- }
- }
- }
- }
- },
- "401": {
- "description": "Unauthorized",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
- "422": {
- "description": "Unprocessible Entity",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- }
- },
- "summary": "List points systems",
- "security": [
- {
- "ApiKeyAuth": []
- }
- ]
- },
- "post": {
- "description": "Create points systems. Optionally include sub-entities (levels, boosts, triggers) in each system payload to create them alongside the system.",
- "operationId": "admin_points_systems_create",
- "x-fern-server-name": "admin",
- "x-fern-sdk-group-name": [
- "admin",
- "points",
- "systems"
+ ]
+ },
+ "post": {
+ "description": "Create metrics.",
+ "operationId": "admin_metrics_create",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "metrics"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -1584,44 +1464,37 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.create([\n {\n name: 'XP',\n key: 'xp',\n description: 'Experience points',\n levels: [\n { name: 'Bronze', key: 'bronze', points: 100 },\n { name: 'Silver', key: 'silver', points: 500 }\n ]\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.create([\n {\n name: 'Invites Sent',\n key: 'invites-sent'\n },\n {\n name: 'Revenue',\n key: 'revenue',\n unitType: 'currency',\n units: 'USD'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.create(\n request=[{\n \"name\": \"XP\",\n \"key\": \"xp\",\n \"description\": \"Experience points\",\n \"levels\": [\n {\"name\": \"Bronze\", \"key\": \"bronze\", \"points\": 100},\n {\"name\": \"Silver\", \"key\": \"silver\", \"points\": 500}\n ]\n }]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.create([\n {\n \"name\": \"Invites Sent\",\n \"key\": \"invites-sent\"\n },\n {\n \"name\": \"Revenue\",\n \"key\": \"revenue\",\n \"unitType\": \"currency\",\n \"units\": \"USD\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Create(context.TODO(), api.CreatePointsSystemsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Create(context.TODO(), api.CreateMetricsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of points systems to create. Maximum 100 systems per request.",
+ "description": "Array of metrics to create. Maximum 100 metrics per request.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsSystemsRequest"
+ "$ref": "#/components/schemas/CreateMetricsRequest"
},
"examples": {
- "Create a system with levels": {
+ "Create number and currency metrics": {
"value": [
{
- "name": "XP",
- "key": "xp",
- "description": "Experience points",
- "levels": [
- {
- "name": "Bronze",
- "key": "bronze",
- "points": 100
- },
- {
- "name": "Silver",
- "key": "silver",
- "points": 500
- }
- ]
+ "name": "Invites Sent",
+ "key": "invites-sent"
+ },
+ {
+ "name": "Revenue",
+ "key": "revenue",
+ "unitType": "currency",
+ "units": "USD"
}
]
}
@@ -1631,11 +1504,11 @@
},
"responses": {
"200": {
- "description": "Successful operation (no systems created)",
+ "description": "Successful operation (no metrics created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsSystemsResponse"
+ "$ref": "#/components/schemas/CreateMetricsResponse"
},
"examples": {
"All requests had errors": {
@@ -1645,7 +1518,12 @@
{
"index": 0,
"severity": "error",
- "message": "name must be a string"
+ "message": "Name not a string"
+ },
+ {
+ "index": 1,
+ "severity": "error",
+ "message": "Key already in use by another metric"
}
]
}
@@ -1655,11 +1533,11 @@
}
},
"201": {
- "description": "Created (at least one system created)",
+ "description": "Created (at least one metric created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsSystemsResponse"
+ "$ref": "#/components/schemas/CreateMetricsResponse"
},
"examples": {
"Success with no issues": {
@@ -1667,26 +1545,41 @@
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "XP",
- "key": "xp",
- "description": "Experience points",
- "status": "active",
- "badge": null,
- "maxPoints": null,
- "levels": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Bronze",
- "key": "bronze",
- "points": 100,
- "description": "",
- "badge": null
- }
- ]
+ "name": "Invites Sent",
+ "key": "invites-sent",
+ "unitType": "number",
+ "units": ""
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Revenue",
+ "key": "revenue",
+ "unitType": "currency",
+ "units": "USD"
}
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440002",
+ "name": "Signups",
+ "key": "signups",
+ "unitType": "number",
+ "units": ""
+ }
+ ],
+ "issues": [
+ {
+ "index": 0,
+ "severity": "error",
+ "message": "Key already in use by another metric"
+ }
+ ]
+ }
}
}
}
@@ -1713,7 +1606,7 @@
}
}
},
- "summary": "Create points systems",
+ "summary": "Create metrics",
"security": [
{
"ApiKeyAuth": []
@@ -1721,13 +1614,12 @@
]
},
"patch": {
- "description": "Update points systems by ID.",
- "operationId": "admin_points_systems_update",
+ "description": "Update metrics by ID.",
+ "operationId": "admin_metrics_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "points",
- "systems"
+ "metrics"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -1736,31 +1628,37 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.update([\n {\n id: 'system-uuid',\n name: 'New Name',\n description: 'Updated description'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Invites Completed',\n units: 'invites'\n },\n {\n id: '550e8400-e29b-41d4-a716-446655440001',\n unitType: 'number',\n units: 'dollars'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.update(\n request=[{\n \"id\": \"system-uuid\",\n \"name\": \"New Name\",\n \"description\": \"Updated description\"\n }]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Invites Completed\",\n \"units\": \"invites\"\n },\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"unitType\": \"number\",\n \"units\": \"dollars\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Update(context.TODO(), api.UpdatePointsSystemsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Update(context.TODO(), api.UpdateMetricsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of points system updates. Maximum 100 systems per request.",
+ "description": "Array of metrics to update. Each item must include an ID and may include any subset of mutable metric fields except `key`.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdatePointsSystemsRequest"
+ "$ref": "#/components/schemas/UpdateMetricsRequest"
},
"examples": {
- "Update a system name": {
+ "Update metric fields": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "New Name"
+ "name": "Invites Completed",
+ "units": "invites"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "unitType": "number",
+ "units": "dollars"
}
]
}
@@ -1774,24 +1672,42 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdatePointsSystemsResponse"
+ "$ref": "#/components/schemas/UpdateMetricsResponse"
},
"examples": {
- "Success": {
+ "Success with no issues": {
"value": {
"updated": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "New Name",
- "key": "xp",
- "description": "",
- "status": "active",
- "badge": null,
- "maxPoints": null
+ "name": "Invites Completed",
+ "key": "invites-sent",
+ "unitType": "number",
+ "units": "invites"
}
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "updated": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Revenue",
+ "key": "revenue",
+ "unitType": "number",
+ "units": "dollars"
+ }
+ ],
+ "issues": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440999",
+ "severity": "error",
+ "message": "Metric not found by ID"
+ }
+ ]
+ }
}
}
}
@@ -1818,7 +1734,7 @@
}
}
},
- "summary": "Update points systems",
+ "summary": "Update metrics",
"security": [
{
"ApiKeyAuth": []
@@ -1826,13 +1742,12 @@
]
},
"delete": {
- "description": "Delete points systems by ID.",
- "operationId": "admin_points_systems_delete",
+ "description": "Delete metrics by ID.",
+ "operationId": "admin_metrics_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "points",
- "systems"
+ "metrics"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -1841,33 +1756,42 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.delete({\n ids: ['system-uuid-1', 'system-uuid-2']\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.delete(\n ids=['system-uuid-1', 'system-uuid-2']\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Delete(context.TODO(), nil)\n"
}
],
"parameters": [
{
"name": "ids",
"in": "query",
- "description": "The IDs of the points systems to delete.",
+ "description": "Metric IDs to delete. Repeat the query param or provide a comma-separated list.",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
- }
+ },
+ "minItems": 1,
+ "maxItems": 100
},
- "example": [
- "550e8400-e29b-41d4-a716-446655440000"
- ]
+ "style": "form",
+ "explode": true,
+ "examples": {
+ "Multiple query params": {
+ "value": [
+ "550e8400-e29b-41d4-a716-446655440000",
+ "550e8400-e29b-41d4-a716-446655440001"
+ ]
+ }
+ }
}
],
"responses": {
@@ -1876,10 +1800,10 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeletePointsSystemsResponse"
+ "$ref": "#/components/schemas/DeleteMetricsResponse"
},
"examples": {
- "Success": {
+ "Success with no issues": {
"value": {
"deleted": [
{
@@ -1888,6 +1812,27 @@
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": [
+ {
+ "id": "not-a-uuid",
+ "severity": "error",
+ "message": "id must be a valid UUID"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440999",
+ "severity": "error",
+ "message": "Metric not found by ID"
+ }
+ ]
+ }
}
}
}
@@ -1914,7 +1859,7 @@
}
}
},
- "summary": "Delete points systems",
+ "summary": "Delete metrics",
"security": [
{
"ApiKeyAuth": []
@@ -1922,7 +1867,7 @@
]
}
},
- "/points/{id}": {
+ "/metrics/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -1935,13 +1880,12 @@
}
],
"get": {
- "description": "Get a points system by ID.",
- "operationId": "admin_points_systems_get",
+ "description": "Get a metric by ID.",
+ "operationId": "admin_metrics_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "points",
- "systems"
+ "metrics"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -1950,27 +1894,27 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst system = await trophy.admin.points.systems.get('system-uuid');\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst metric = await trophy.admin.metrics.get(\n '550e8400-e29b-41d4-a716-446655440000'\n);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsystem = client.admin.points.systems.get(id='system-uuid')\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nmetric = client.admin.metrics.get(\n \"550e8400-e29b-41d4-a716-446655440000\"\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
}
],
"parameters": [
{
"name": "id",
"in": "path",
+ "description": "The UUID of the metric to retrieve.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
- "description": "The ID of the points system.",
"example": "550e8400-e29b-41d4-a716-446655440000"
}
],
@@ -1980,18 +1924,25 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminPointsSystem"
+ "$ref": "#/components/schemas/CreatedMetric"
},
"examples": {
- "Points system": {
+ "Number metric": {
"value": {
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "XP",
- "key": "xp",
- "description": "Experience points",
- "status": "active",
- "badge": null,
- "maxPoints": null
+ "name": "Invites Sent",
+ "key": "invites-sent",
+ "unitType": "number",
+ "units": ""
+ }
+ },
+ "Currency metric": {
+ "value": {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Revenue",
+ "key": "revenue",
+ "unitType": "currency",
+ "units": "USD"
}
}
}
@@ -2029,7 +1980,7 @@
}
}
},
- "summary": "Get a points system by ID",
+ "summary": "Get a metric by ID",
"security": [
{
"ApiKeyAuth": []
@@ -2037,7 +1988,7 @@
]
}
},
- "/points/{systemId}/boosts": {
+ "/metrics/events": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -2049,96 +2000,60 @@
"$ref": "#/components/parameters/TenantId"
}
],
- "get": {
- "description": "List points boosts for a system.",
- "operationId": "admin_points_boosts_list",
+ "post": {
+ "description": "Submit up to 1,000 metric events for asynchronous processing.\n",
+ "operationId": "admin_metrics_batch_events",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "points",
- "boosts"
+ "metrics"
],
- "x-fern-sdk-method-name": "list",
+ "x-fern-sdk-method-name": "batchEvents",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst boosts = await trophy.admin.points.boosts.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.metrics.batchEvents([\n {\n key: 'words-written',\n user: {\n id: 'user-id',\n email: 'user@example.com',\n tz: 'Europe/London'\n },\n value: 750,\n idempotencyKey: 'e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f',\n attributes: {\n category: 'writing'\n }\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nboosts = client.admin.points.boosts.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.metrics.batch_events(\n [\n {\n \"key\": \"words-written\",\n \"user\": {\n \"id\": \"user-id\",\n \"email\": \"user@example.com\",\n \"tz\": \"Europe/London\"\n },\n \"value\": 750,\n \"idempotencyKey\": \"e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f\",\n \"attributes\": {\n \"category\": \"writing\"\n }\n }\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.List(context.TODO(), \"system-uuid\", nil)\n"
- }
- ],
- "parameters": [
- {
- "name": "systemId",
- "in": "path",
- "description": "The UUID of the points system.",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uuid"
- },
- "example": "550e8400-e29b-41d4-a716-446655440000"
- },
- {
- "name": "limit",
- "in": "query",
- "description": "Maximum number of results to return (1-100, default 10).",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 1,
- "maximum": 100,
- "default": 10
- }
- },
- {
- "name": "skip",
- "in": "query",
- "description": "Number of results to skip for pagination (default 0).",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 0,
- "default": 0
- }
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Metrics.BatchEvents(\n context.TODO(),\n []*api.BatchMetricEvent{\n {\n Key: \"words-written\",\n User: &api.BatchMetricEventUser{Id: \"user-id\"},\n Value: 750,\n Attributes: map[string]string{\n \"category\": \"writing\",\n },\n },\n },\n)\n"
}
],
"responses": {
- "200": {
- "description": "A paginated list of points boosts.",
+ "202": {
+ "description": "Events accepted into the processing queue",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ListPointsBoostsResponse"
+ "$ref": "#/components/schemas/BatchEventsResponse"
},
"examples": {
- "Boosts list": {
- "value": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Double XP Weekend",
- "status": "active",
- "start": "2024-01-01",
- "end": "2024-01-03",
- "multiplier": 2,
- "rounding": "down",
- "userId": "user-123"
- }
- ]
+ "Successful operation": {
+ "value": {
+ "accepted": 1
+ }
}
}
}
}
},
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"401": {
"description": "Unauthorized",
"content": {
@@ -2150,7 +2065,7 @@
}
},
"404": {
- "description": "Not Found (points system not found)",
+ "description": "Metric not found",
"content": {
"application/json": {
"schema": {
@@ -2170,93 +2085,225 @@
}
}
},
- "summary": "List points boosts",
+ "summary": "Submit a batch of metric events",
"security": [
{
"ApiKeyAuth": []
}
- ]
- },
- "post": {
- "description": "Create points boosts.",
- "operationId": "admin_points_boosts_create",
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 1000,
+ "items": {
+ "$ref": "#/components/schemas/BatchMetricEvent"
+ }
+ },
+ "examples": {
+ "Successful operation": {
+ "value": [
+ {
+ "key": "words-written",
+ "user": {
+ "email": "user@example.com",
+ "tz": "Europe/London",
+ "id": "18",
+ "attributes": {
+ "department": "engineering",
+ "role": "developer"
+ }
+ },
+ "value": 750,
+ "idempotencyKey": "e4296e4b-8493-4bd1-9c30-5a1a9ac4d78f",
+ "attributes": {
+ "category": "writing",
+ "source": "mobile-app"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/points": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
+ "get": {
+ "description": "List points systems.",
+ "operationId": "admin_points_systems_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "boosts"
+ "systems"
],
- "x-fern-sdk-method-name": "create",
+ "x-fern-sdk-method-name": "list",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.create('system-uuid', [\n {\n userId: 'user-123',\n name: 'Double XP Weekend',\n start: '2024-01-01',\n end: '2024-01-03',\n multiplier: 2\n },\n {\n name: 'Global Holiday Bonus',\n start: '2024-12-25',\n multiplier: 1.5,\n rounding: 'up'\n },\n {\n name: 'Premium User Boost',\n start: '2024-01-01',\n multiplier: 2,\n userAttributes: [\n { attributeId: 'attr-uuid', attributeValue: 'premium' }\n ]\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst systems = await trophy.admin.points.systems.list({\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.create(\n system_id='system-uuid',\n boosts=[\n {\n \"userId\": \"user-123\",\n \"name\": \"Double XP Weekend\",\n \"start\": \"2024-01-01\",\n \"end\": \"2024-01-03\",\n \"multiplier\": 2\n },\n {\n \"name\": \"Global Holiday Bonus\",\n \"start\": \"2024-12-25\",\n \"multiplier\": 1.5,\n \"rounding\": \"up\"\n },\n {\n \"name\": \"Premium User Boost\",\n \"start\": \"2024-01-01\",\n \"multiplier\": 2,\n \"userAttributes\": [\n {\"attributeId\": \"attr-uuid\", \"attributeValue\": \"premium\"}\n ]\n }\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsystems = client.admin.points.systems.list(\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Create(context.TODO(), \"system-uuid\", api.CreatePointsBoostsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.List(context.TODO(), nil)\n"
}
],
"parameters": [
{
- "name": "systemId",
- "in": "path",
- "description": "The UUID of the points system.",
- "required": true,
+ "name": "limit",
+ "in": "query",
+ "description": "Number of records to return.",
+ "required": false,
"schema": {
- "type": "string",
- "format": "uuid"
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10
},
- "example": "550e8400-e29b-41d4-a716-446655440000"
+ "example": 10
+ },
+ {
+ "name": "skip",
+ "in": "query",
+ "description": "Number of records to skip from the start of the list.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "example": 0
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListPointsSystemsResponse"
+ },
+ "examples": {
+ "Systems list": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "XP",
+ "key": "xp",
+ "description": "Experience points",
+ "status": "active",
+ "badge": null,
+ "maxPoints": null
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "List points systems",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "post": {
+ "description": "Create points systems. Optionally include sub-entities (levels, boosts, triggers) in each system payload to create them alongside the system.",
+ "operationId": "admin_points_systems_create",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "points",
+ "systems"
+ ],
+ "x-fern-sdk-method-name": "create",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.create([\n {\n name: 'XP',\n key: 'xp',\n description: 'Experience points',\n levels: [\n { name: 'Bronze', key: 'bronze', points: 100 },\n { name: 'Silver', key: 'silver', points: 500 }\n ]\n }\n]);\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.create(\n request=[{\n \"name\": \"XP\",\n \"key\": \"xp\",\n \"description\": \"Experience points\",\n \"levels\": [\n {\"name\": \"Bronze\", \"key\": \"bronze\", \"points\": 100},\n {\"name\": \"Silver\", \"key\": \"silver\", \"points\": 500}\n ]\n }]\n)\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Create(context.TODO(), api.CreatePointsSystemsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of boosts to create.",
+ "description": "Array of points systems to create. Maximum 100 systems per request.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsBoostsRequest"
+ "$ref": "#/components/schemas/CreatePointsSystemsRequest"
},
"examples": {
- "Create user-specific boost": {
- "value": [
- {
- "userId": "user-123",
- "name": "Double XP Weekend",
- "start": "2024-01-01",
- "end": "2024-01-03",
- "multiplier": 2
- }
- ]
- },
- "Create global boost": {
- "value": [
- {
- "name": "Global Holiday Bonus",
- "start": "2024-12-25",
- "multiplier": 1.5,
- "rounding": "up"
- }
- ]
- },
- "Create boost with user attributes": {
+ "Create a system with levels": {
"value": [
{
- "name": "Premium User Boost",
- "start": "2024-01-01",
- "multiplier": 2,
- "userAttributes": [
+ "name": "XP",
+ "key": "xp",
+ "description": "Experience points",
+ "levels": [
{
- "attributeId": "550e8400-e29b-41d4-a716-446655440000",
- "attributeValue": "premium"
+ "name": "Bronze",
+ "key": "bronze",
+ "points": 100
+ },
+ {
+ "name": "Silver",
+ "key": "silver",
+ "points": 500
}
]
}
@@ -2268,11 +2315,11 @@
},
"responses": {
"200": {
- "description": "Successful operation (no boosts created)",
+ "description": "Successful operation (no systems created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsBoostsResponse"
+ "$ref": "#/components/schemas/CreatePointsSystemsResponse"
},
"examples": {
"All requests had errors": {
@@ -2282,7 +2329,7 @@
{
"index": 0,
"severity": "error",
- "message": "User does not exist"
+ "message": "name must be a string"
}
]
}
@@ -2292,11 +2339,11 @@
}
},
"201": {
- "description": "Created (at least one boost created)",
+ "description": "Created (at least one system created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsBoostsResponse"
+ "$ref": "#/components/schemas/CreatePointsSystemsResponse"
},
"examples": {
"Success with no issues": {
@@ -2304,63 +2351,25 @@
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Double XP Weekend",
+ "name": "XP",
+ "key": "xp",
+ "description": "Experience points",
"status": "active",
- "start": "2024-01-01",
- "end": "2024-01-03",
- "multiplier": 2,
- "rounding": "down",
- "userId": "user-123"
- }
- ],
- "issues": []
- }
- },
- "Global boost created": {
- "value": {
- "created": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Global Holiday Bonus",
- "status": "active",
- "start": "2024-01-15",
- "end": null,
- "multiplier": 1.5,
- "rounding": "down",
- "userId": null,
- "userAttributes": []
- }
- ],
- "issues": []
- }
- },
- "Mixed success and errors": {
- "value": {
- "created": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "name": "Valid Boost",
- "status": "active",
- "start": "2024-01-15",
- "end": null,
- "multiplier": 1.5,
- "rounding": "down",
- "userId": null,
- "userAttributes": [
+ "badge": null,
+ "maxPoints": null,
+ "levels": [
{
- "attributeId": "550e8400-e29b-41d4-a716-446655440000",
- "attributeValue": "premium"
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Bronze",
+ "key": "bronze",
+ "points": 100,
+ "description": "",
+ "badge": null
}
]
}
],
- "issues": [
- {
- "index": 1,
- "severity": "error",
- "message": "User does not exist"
- }
- ]
+ "issues": []
}
}
}
@@ -2377,16 +2386,6 @@
}
}
},
- "404": {
- "description": "Not Found (points system not found)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -2398,7 +2397,7 @@
}
}
},
- "summary": "Create points boosts",
+ "summary": "Create points systems",
"security": [
{
"ApiKeyAuth": []
@@ -2406,13 +2405,13 @@
]
},
"patch": {
- "description": "Update multiple points boosts.",
- "operationId": "admin_points_boosts_update",
+ "description": "Update points systems by ID.",
+ "operationId": "admin_points_systems_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "boosts"
+ "systems"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -2421,45 +2420,31 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.update('system-uuid', [\n {\n id: 'boost-uuid-1',\n name: 'Updated Boost Name',\n multiplier: 3\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.update([\n {\n id: 'system-uuid',\n name: 'New Name',\n description: 'Updated description'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.update(\n system_id='system-uuid',\n boosts=[\n {\n \"id\": \"boost-uuid-1\",\n \"name\": \"Updated Boost Name\",\n \"multiplier\": 3\n }\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.update(\n request=[{\n \"id\": \"system-uuid\",\n \"name\": \"New Name\",\n \"description\": \"Updated description\"\n }]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Update(context.TODO(), \"system-uuid\", api.PatchPointsBoostsRequest{})\n"
- }
- ],
- "parameters": [
- {
- "name": "systemId",
- "in": "path",
- "description": "The UUID of the points system.",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uuid"
- },
- "example": "550e8400-e29b-41d4-a716-446655440000"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Update(context.TODO(), api.UpdatePointsSystemsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of boost patches.",
+ "description": "Array of points system updates. Maximum 100 systems per request.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsBoostsRequest"
+ "$ref": "#/components/schemas/UpdatePointsSystemsRequest"
},
"examples": {
- "Update boost names and multipliers": {
+ "Update a system name": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Updated Boost Name",
- "multiplier": 3
+ "name": "New Name"
}
]
}
@@ -2473,7 +2458,7 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsBoostsResponse"
+ "$ref": "#/components/schemas/UpdatePointsSystemsResponse"
},
"examples": {
"Success": {
@@ -2481,13 +2466,12 @@
"updated": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Updated Boost Name",
+ "name": "New Name",
+ "key": "xp",
+ "description": "",
"status": "active",
- "start": "2024-01-01",
- "end": "2024-01-03",
- "multiplier": 3,
- "rounding": "down",
- "userId": "user-123"
+ "badge": null,
+ "maxPoints": null
}
],
"issues": []
@@ -2507,16 +2491,6 @@
}
}
},
- "404": {
- "description": "Not Found (points system not found)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -2528,7 +2502,7 @@
}
}
},
- "summary": "Update multiple points boosts",
+ "summary": "Update points systems",
"security": [
{
"ApiKeyAuth": []
@@ -2536,13 +2510,13 @@
]
},
"delete": {
- "description": "Delete multiple points boosts by ID.",
- "operationId": "admin_points_boosts_delete",
+ "description": "Delete points systems by ID.",
+ "operationId": "admin_points_systems_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "boosts"
+ "systems"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -2551,43 +2525,33 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.delete('system-uuid', {\n ids: ['boost-uuid-1', 'boost-uuid-2', 'boost-uuid-3']\n});\n\nconsole.log(`Deleted ${response.deleted.length} boosts`);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.systems.delete({\n ids: ['system-uuid-1', 'system-uuid-2']\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.delete(\n system_id='system-uuid',\n ids=['boost-uuid-1', 'boost-uuid-2', 'boost-uuid-3']\n)\n\nprint(f\"Deleted {len(response.deleted)} boosts\")\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.systems.delete(\n ids=['system-uuid-1', 'system-uuid-2']\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Delete(context.TODO(), \"system-uuid\", nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Delete(context.TODO(), nil)\n"
}
],
"parameters": [
- {
- "name": "systemId",
- "in": "path",
- "description": "The UUID of the points system.",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uuid"
- },
- "example": "550e8400-e29b-41d4-a716-446655440000"
- },
{
"name": "ids",
"in": "query",
- "description": "A list of up to 100 boost IDs.",
+ "description": "The IDs of the points systems to delete.",
"required": true,
"schema": {
"type": "array",
"items": {
- "type": "string"
- },
- "minItems": 1,
- "maxItems": 100
+ "type": "string",
+ "format": "uuid"
+ }
},
- "example": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,b1ffcd00-0d1c-4ef9-cc7e-7cc0ce491b22"
+ "example": [
+ "550e8400-e29b-41d4-a716-446655440000"
+ ]
}
],
"responses": {
@@ -2596,40 +2560,18 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeletePointsBoostsResponse"
+ "$ref": "#/components/schemas/DeletePointsSystemsResponse"
},
"examples": {
- "All boosts deleted": {
+ "Success": {
"value": {
"deleted": [
{
"id": "550e8400-e29b-41d4-a716-446655440000"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440001"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440002"
}
],
"issues": []
}
- },
- "Some boosts not found": {
- "value": {
- "deleted": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000"
- }
- ],
- "issues": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "severity": "error",
- "message": "Points boost not found by ID"
- }
- ]
- }
}
}
}
@@ -2645,18 +2587,8 @@
}
}
},
- "404": {
- "description": "Not Found (points system not found)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"422": {
- "description": "Unprocessible Entity (no IDs provided or too many IDs)",
+ "description": "Unprocessible Entity",
"content": {
"application/json": {
"schema": {
@@ -2666,7 +2598,7 @@
}
}
},
- "summary": "Delete multiple points boosts",
+ "summary": "Delete points systems",
"security": [
{
"ApiKeyAuth": []
@@ -2674,7 +2606,7 @@
]
}
},
- "/points/{systemId}/boosts/{id}": {
+ "/points/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -2687,13 +2619,13 @@
}
],
"get": {
- "description": "Get a single points boost by ID.",
- "operationId": "admin_points_boosts_get",
+ "description": "Get a points system by ID.",
+ "operationId": "admin_points_systems_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "boosts"
+ "systems"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -2702,60 +2634,48 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst boost = await trophy.admin.points.boosts.get('system-uuid', 'boost-uuid');\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst system = await trophy.admin.points.systems.get('system-uuid');\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nboost = client.admin.points.boosts.get(\n system_id='system-uuid',\n boost_id='boost-uuid'\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsystem = client.admin.points.systems.get(id='system-uuid')\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Get(context.TODO(), \"system-uuid\", \"boost-uuid\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Systems.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
}
],
"parameters": [
- {
- "name": "systemId",
- "in": "path",
- "description": "The UUID of the points system.",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uuid"
- },
- "example": "550e8400-e29b-41d4-a716-446655440000"
- },
{
"name": "id",
"in": "path",
- "description": "The UUID of the points boost.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
- "example": "660f9500-f30c-42e5-b827-557766550001"
+ "description": "The ID of the points system.",
+ "example": "550e8400-e29b-41d4-a716-446655440000"
}
],
"responses": {
"200": {
- "description": "The points boost.",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminPointsBoost"
+ "$ref": "#/components/schemas/AdminPointsSystem"
},
"examples": {
- "A single boost": {
+ "Points system": {
"value": {
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Double XP Weekend",
+ "name": "XP",
+ "key": "xp",
+ "description": "Experience points",
"status": "active",
- "start": "2024-01-01",
- "end": "2024-01-03",
- "multiplier": 2,
- "rounding": "down",
- "userId": "user-123"
+ "badge": null,
+ "maxPoints": null
}
}
}
@@ -2793,7 +2713,7 @@
}
}
},
- "summary": "Get a points boost by ID",
+ "summary": "Get a points system by ID",
"security": [
{
"ApiKeyAuth": []
@@ -2801,7 +2721,7 @@
]
}
},
- "/points/{systemId}/levels": {
+ "/points/{systemId}/boosts": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -2814,13 +2734,13 @@
}
],
"get": {
- "description": "List points levels for a system.",
- "operationId": "admin_points_levels_list",
+ "description": "List points boosts for a system.",
+ "operationId": "admin_points_boosts_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "levels"
+ "boosts"
],
"x-fern-sdk-method-name": "list",
"tags": [
@@ -2829,15 +2749,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst levels = await trophy.admin.points.levels.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst boosts = await trophy.admin.points.boosts.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nlevels = client.admin.points.levels.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nboosts = client.admin.points.boosts.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.List(context.TODO(), \"system-uuid\", nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.List(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
@@ -2855,57 +2775,47 @@
{
"name": "limit",
"in": "query",
- "description": "Number of records to return.",
+ "description": "Maximum number of results to return (1-100, default 10).",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
- },
- "example": 10
+ }
},
{
"name": "skip",
"in": "query",
- "description": "Number of records to skip from the start of the list.",
+ "description": "Number of results to skip for pagination (default 0).",
"required": false,
"schema": {
"type": "integer",
"minimum": 0,
"default": 0
- },
- "example": 0
+ }
}
],
"responses": {
"200": {
- "description": "A paginated list of points levels.",
+ "description": "A paginated list of points boosts.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ListPointsLevelsResponse"
+ "$ref": "#/components/schemas/ListPointsBoostsResponse"
},
"examples": {
- "Two levels": {
+ "Boosts list": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Bronze",
- "key": "bronze",
- "points": 100,
- "description": "Starting level",
- "badge": null
- },
- {
- "id": "660f9500-f30c-42e5-b827-557766550001",
- "name": "Silver",
- "key": "silver",
- "points": 500,
- "description": "Intermediate level",
- "badge": {
- "url": "https://example.com/silver.png"
- }
+ "name": "Double XP Weekend",
+ "status": "active",
+ "start": "2024-01-01",
+ "end": "2024-01-03",
+ "multiplier": 2,
+ "rounding": "down",
+ "userId": "user-123"
}
]
}
@@ -2944,7 +2854,7 @@
}
}
},
- "summary": "List points levels",
+ "summary": "List points boosts",
"security": [
{
"ApiKeyAuth": []
@@ -2952,13 +2862,13 @@
]
},
"post": {
- "description": "Create points levels. Maximum 100 levels per request.",
- "operationId": "admin_points_levels_create",
+ "description": "Create points boosts.",
+ "operationId": "admin_points_boosts_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "levels"
+ "boosts"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -2967,15 +2877,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.create('system-uuid', [\n {\n name: 'Bronze',\n key: 'bronze',\n points: 100,\n description: 'Starting level',\n badge: { url: 'https://example.com/bronze.png' }\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.create('system-uuid', [\n {\n userId: 'user-123',\n name: 'Double XP Weekend',\n start: '2024-01-01',\n end: '2024-01-03',\n multiplier: 2\n },\n {\n name: 'Global Holiday Bonus',\n start: '2024-12-25',\n multiplier: 1.5,\n rounding: 'up'\n },\n {\n name: 'Premium User Boost',\n start: '2024-01-01',\n multiplier: 2,\n userAttributes: [\n { attributeId: 'attr-uuid', attributeValue: 'premium' }\n ]\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.create(\n system_id='system-uuid',\n request=[{\n \"name\": \"Bronze\",\n \"key\": \"bronze\",\n \"points\": 100,\n \"description\": \"Starting level\",\n \"badge\": {\"url\": \"https://example.com/bronze.png\"}\n }]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.create(\n system_id='system-uuid',\n boosts=[\n {\n \"userId\": \"user-123\",\n \"name\": \"Double XP Weekend\",\n \"start\": \"2024-01-01\",\n \"end\": \"2024-01-03\",\n \"multiplier\": 2\n },\n {\n \"name\": \"Global Holiday Bonus\",\n \"start\": \"2024-12-25\",\n \"multiplier\": 1.5,\n \"rounding\": \"up\"\n },\n {\n \"name\": \"Premium User Boost\",\n \"start\": \"2024-01-01\",\n \"multiplier\": 2,\n \"userAttributes\": [\n {\"attributeId\": \"attr-uuid\", \"attributeValue\": \"premium\"}\n ]\n }\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Create(context.TODO(), \"system-uuid\", api.CreatePointsLevelsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Create(context.TODO(), \"system-uuid\", api.CreatePointsBoostsRequest{})\n"
}
],
"parameters": [
@@ -2992,33 +2902,71 @@
}
],
"requestBody": {
- "description": "Array of levels to create. Maximum 100 levels per request.",
+ "description": "Array of boosts to create.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsLevelsRequest"
+ "$ref": "#/components/schemas/CreatePointsBoostsRequest"
+ },
+ "examples": {
+ "Create user-specific boost": {
+ "value": [
+ {
+ "userId": "user-123",
+ "name": "Double XP Weekend",
+ "start": "2024-01-01",
+ "end": "2024-01-03",
+ "multiplier": 2
+ }
+ ]
+ },
+ "Create global boost": {
+ "value": [
+ {
+ "name": "Global Holiday Bonus",
+ "start": "2024-12-25",
+ "multiplier": 1.5,
+ "rounding": "up"
+ }
+ ]
+ },
+ "Create boost with user attributes": {
+ "value": [
+ {
+ "name": "Premium User Boost",
+ "start": "2024-01-01",
+ "multiplier": 2,
+ "userAttributes": [
+ {
+ "attributeId": "550e8400-e29b-41d4-a716-446655440000",
+ "attributeValue": "premium"
+ }
+ ]
+ }
+ ]
+ }
}
}
}
},
"responses": {
"200": {
- "description": "Successful operation (no levels created)",
+ "description": "Successful operation (no boosts created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsLevelsResponse"
+ "$ref": "#/components/schemas/CreatePointsBoostsResponse"
},
"examples": {
- "No levels created": {
+ "All requests had errors": {
"value": {
"created": [],
"issues": [
{
"index": 0,
"severity": "error",
- "message": "Key already in use by another level"
+ "message": "User does not exist"
}
]
}
@@ -3028,29 +2976,76 @@
}
},
"201": {
- "description": "Created (at least one level created)",
+ "description": "Created (at least one boost created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsLevelsResponse"
+ "$ref": "#/components/schemas/CreatePointsBoostsResponse"
},
"examples": {
- "Created successfully": {
+ "Success with no issues": {
"value": {
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Bronze",
- "key": "bronze",
- "points": 100,
- "description": "Starting level",
- "badge": {
- "url": "https://example.com/bronze.png"
- }
+ "name": "Double XP Weekend",
+ "status": "active",
+ "start": "2024-01-01",
+ "end": "2024-01-03",
+ "multiplier": 2,
+ "rounding": "down",
+ "userId": "user-123"
+ }
+ ],
+ "issues": []
+ }
+ },
+ "Global boost created": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Global Holiday Bonus",
+ "status": "active",
+ "start": "2024-01-15",
+ "end": null,
+ "multiplier": 1.5,
+ "rounding": "down",
+ "userId": null,
+ "userAttributes": []
}
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Valid Boost",
+ "status": "active",
+ "start": "2024-01-15",
+ "end": null,
+ "multiplier": 1.5,
+ "rounding": "down",
+ "userId": null,
+ "userAttributes": [
+ {
+ "attributeId": "550e8400-e29b-41d4-a716-446655440000",
+ "attributeValue": "premium"
+ }
+ ]
+ }
+ ],
+ "issues": [
+ {
+ "index": 1,
+ "severity": "error",
+ "message": "User does not exist"
+ }
+ ]
+ }
}
}
}
@@ -3087,7 +3082,7 @@
}
}
},
- "summary": "Create points levels",
+ "summary": "Create points boosts",
"security": [
{
"ApiKeyAuth": []
@@ -3095,13 +3090,13 @@
]
},
"patch": {
- "description": "Update multiple points levels. Each item must include an ID. `key` cannot be changed.",
- "operationId": "admin_points_levels_update",
+ "description": "Update multiple points boosts.",
+ "operationId": "admin_points_boosts_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "levels"
+ "boosts"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -3110,15 +3105,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.update('system-uuid', [\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Bronze Tier',\n points: 150\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.update('system-uuid', [\n {\n id: 'boost-uuid-1',\n name: 'Updated Boost Name',\n multiplier: 3\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.update(\n system_id='system-uuid',\n request=[{\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Bronze Tier\",\n \"points\": 150\n }]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.update(\n system_id='system-uuid',\n boosts=[\n {\n \"id\": \"boost-uuid-1\",\n \"name\": \"Updated Boost Name\",\n \"multiplier\": 3\n }\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Update(context.TODO(), \"system-uuid\", api.PatchPointsLevelsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Update(context.TODO(), \"system-uuid\", api.PatchPointsBoostsRequest{})\n"
}
],
"parameters": [
@@ -3135,12 +3130,23 @@
}
],
"requestBody": {
- "description": "Array of level patches. Each item must include an ID.",
+ "description": "Array of boost patches.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsLevelsRequest"
+ "$ref": "#/components/schemas/PatchPointsBoostsRequest"
+ },
+ "examples": {
+ "Update boost names and multipliers": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "Updated Boost Name",
+ "multiplier": 3
+ }
+ ]
+ }
}
}
}
@@ -3151,19 +3157,21 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsLevelsResponse"
+ "$ref": "#/components/schemas/PatchPointsBoostsResponse"
},
"examples": {
- "Updated successfully": {
+ "Success": {
"value": {
"updated": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Bronze Tier",
- "key": "bronze",
- "points": 150,
- "description": "Starting level",
- "badge": null
+ "name": "Updated Boost Name",
+ "status": "active",
+ "start": "2024-01-01",
+ "end": "2024-01-03",
+ "multiplier": 3,
+ "rounding": "down",
+ "userId": "user-123"
}
],
"issues": []
@@ -3204,7 +3212,7 @@
}
}
},
- "summary": "Update multiple points levels",
+ "summary": "Update multiple points boosts",
"security": [
{
"ApiKeyAuth": []
@@ -3212,13 +3220,13 @@
]
},
"delete": {
- "description": "Delete multiple points levels by ID.",
- "operationId": "admin_points_levels_delete",
+ "description": "Delete multiple points boosts by ID.",
+ "operationId": "admin_points_boosts_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "levels"
+ "boosts"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -3227,15 +3235,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.delete('system-uuid', {\n ids: ['550e8400-e29b-41d4-a716-446655440000']\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.points.boosts.delete('system-uuid', {\n ids: ['boost-uuid-1', 'boost-uuid-2', 'boost-uuid-3']\n});\n\nconsole.log(`Deleted ${response.deleted.length} boosts`);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.delete(\n system_id='system-uuid',\n ids=['550e8400-e29b-41d4-a716-446655440000']\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.points.boosts.delete(\n system_id='system-uuid',\n ids=['boost-uuid-1', 'boost-uuid-2', 'boost-uuid-3']\n)\n\nprint(f\"Deleted {len(response.deleted)} boosts\")\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Delete(context.TODO(), \"system-uuid\", nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Delete(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
@@ -3253,17 +3261,16 @@
{
"name": "ids",
"in": "query",
- "description": "Comma-separated list of level UUIDs to delete.",
+ "description": "A list of up to 100 boost IDs.",
"required": true,
"schema": {
"type": "array",
"items": {
- "type": "string",
- "format": "uuid"
- }
+ "type": "string"
+ },
+ "minItems": 1,
+ "maxItems": 100
},
- "style": "form",
- "explode": true,
"example": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,b1ffcd00-0d1c-4ef9-cc7e-7cc0ce491b22"
}
],
@@ -3273,31 +3280,37 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeletePointsLevelsResponse"
+ "$ref": "#/components/schemas/DeletePointsBoostsResponse"
},
"examples": {
- "Deleted successfully": {
+ "All boosts deleted": {
"value": {
"deleted": [
{
- "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440002"
}
],
"issues": []
}
},
- "Partial success": {
+ "Some boosts not found": {
"value": {
"deleted": [
{
- "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
+ "id": "550e8400-e29b-41d4-a716-446655440000"
}
],
"issues": [
{
- "id": "b1ffcd00-0d1c-4ef9-cc7e-7cc0ce491b22",
+ "id": "550e8400-e29b-41d4-a716-446655440001",
"severity": "error",
- "message": "Level not found by ID"
+ "message": "Points boost not found by ID"
}
]
}
@@ -3337,7 +3350,7 @@
}
}
},
- "summary": "Delete multiple points levels",
+ "summary": "Delete multiple points boosts",
"security": [
{
"ApiKeyAuth": []
@@ -3345,7 +3358,7 @@
]
}
},
- "/points/{systemId}/levels/{id}": {
+ "/points/{systemId}/boosts/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -3358,13 +3371,13 @@
}
],
"get": {
- "description": "Get a single points level by ID.",
- "operationId": "admin_points_levels_get",
+ "description": "Get a single points boost by ID.",
+ "operationId": "admin_points_boosts_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "levels"
+ "boosts"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -3373,15 +3386,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst level = await trophy.admin.points.levels.get('system-uuid', 'level-uuid');\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst boost = await trophy.admin.points.boosts.get('system-uuid', 'boost-uuid');\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nlevel = client.admin.points.levels.get(\n system_id='system-uuid',\n level_id='level-uuid'\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nboost = client.admin.points.boosts.get(\n system_id='system-uuid',\n boost_id='boost-uuid'\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Get(context.TODO(), \"system-uuid\", \"level-uuid\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Boosts.Get(context.TODO(), \"system-uuid\", \"boost-uuid\")\n"
}
],
"parameters": [
@@ -3399,7 +3412,7 @@
{
"name": "id",
"in": "path",
- "description": "The UUID of the points level.",
+ "description": "The UUID of the points boost.",
"required": true,
"schema": {
"type": "string",
@@ -3410,23 +3423,23 @@
],
"responses": {
"200": {
- "description": "The points level.",
+ "description": "The points boost.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminPointsLevel"
+ "$ref": "#/components/schemas/AdminPointsBoost"
},
"examples": {
- "A single level": {
+ "A single boost": {
"value": {
"id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Bronze",
- "key": "bronze",
- "points": 100,
- "description": "Starting level",
- "badge": {
- "url": "https://example.com/bronze.png"
- }
+ "name": "Double XP Weekend",
+ "status": "active",
+ "start": "2024-01-01",
+ "end": "2024-01-03",
+ "multiplier": 2,
+ "rounding": "down",
+ "userId": "user-123"
}
}
}
@@ -3464,7 +3477,7 @@
}
}
},
- "summary": "Get a points level by ID",
+ "summary": "Get a points boost by ID",
"security": [
{
"ApiKeyAuth": []
@@ -3472,7 +3485,7 @@
]
}
},
- "/points/{systemId}/triggers": {
+ "/points/{systemId}/levels": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -3485,13 +3498,13 @@
}
],
"get": {
- "description": "List points triggers for a system.",
- "operationId": "admin_points_triggers_list",
+ "description": "List points levels for a system.",
+ "operationId": "admin_points_levels_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "triggers"
+ "levels"
],
"x-fern-sdk-method-name": "list",
"tags": [
@@ -3500,15 +3513,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst triggers = await trophy.admin.points.triggers.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst levels = await trophy.admin.points.levels.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntriggers = client.admin.points.triggers.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nlevels = client.admin.points.levels.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.List(context.TODO(), \"system-uuid\", nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.List(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
@@ -3526,48 +3539,57 @@
{
"name": "limit",
"in": "query",
- "description": "Maximum number of results to return (1-100, default 10).",
+ "description": "Number of records to return.",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
- }
+ },
+ "example": 10
},
{
"name": "skip",
"in": "query",
- "description": "Number of results to skip for pagination (default 0).",
+ "description": "Number of records to skip from the start of the list.",
"required": false,
"schema": {
"type": "integer",
"minimum": 0,
"default": 0
- }
+ },
+ "example": 0
}
],
"responses": {
"200": {
- "description": "A paginated list of points triggers.",
+ "description": "A paginated list of points levels.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ListPointsTriggersResponse"
+ "$ref": "#/components/schemas/ListPointsLevelsResponse"
},
"examples": {
- "Triggers list": {
+ "Two levels": {
"value": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "type": "metric",
- "points": 10,
- "status": "active",
- "userAttributes": [],
- "metricId": "660f9500-f30c-42e5-b827-557766550001",
- "metricThreshold": 5,
- "eventAttributes": [],
- "blockIfOutOfPoints": false
+ "name": "Bronze",
+ "key": "bronze",
+ "points": 100,
+ "description": "Starting level",
+ "badge": null
+ },
+ {
+ "id": "660f9500-f30c-42e5-b827-557766550001",
+ "name": "Silver",
+ "key": "silver",
+ "points": 500,
+ "description": "Intermediate level",
+ "badge": {
+ "url": "https://example.com/silver.png"
+ }
}
]
}
@@ -3606,7 +3628,7 @@
}
}
},
- "summary": "List points triggers",
+ "summary": "List points levels",
"security": [
{
"ApiKeyAuth": []
@@ -3614,13 +3636,13 @@
]
},
"post": {
- "description": "Create points triggers in bulk. Maximum 100 triggers per request.",
- "operationId": "admin_points_triggers_create",
+ "description": "Create points levels.",
+ "operationId": "admin_points_levels_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "triggers"
+ "levels"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -3629,15 +3651,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.create('system-uuid', [\n {\n type: 'metric',\n points: 10,\n metricId: 'metric-uuid',\n metricThreshold: 5\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.create('system-uuid', [\n {\n name: 'Bronze',\n key: 'bronze',\n points: 100,\n description: 'Starting level',\n badge: { url: 'https://example.com/bronze.png' }\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.create(\n system_id='system-uuid',\n request=[{\n 'type': 'metric',\n 'points': 10,\n 'metric_id': 'metric-uuid',\n 'metric_threshold': 5\n }]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.create(\n system_id='system-uuid',\n request=[{\n \"name\": \"Bronze\",\n \"key\": \"bronze\",\n \"points\": 100,\n \"description\": \"Starting level\",\n \"badge\": {\"url\": \"https://example.com/bronze.png\"}\n }]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Create(context.TODO(), \"system-uuid\", api.CreatePointsTriggersRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Create(context.TODO(), \"system-uuid\", api.CreatePointsLevelsRequest{})\n"
}
],
"parameters": [
@@ -3654,47 +3676,61 @@
}
],
"requestBody": {
+ "description": "Array of levels to create. Maximum 100 levels per request.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsTriggersRequest"
+ "$ref": "#/components/schemas/CreatePointsLevelsRequest"
}
}
}
},
"responses": {
"200": {
- "description": "Request was valid but no triggers were created (all items had issues).",
+ "description": "Successful operation (no levels created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsTriggersResponse"
+ "$ref": "#/components/schemas/CreatePointsLevelsResponse"
+ },
+ "examples": {
+ "No levels created": {
+ "value": {
+ "created": [],
+ "issues": [
+ {
+ "index": 0,
+ "severity": "error",
+ "message": "Key already in use by another level"
+ }
+ ]
+ }
+ }
}
}
}
},
"201": {
- "description": "At least one trigger was created.",
+ "description": "Created (at least one level created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreatePointsTriggersResponse"
+ "$ref": "#/components/schemas/CreatePointsLevelsResponse"
},
"examples": {
- "Created triggers": {
+ "Created successfully": {
"value": {
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "type": "metric",
- "points": 10,
- "status": "active",
- "userAttributes": [],
- "metricId": "660f9500-f30c-42e5-b827-557766550001",
- "metricThreshold": 5,
- "eventAttributes": [],
- "blockIfOutOfPoints": false
+ "name": "Bronze",
+ "key": "bronze",
+ "points": 100,
+ "description": "Starting level",
+ "badge": {
+ "url": "https://example.com/bronze.png"
+ }
}
],
"issues": []
@@ -3735,7 +3771,7 @@
}
}
},
- "summary": "Create points triggers",
+ "summary": "Create points levels",
"security": [
{
"ApiKeyAuth": []
@@ -3743,13 +3779,13 @@
]
},
"patch": {
- "description": "Update points triggers in bulk. Maximum 100 triggers per request. Only provided fields are updated; omitted fields are preserved.",
- "operationId": "admin_points_triggers_update",
+ "description": "Update multiple points levels. Each item must include an ID. `key` cannot be changed.",
+ "operationId": "admin_points_levels_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "triggers"
+ "levels"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -3758,15 +3794,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.update('system-uuid', [\n { id: 'trigger-uuid', points: 20 }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.update('system-uuid', [\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Bronze Tier',\n points: 150\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.update(\n system_id='system-uuid',\n request=[{'id': 'trigger-uuid', 'points': 20}]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.update(\n system_id='system-uuid',\n request=[{\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Bronze Tier\",\n \"points\": 150\n }]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Update(context.TODO(), \"system-uuid\", api.PatchPointsTriggersRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Update(context.TODO(), \"system-uuid\", api.PatchPointsLevelsRequest{})\n"
}
],
"parameters": [
@@ -3783,37 +3819,35 @@
}
],
"requestBody": {
+ "description": "Array of level patches. Each item must include an ID.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsTriggersRequest"
+ "$ref": "#/components/schemas/PatchPointsLevelsRequest"
}
}
}
},
"responses": {
"200": {
- "description": "Successfully processed the update request.",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/PatchPointsTriggersResponse"
+ "$ref": "#/components/schemas/PatchPointsLevelsResponse"
},
"examples": {
- "Updated triggers": {
+ "Updated successfully": {
"value": {
"updated": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "type": "metric",
- "points": 20,
- "status": "active",
- "userAttributes": [],
- "metricId": "660f9500-f30c-42e5-b827-557766550001",
- "metricThreshold": 5,
- "eventAttributes": [],
- "blockIfOutOfPoints": false
+ "name": "Bronze Tier",
+ "key": "bronze",
+ "points": 150,
+ "description": "Starting level",
+ "badge": null
}
],
"issues": []
@@ -3854,7 +3888,7 @@
}
}
},
- "summary": "Update points triggers",
+ "summary": "Update multiple points levels",
"security": [
{
"ApiKeyAuth": []
@@ -3862,13 +3896,13 @@
]
},
"delete": {
- "description": "Delete points triggers by ID. Maximum 100 trigger IDs per request.",
- "operationId": "admin_points_triggers_delete",
+ "description": "Delete multiple points levels by ID.",
+ "operationId": "admin_points_levels_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "triggers"
+ "levels"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -3877,15 +3911,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.delete('system-uuid', {\n ids: ['trigger-uuid-1', 'trigger-uuid-2']\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.levels.delete('system-uuid', {\n ids: ['550e8400-e29b-41d4-a716-446655440000']\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.delete(\n system_id='system-uuid',\n ids=['trigger-uuid-1', 'trigger-uuid-2']\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.levels.delete(\n system_id='system-uuid',\n ids=['550e8400-e29b-41d4-a716-446655440000']\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Delete(context.TODO(), \"system-uuid\", nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Delete(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
@@ -3903,7 +3937,7 @@
{
"name": "ids",
"in": "query",
- "description": "Trigger IDs to delete. Can be repeated or comma-separated.",
+ "description": "Comma-separated list of level UUIDs to delete.",
"required": true,
"schema": {
"type": "array",
@@ -3914,29 +3948,43 @@
},
"style": "form",
"explode": true,
- "example": [
- "550e8400-e29b-41d4-a716-446655440000"
- ]
+ "example": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,b1ffcd00-0d1c-4ef9-cc7e-7cc0ce491b22"
}
],
"responses": {
"200": {
- "description": "Successfully processed the delete request.",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeletePointsTriggersResponse"
+ "$ref": "#/components/schemas/DeletePointsLevelsResponse"
},
"examples": {
- "Deleted triggers": {
+ "Deleted successfully": {
"value": {
"deleted": [
{
- "id": "550e8400-e29b-41d4-a716-446655440000"
+ "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
}
],
"issues": []
}
+ },
+ "Partial success": {
+ "value": {
+ "deleted": [
+ {
+ "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
+ }
+ ],
+ "issues": [
+ {
+ "id": "b1ffcd00-0d1c-4ef9-cc7e-7cc0ce491b22",
+ "severity": "error",
+ "message": "Level not found by ID"
+ }
+ ]
+ }
}
}
}
@@ -3963,7 +4011,7 @@
}
},
"422": {
- "description": "Unprocessible Entity",
+ "description": "Unprocessible Entity (no IDs provided or too many IDs)",
"content": {
"application/json": {
"schema": {
@@ -3973,7 +4021,7 @@
}
}
},
- "summary": "Delete points triggers",
+ "summary": "Delete multiple points levels",
"security": [
{
"ApiKeyAuth": []
@@ -3981,7 +4029,7 @@
]
}
},
- "/points/{systemId}/triggers/{id}": {
+ "/points/{systemId}/levels/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -3994,13 +4042,13 @@
}
],
"get": {
- "description": "Get a single points trigger by ID.",
- "operationId": "admin_points_triggers_get",
+ "description": "Get a single points level by ID.",
+ "operationId": "admin_points_levels_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
"points",
- "triggers"
+ "levels"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -4009,15 +4057,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst trigger = await trophy.admin.points.triggers.get('system-uuid', 'trigger-uuid');\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst level = await trophy.admin.points.levels.get('system-uuid', 'level-uuid');\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntrigger = client.admin.points.triggers.get(\n system_id='system-uuid',\n id='trigger-uuid'\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nlevel = client.admin.points.levels.get(\n system_id='system-uuid',\n level_id='level-uuid'\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Get(context.TODO(), \"system-uuid\", \"trigger-uuid\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Levels.Get(context.TODO(), \"system-uuid\", \"level-uuid\")\n"
}
],
"parameters": [
@@ -4035,7 +4083,7 @@
{
"name": "id",
"in": "path",
- "description": "The UUID of the points trigger.",
+ "description": "The UUID of the points level.",
"required": true,
"schema": {
"type": "string",
@@ -4046,24 +4094,23 @@
],
"responses": {
"200": {
- "description": "The points trigger.",
+ "description": "The points level.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminPointsTrigger"
+ "$ref": "#/components/schemas/AdminPointsLevel"
},
"examples": {
- "A single trigger": {
+ "A single level": {
"value": {
"id": "550e8400-e29b-41d4-a716-446655440000",
- "type": "metric",
- "points": 10,
- "status": "active",
- "userAttributes": [],
- "metricId": "660f9500-f30c-42e5-b827-557766550001",
- "metricThreshold": 5,
- "eventAttributes": [],
- "blockIfOutOfPoints": false
+ "name": "Bronze",
+ "key": "bronze",
+ "points": 100,
+ "description": "Starting level",
+ "badge": {
+ "url": "https://example.com/bronze.png"
+ }
}
}
}
@@ -4101,7 +4148,7 @@
}
}
},
- "summary": "Get a points trigger by ID",
+ "summary": "Get a points level by ID",
"security": [
{
"ApiKeyAuth": []
@@ -4109,7 +4156,7 @@
]
}
},
- "/leaderboards": {
+ "/points/{systemId}/triggers": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -4122,12 +4169,13 @@
}
],
"get": {
- "description": "List leaderboards.",
- "operationId": "admin_leaderboards_list",
+ "description": "List points triggers for a system.",
+ "operationId": "admin_points_triggers_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "leaderboards"
+ "points",
+ "triggers"
],
"x-fern-sdk-method-name": "list",
"tags": [
@@ -4136,81 +4184,74 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst leaderboards = await trophy.admin.leaderboards.list({\n limit: 10,\n skip: 0\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst triggers = await trophy.admin.points.triggers.list('system-uuid', {\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nleaderboards = client.admin.leaderboards.list(\n limit=10,\n skip=0\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntriggers = client.admin.points.triggers.list(\n system_id='system-uuid',\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.List(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.List(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
+ {
+ "name": "systemId",
+ "in": "path",
+ "description": "The UUID of the points system.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
+ },
{
"name": "limit",
"in": "query",
- "description": "Number of records to return.",
+ "description": "Maximum number of results to return (1-100, default 10).",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
- },
- "example": 10
+ }
},
{
"name": "skip",
"in": "query",
- "description": "Number of records to skip from the start of the list.",
+ "description": "Number of results to skip for pagination (default 0).",
"required": false,
"schema": {
"type": "integer",
"minimum": 0,
"default": 0
- },
- "example": 0
+ }
}
],
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "A paginated list of points triggers.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ListLeaderboardsResponse"
+ "$ref": "#/components/schemas/ListPointsTriggersResponse"
},
"examples": {
- "Leaderboards list": {
+ "Triggers list": {
"value": [
{
- "id": "550e8400-e29b-41d4-a716-446655440100",
- "name": "Revenue Champions",
- "key": "revenue-champions",
- "description": "Ranked by monthly revenue",
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "type": "metric",
+ "points": 10,
"status": "active",
- "rankBy": "metric",
- "metricId": "550e8400-e29b-41d4-a716-446655440000",
- "maxParticipants": 100,
- "start": "2026-04-20",
- "end": "2026-05-20",
- "breakdownAttributes": [
- "550e8400-e29b-41d4-a716-446655440010"
- ],
- "runUnit": "month",
- "runInterval": 1
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440101",
- "name": "Streak Legends",
- "key": "streak-legends",
- "status": "scheduled",
- "rankBy": "streak",
- "maxParticipants": 1000,
- "start": "2026-04-27",
- "breakdownAttributes": []
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricThreshold": 5,
+ "eventAttributes": [],
+ "blockIfOutOfPoints": false
}
]
}
@@ -4228,6 +4269,16 @@
}
}
},
+ "404": {
+ "description": "Not Found (points system not found)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -4239,7 +4290,7 @@
}
}
},
- "summary": "List leaderboards",
+ "summary": "List points triggers",
"security": [
{
"ApiKeyAuth": []
@@ -4247,18 +4298,13 @@
]
},
"post": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "description": "Create leaderboards. Maximum 100 leaderboards per request.",
- "operationId": "admin_leaderboards_create",
+ "description": "Create points triggers in bulk.",
+ "operationId": "admin_points_triggers_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "leaderboards"
+ "points",
+ "triggers"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -4267,72 +4313,77 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.create([\n {\n name: 'Revenue Champions',\n key: 'revenue-champions',\n status: 'inactive',\n rankBy: 'metric',\n metricId: '550e8400-e29b-41d4-a716-446655440000',\n maxParticipants: 100,\n start: '2026-04-20'\n },\n {\n name: 'Streak Legends',\n key: 'streak-legends',\n status: 'scheduled',\n rankBy: 'streak',\n start: '2026-04-27'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.create('system-uuid', [\n {\n type: 'metric',\n points: 10,\n metricId: 'metric-uuid',\n metricThreshold: 5\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.create([\n {\n \"name\": \"Revenue Champions\",\n \"key\": \"revenue-champions\",\n \"status\": \"inactive\",\n \"rankBy\": \"metric\",\n \"metricId\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"maxParticipants\": 100,\n \"start\": \"2026-04-20\"\n },\n {\n \"name\": \"Streak Legends\",\n \"key\": \"streak-legends\",\n \"status\": \"scheduled\",\n \"rankBy\": \"streak\",\n \"start\": \"2026-04-27\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.create(\n system_id='system-uuid',\n request=[{\n 'type': 'metric',\n 'points': 10,\n 'metric_id': 'metric-uuid',\n 'metric_threshold': 5\n }]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Create(context.TODO(), api.CreateLeaderboardsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Create(context.TODO(), \"system-uuid\", api.CreatePointsTriggersRequest{})\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "systemId",
+ "in": "path",
+ "description": "The UUID of the points system.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
}
],
"requestBody": {
- "description": "Array of leaderboards to create.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateLeaderboardsRequest"
- },
- "examples": {
- "Create leaderboards": {
- "value": [
- {
- "name": "Revenue Champions",
- "key": "revenue-champions",
- "status": "inactive",
- "rankBy": "metric",
- "metricId": "550e8400-e29b-41d4-a716-446655440000",
- "maxParticipants": 100,
- "start": "2026-04-20",
- "breakdownAttributes": [
- "550e8400-e29b-41d4-a716-446655440010"
- ],
- "runUnit": "month",
- "runInterval": 1
- },
- {
- "name": "Streak Legends",
- "key": "streak-legends",
- "status": "scheduled",
- "rankBy": "streak",
- "start": "2026-04-27"
- }
- ]
- }
+ "$ref": "#/components/schemas/CreatePointsTriggersRequest"
}
}
}
},
"responses": {
"200": {
- "description": "Successful operation (no leaderboards created)",
+ "description": "Request was valid but no triggers were created (all items had issues).",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateLeaderboardsResponse"
+ "$ref": "#/components/schemas/CreatePointsTriggersResponse"
}
}
}
},
"201": {
- "description": "Created (at least one leaderboard created)",
+ "description": "At least one trigger was created.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateLeaderboardsResponse"
+ "$ref": "#/components/schemas/CreatePointsTriggersResponse"
+ },
+ "examples": {
+ "Created triggers": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "type": "metric",
+ "points": 10,
+ "status": "active",
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricThreshold": 5,
+ "eventAttributes": [],
+ "blockIfOutOfPoints": false
+ }
+ ],
+ "issues": []
+ }
+ }
}
}
}
@@ -4347,6 +4398,16 @@
}
}
},
+ "404": {
+ "description": "Not Found (points system not found)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -4358,7 +4419,7 @@
}
}
},
- "summary": "Create leaderboards",
+ "summary": "Create points triggers",
"security": [
{
"ApiKeyAuth": []
@@ -4366,18 +4427,13 @@
]
},
"patch": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "description": "Update leaderboards by ID. Updating `status` behaves the same as activating, scheduling, deactivating, or finishing a leaderboard in the dashboard.",
- "operationId": "admin_leaderboards_update",
+ "description": "Update points triggers in bulk. Maximum 100 triggers per request. Only provided fields are updated; omitted fields are preserved.",
+ "operationId": "admin_points_triggers_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "leaderboards"
+ "points",
+ "triggers"
],
"x-fern-sdk-method-name": "update",
"tags": [
@@ -4386,54 +4442,70 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440100',\n name: 'Monthly Revenue Champions',\n description: 'Ranked by monthly revenue',\n status: 'active'\n },\n {\n id: '550e8400-e29b-41d4-a716-446655440101',\n status: 'finished'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.update('system-uuid', [\n { id: 'trigger-uuid', points: 20 }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440100\",\n \"name\": \"Monthly Revenue Champions\",\n \"description\": \"Ranked by monthly revenue\",\n \"status\": \"active\"\n },\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440101\",\n \"status\": \"finished\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.update(\n system_id='system-uuid',\n request=[{'id': 'trigger-uuid', 'points': 20}]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Update(context.TODO(), api.UpdateLeaderboardsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Update(context.TODO(), \"system-uuid\", api.PatchPointsTriggersRequest{})\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "systemId",
+ "in": "path",
+ "description": "The UUID of the points system.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
}
],
"requestBody": {
- "description": "Array of leaderboards to update. Each item must include an ID.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdateLeaderboardsRequest"
- },
- "examples": {
- "Update leaderboards": {
- "value": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440100",
- "name": "Monthly Revenue Champions",
- "description": "Ranked by monthly revenue",
- "status": "active"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440101",
- "status": "finished"
- }
- ]
- }
+ "$ref": "#/components/schemas/PatchPointsTriggersRequest"
}
}
}
},
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "Successfully processed the update request.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdateLeaderboardsResponse"
- }
- }
- }
+ "$ref": "#/components/schemas/PatchPointsTriggersResponse"
+ },
+ "examples": {
+ "Updated triggers": {
+ "value": {
+ "updated": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "type": "metric",
+ "points": 20,
+ "status": "active",
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricThreshold": 5,
+ "eventAttributes": [],
+ "blockIfOutOfPoints": false
+ }
+ ],
+ "issues": []
+ }
+ }
+ }
+ }
+ }
},
"401": {
"description": "Unauthorized",
@@ -4445,6 +4517,16 @@
}
}
},
+ "404": {
+ "description": "Not Found (points system not found)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -4456,7 +4538,7 @@
}
}
},
- "summary": "Update leaderboards",
+ "summary": "Update points triggers",
"security": [
{
"ApiKeyAuth": []
@@ -4464,18 +4546,13 @@
]
},
"delete": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "description": "Delete leaderboards by ID.",
- "operationId": "admin_leaderboards_delete",
+ "description": "Delete points triggers by ID. Maximum 100 trigger IDs per request.",
+ "operationId": "admin_points_triggers_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "leaderboards"
+ "points",
+ "triggers"
],
"x-fern-sdk-method-name": "delete",
"tags": [
@@ -4484,43 +4561,67 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440100',\n '550e8400-e29b-41d4-a716-446655440101'\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst result = await trophy.admin.points.triggers.delete('system-uuid', {\n ids: ['trigger-uuid-1', 'trigger-uuid-2']\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440100',\n '550e8400-e29b-41d4-a716-446655440101'\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresult = client.admin.points.triggers.delete(\n system_id='system-uuid',\n ids=['trigger-uuid-1', 'trigger-uuid-2']\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Delete(context.TODO(), \"system-uuid\", nil)\n"
}
],
"parameters": [
+ {
+ "name": "systemId",
+ "in": "path",
+ "description": "The UUID of the points system.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
+ },
{
"name": "ids",
"in": "query",
- "description": "Leaderboard IDs to delete. Repeat the query param or provide a comma-separated list.",
+ "description": "Trigger IDs to delete. Can be repeated or comma-separated.",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
- },
- "minItems": 1,
- "maxItems": 100
+ }
},
"style": "form",
- "explode": true
+ "explode": true,
+ "example": [
+ "550e8400-e29b-41d4-a716-446655440000"
+ ]
}
],
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "Successfully processed the delete request.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeleteLeaderboardsResponse"
+ "$ref": "#/components/schemas/DeletePointsTriggersResponse"
+ },
+ "examples": {
+ "Deleted triggers": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": []
+ }
+ }
}
}
}
@@ -4535,6 +4636,16 @@
}
}
},
+ "404": {
+ "description": "Not Found (points system not found)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -4546,7 +4657,7 @@
}
}
},
- "summary": "Delete leaderboards",
+ "summary": "Delete points triggers",
"security": [
{
"ApiKeyAuth": []
@@ -4554,7 +4665,7 @@
]
}
},
- "/leaderboards/{id}": {
+ "/points/{systemId}/triggers/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -4567,12 +4678,13 @@
}
],
"get": {
- "description": "Get a leaderboard by ID.",
- "operationId": "admin_leaderboards_get",
+ "description": "Get a single points trigger by ID.",
+ "operationId": "admin_points_triggers_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "leaderboards"
+ "points",
+ "triggers"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -4581,68 +4693,61 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst leaderboard = await trophy.admin.leaderboards.get(\n '550e8400-e29b-41d4-a716-446655440100'\n);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst trigger = await trophy.admin.points.triggers.get('system-uuid', 'trigger-uuid');\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nleaderboard = client.admin.leaderboards.get(\n \"550e8400-e29b-41d4-a716-446655440100\"\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntrigger = client.admin.points.triggers.get(\n system_id='system-uuid',\n id='trigger-uuid'\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Points.Triggers.Get(context.TODO(), \"system-uuid\", \"trigger-uuid\")\n"
}
],
"parameters": [
+ {
+ "name": "systemId",
+ "in": "path",
+ "description": "The UUID of the points system.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
+ },
{
"name": "id",
"in": "path",
- "description": "The UUID of the leaderboard to retrieve.",
+ "description": "The UUID of the points trigger.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
- "example": "550e8400-e29b-41d4-a716-446655440100"
+ "example": "660f9500-f30c-42e5-b827-557766550001"
}
],
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "The points trigger.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminLeaderboard"
+ "$ref": "#/components/schemas/AdminPointsTrigger"
},
"examples": {
- "Metric leaderboard": {
- "value": {
- "id": "550e8400-e29b-41d4-a716-446655440100",
- "name": "Revenue Champions",
- "key": "revenue-champions",
- "description": "Ranked by monthly revenue",
- "status": "active",
- "rankBy": "metric",
- "metricId": "550e8400-e29b-41d4-a716-446655440000",
- "maxParticipants": 100,
- "start": "2026-04-20",
- "end": "2026-05-20",
- "breakdownAttributes": [
- "550e8400-e29b-41d4-a716-446655440010"
- ],
- "runUnit": "month",
- "runInterval": 1
- }
- },
- "Streak leaderboard": {
+ "A single trigger": {
"value": {
- "id": "550e8400-e29b-41d4-a716-446655440101",
- "name": "Streak Legends",
- "key": "streak-legends",
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "type": "metric",
+ "points": 10,
"status": "active",
- "rankBy": "streak",
- "maxParticipants": 1000,
- "start": "2026-04-27",
- "breakdownAttributes": []
+ "userAttributes": [],
+ "metricId": "660f9500-f30c-42e5-b827-557766550001",
+ "metricThreshold": 5,
+ "eventAttributes": [],
+ "blockIfOutOfPoints": false
}
}
}
@@ -4660,7 +4765,7 @@
}
},
"404": {
- "description": "Leaderboard Not Found",
+ "description": "Not Found",
"content": {
"application/json": {
"schema": {
@@ -4680,7 +4785,7 @@
}
}
},
- "summary": "Get a leaderboard",
+ "summary": "Get a points trigger by ID",
"security": [
{
"ApiKeyAuth": []
@@ -4688,7 +4793,7 @@
]
}
},
- "/streaks/freezes": {
+ "/leaderboards": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
@@ -4700,139 +4805,103 @@
"$ref": "#/components/parameters/TenantId"
}
],
- "post": {
- "description": "Create streak freezes for multiple users.",
- "operationId": "admin_streaks_freezes_create",
+ "get": {
+ "description": "List leaderboards.",
+ "operationId": "admin_leaderboards_list",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "streaks",
- "freezes"
+ "leaderboards"
],
- "x-fern-sdk-method-name": "create",
+ "x-fern-sdk-method-name": "list",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.freezes.create({\n freezes: [\n { userId: 'user-123' },\n { userId: 'user-456' },\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst leaderboards = await trophy.admin.leaderboards.list({\n limit: 10,\n skip: 0\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.freezes.create({\n \"freezes\": [\n {\"userId\": \"user-123\"},\n {\"userId\": \"user-456\"}\n ]\n})\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nleaderboards = client.admin.leaderboards.list(\n limit=10,\n skip=0\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Freezes.Create(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.List(context.TODO(), nil)\n"
}
],
- "requestBody": {
- "description": "Array of freezes to create",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/CreateStreakFreezesRequest"
- },
- "examples": {
- "Create freezes for multiple users": {
- "value": {
- "freezes": [
- {
- "userId": "user-123"
- },
- {
- "userId": "user-456"
- },
- {
- "userId": "user-123"
- }
- ]
- }
- }
- }
- }
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "Number of records to return.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10
+ },
+ "example": 10
+ },
+ {
+ "name": "skip",
+ "in": "query",
+ "description": "Number of records to skip from the start of the list.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "example": 0
}
- },
+ ],
"responses": {
"200": {
- "description": "Successful operation (no freezes created)",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateStreakFreezesResponse"
+ "$ref": "#/components/schemas/ListLeaderboardsResponse"
},
"examples": {
- "Success with warnings": {
- "value": {
- "issues": [
- {
- "userId": "user-789",
- "severity": "warning",
- "message": "Would exceed maximum freeze limit"
- }
- ]
- }
- },
- "Mixed success and errors": {
- "value": {
- "issues": [
- {
- "userId": "non-existent-user",
- "severity": "error",
- "message": "User does not exist"
- },
- {
- "userId": "user-456",
- "severity": "warning",
- "message": "Would exceed maximum freeze limit"
- }
- ]
- }
- }
- }
- }
- }
- },
- "201": {
- "description": "Created (at least one freeze created)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/CreateStreakFreezesResponse"
- },
- "examples": {
- "Success with no issues": {
- "value": {
- "issues": []
- }
- },
- "Mixed success and warnings": {
- "value": {
- "issues": [
- {
- "userId": "user-456",
- "severity": "warning",
- "message": "Would exceed maximum freeze limit"
- }
- ]
- }
+ "Leaderboards list": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440100",
+ "name": "Revenue Champions",
+ "key": "revenue-champions",
+ "description": "Ranked by monthly revenue",
+ "status": "active",
+ "rankBy": "metric",
+ "metricId": "550e8400-e29b-41d4-a716-446655440000",
+ "maxParticipants": 100,
+ "start": "2026-04-20",
+ "end": "2026-05-20",
+ "breakdownAttributes": [
+ "550e8400-e29b-41d4-a716-446655440010"
+ ],
+ "runUnit": "month",
+ "runInterval": 1
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440101",
+ "name": "Streak Legends",
+ "key": "streak-legends",
+ "status": "scheduled",
+ "rankBy": "streak",
+ "maxParticipants": 1000,
+ "start": "2026-04-27",
+ "breakdownAttributes": []
+ }
+ ]
}
}
}
}
},
- "400": {
- "description": "Bad Request",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"401": {
"description": "Unauthorized",
"content": {
@@ -4854,34 +4923,26 @@
}
}
},
- "summary": "Create streak freezes for multiple users",
+ "summary": "List leaderboards",
"security": [
{
"ApiKeyAuth": []
}
]
- }
- },
- "/streaks/pauses": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "parameters": [
- {
- "$ref": "#/components/parameters/TenantId"
- }
- ],
+ },
"post": {
- "description": "Create streak pauses for multiple users. A pause covers a specific date range and maintains the user's streak length during that range instead of ending the streak. Start dates in the past are rejected.",
- "operationId": "admin_streaks_pauses_create",
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "description": "Create leaderboards.",
+ "operationId": "admin_leaderboards_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "streaks",
- "pauses"
+ "leaderboards"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -4890,41 +4951,50 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.pauses.create({\n pauses: [\n { userId: 'user-123', start: '2026-08-20', end: '2026-08-27' },\n { userId: 'user-456', start: '2026-09-01', end: '2026-09-07' },\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.create([\n {\n name: 'Revenue Champions',\n key: 'revenue-champions',\n status: 'inactive',\n rankBy: 'metric',\n metricId: '550e8400-e29b-41d4-a716-446655440000',\n maxParticipants: 100,\n start: '2026-04-20'\n },\n {\n name: 'Streak Legends',\n key: 'streak-legends',\n status: 'scheduled',\n rankBy: 'streak',\n start: '2026-04-27'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.pauses.create({\n \"pauses\": [\n {\"userId\": \"user-123\", \"start\": \"2026-08-20\", \"end\": \"2026-08-27\"},\n {\"userId\": \"user-456\", \"start\": \"2026-09-01\", \"end\": \"2026-09-07\"}\n ]\n})\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.create([\n {\n \"name\": \"Revenue Champions\",\n \"key\": \"revenue-champions\",\n \"status\": \"inactive\",\n \"rankBy\": \"metric\",\n \"metricId\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"maxParticipants\": 100,\n \"start\": \"2026-04-20\"\n },\n {\n \"name\": \"Streak Legends\",\n \"key\": \"streak-legends\",\n \"status\": \"scheduled\",\n \"rankBy\": \"streak\",\n \"start\": \"2026-04-27\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Pauses.Create(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Create(context.TODO(), api.CreateLeaderboardsRequest{})\n"
}
],
"requestBody": {
- "description": "Array of pauses to create",
+ "description": "Array of leaderboards to create.",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateStreakPausesRequest"
+ "$ref": "#/components/schemas/CreateLeaderboardsRequest"
},
"examples": {
- "Create pauses for multiple users": {
- "value": {
- "pauses": [
- {
- "userId": "user-123",
- "start": "2026-08-20",
- "end": "2026-08-27"
- },
- {
- "userId": "user-456",
- "start": "2026-09-01",
- "end": "2026-09-07"
- }
- ]
- }
+ "Create leaderboards": {
+ "value": [
+ {
+ "name": "Revenue Champions",
+ "key": "revenue-champions",
+ "status": "inactive",
+ "rankBy": "metric",
+ "metricId": "550e8400-e29b-41d4-a716-446655440000",
+ "maxParticipants": 100,
+ "start": "2026-04-20",
+ "breakdownAttributes": [
+ "550e8400-e29b-41d4-a716-446655440010"
+ ],
+ "runUnit": "month",
+ "runInterval": 1
+ },
+ {
+ "name": "Streak Legends",
+ "key": "streak-legends",
+ "status": "scheduled",
+ "rankBy": "streak",
+ "start": "2026-04-27"
+ }
+ ]
}
}
}
@@ -4932,71 +5002,21 @@
},
"responses": {
"200": {
- "description": "Successful operation (no pauses created)",
+ "description": "Successful operation (no leaderboards created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateStreakPausesResponse"
- },
- "examples": {
- "Mixed success and errors": {
- "value": {
- "created": [],
- "issues": [
- {
- "userId": "non-existent-user",
- "severity": "error",
- "message": "User does not exist"
- }
- ]
- }
- }
+ "$ref": "#/components/schemas/CreateLeaderboardsResponse"
}
}
}
},
"201": {
- "description": "Created (at least one pause created)",
+ "description": "Created (at least one leaderboard created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateStreakPausesResponse"
- },
- "examples": {
- "Success with no issues": {
- "value": {
- "created": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "userId": "user-123",
- "start": "2026-08-20",
- "end": "2026-08-27",
- "status": "active"
- }
- ],
- "issues": []
- }
- },
- "Mixed success and errors": {
- "value": {
- "created": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "userId": "user-123",
- "start": "2026-08-20",
- "end": "2026-08-27",
- "status": "active"
- }
- ],
- "issues": [
- {
- "userId": "non-existent-user",
- "severity": "error",
- "message": "User does not exist"
- }
- ]
- }
- }
+ "$ref": "#/components/schemas/CreateLeaderboardsResponse"
}
}
}
@@ -5022,107 +5042,79 @@
}
}
},
- "summary": "Create streak pauses for multiple users",
+ "summary": "Create leaderboards",
"security": [
{
"ApiKeyAuth": []
}
]
},
- "delete": {
- "description": "Delete streak pauses by ID.",
- "operationId": "admin_streaks_pauses_delete",
+ "patch": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "description": "Update leaderboards by ID. Updating `status` behaves the same as activating, scheduling, deactivating, or finishing a leaderboard in the dashboard.",
+ "operationId": "admin_leaderboards_update",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "streaks",
- "pauses"
+ "leaderboards"
],
- "x-fern-sdk-method-name": "delete",
+ "x-fern-sdk-method-name": "update",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.pauses.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440100',\n name: 'Monthly Revenue Champions',\n description: 'Ranked by monthly revenue',\n status: 'active'\n },\n {\n id: '550e8400-e29b-41d4-a716-446655440101',\n status: 'finished'\n }\n]);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.pauses.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440100\",\n \"name\": \"Monthly Revenue Champions\",\n \"description\": \"Ranked by monthly revenue\",\n \"status\": \"active\"\n },\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440101\",\n \"status\": \"finished\"\n }\n])\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Pauses.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Update(context.TODO(), api.UpdateLeaderboardsRequest{})\n"
}
],
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "description": "Streak pause IDs to delete. Repeat the query param or provide a comma-separated list.",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "type": "string",
- "format": "uuid"
+ "requestBody": {
+ "description": "Array of leaderboards to update. Each item must include an ID.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateLeaderboardsRequest"
},
- "minItems": 1,
- "maxItems": 100
- },
- "style": "form",
- "explode": true,
- "examples": {
- "Multiple query params": {
- "value": [
- "550e8400-e29b-41d4-a716-446655440000",
- "550e8400-e29b-41d4-a716-446655440001"
- ]
+ "examples": {
+ "Update leaderboards": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440100",
+ "name": "Monthly Revenue Champions",
+ "description": "Ranked by monthly revenue",
+ "status": "active"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440101",
+ "status": "finished"
+ }
+ ]
+ }
}
}
}
- ],
+ },
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeleteStreakPausesResponse"
- },
- "examples": {
- "Success with no issues": {
- "value": {
- "deleted": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000"
- }
- ],
- "issues": []
- }
- },
- "Mixed success and errors": {
- "value": {
- "deleted": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000"
- }
- ],
- "issues": [
- {
- "id": "not-a-uuid",
- "severity": "error",
- "message": "id must be a valid UUID"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440999",
- "severity": "error",
- "message": "Streak pause not found by ID"
- }
- ]
- }
- }
+ "$ref": "#/components/schemas/UpdateLeaderboardsResponse"
}
}
}
@@ -5148,160 +5140,71 @@
}
}
},
- "summary": "Delete streak pauses",
+ "summary": "Update leaderboards",
"security": [
{
"ApiKeyAuth": []
}
]
- }
- },
- "/streaks/restore": {
- "servers": [
- {
- "url": "https://admin.trophy.so/v1",
- "description": "Admin API"
- }
- ],
- "parameters": [
- {
- "$ref": "#/components/parameters/TenantId"
- }
- ],
- "post": {
- "description": "Restore streaks for multiple users to the maximum previously achieved streak length found within the current restore window: the last 90 days for daily streaks, weekly periods starting with the week containing the start of the current calendar year for weekly streaks, and monthly periods starting at the beginning of the previous calendar year for monthly streaks.",
- "operationId": "admin_streaks_restore",
+ },
+ "delete": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "description": "Delete leaderboards by ID.",
+ "operationId": "admin_leaderboards_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "streaks"
+ "leaderboards"
],
- "x-fern-sdk-method-name": "restore",
+ "x-fern-sdk-method-name": "delete",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.restore({\n users: [{ id: 'user-123' }, { id: 'user-456' }]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.leaderboards.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440100',\n '550e8400-e29b-41d4-a716-446655440101'\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.restore({\n \"users\": [{\"id\": \"user-123\"}, {\"id\": \"user-456\"}]\n})\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.leaderboards.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440100',\n '550e8400-e29b-41d4-a716-446655440101'\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Restore(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Delete(context.TODO(), nil)\n"
}
],
- "requestBody": {
- "description": "Array of users to restore streaks for",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RestoreStreaksRequest"
+ "parameters": [
+ {
+ "name": "ids",
+ "in": "query",
+ "description": "Leaderboard IDs to delete. Repeat the query param or provide a comma-separated list.",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
},
- "examples": {
- "Restore streaks for multiple users": {
- "value": {
- "users": [
- {
- "id": "user-123"
- },
- {
- "id": "user-456"
- }
- ]
- }
- }
- }
- }
+ "minItems": 1,
+ "maxItems": 100
+ },
+ "style": "form",
+ "explode": true
}
- },
+ ],
"responses": {
"200": {
- "description": "Successful operation (no streaks restored)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RestoreStreaksResponse"
- },
- "examples": {
- "Success with warnings": {
- "value": {
- "restoredUsers": [],
- "issues": [
- {
- "userId": "user-123",
- "severity": "warning",
- "message": "No streak to restore"
- }
- ]
- }
- },
- "Mixed success and errors": {
- "value": {
- "restoredUsers": [],
- "issues": [
- {
- "userId": "non-existent-user",
- "severity": "error",
- "message": "User does not exist"
- },
- {
- "userId": "user-789",
- "severity": "warning",
- "message": "No streak to restore"
- }
- ]
- }
- }
- }
- }
- }
- },
- "201": {
- "description": "Created (at least one streak restored)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RestoreStreaksResponse"
- },
- "examples": {
- "Success with no issues": {
- "value": {
- "restoredUsers": [
- "user-123",
- "user-456"
- ],
- "issues": []
- }
- },
- "Mixed success and errors": {
- "value": {
- "restoredUsers": [
- "user-123"
- ],
- "issues": [
- {
- "userId": "non-existent-user",
- "severity": "error",
- "message": "User does not exist"
- }
- ]
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad Request",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
+ "$ref": "#/components/schemas/DeleteLeaderboardsResponse"
}
}
}
@@ -5327,7 +5230,7 @@
}
}
},
- "summary": "Restore streaks for multiple users",
+ "summary": "Delete leaderboards",
"security": [
{
"ApiKeyAuth": []
@@ -5335,92 +5238,95 @@
]
}
},
- "/application-api-keys": {
+ "/leaderboards/{id}": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
"description": "Admin API"
}
],
- "post": {
- "description": "Create application API keys scoped to specific users. Each key can only perform operations on behalf of the user it was created for.",
- "operationId": "admin_application_api_keys_create",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
+ "get": {
+ "description": "Get a leaderboard by ID.",
+ "operationId": "admin_leaderboards_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "applicationApiKeys"
+ "leaderboards"
],
- "x-fern-sdk-method-name": "create",
+ "x-fern-sdk-method-name": "get",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.applicationApiKeys.create([\n { userId: 'user_123' }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst leaderboard = await trophy.admin.leaderboards.get(\n '550e8400-e29b-41d4-a716-446655440100'\n);\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.applicationApiKeys.create([\n { \"userId\": \"user_123\" }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nleaderboard = client.admin.leaderboards.get(\n \"550e8400-e29b-41d4-a716-446655440100\"\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.ApplicationApiKeys.Create(context.TODO(), api.CreateApplicationKeysRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Leaderboards.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
}
],
- "requestBody": {
- "description": "Array of users to create application API keys for. Maximum 100 users per request.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/CreateApplicationKeysRequest"
- },
- "examples": {
- "Create application keys": {
- "value": [
- {
- "userId": "user_123"
- },
- {
- "userId": "user_456"
- }
- ]
- }
- }
- }
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "The UUID of the leaderboard to retrieve.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440100"
}
- },
+ ],
"responses": {
"200": {
- "description": "Successful operation (no keys created)",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/CreateApplicationKeysResponse"
- }
- }
- }
- },
- "201": {
- "description": "Created (at least one application API key created)",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateApplicationKeysResponse"
+ "$ref": "#/components/schemas/AdminLeaderboard"
},
"examples": {
- "Success": {
+ "Metric leaderboard": {
"value": {
- "created": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "userId": "user_123",
- "key": "app_XXXXX.YOUR_API_KEY",
- "prefix": "app_XXXXX"
- }
+ "id": "550e8400-e29b-41d4-a716-446655440100",
+ "name": "Revenue Champions",
+ "key": "revenue-champions",
+ "description": "Ranked by monthly revenue",
+ "status": "active",
+ "rankBy": "metric",
+ "metricId": "550e8400-e29b-41d4-a716-446655440000",
+ "maxParticipants": 100,
+ "start": "2026-04-20",
+ "end": "2026-05-20",
+ "breakdownAttributes": [
+ "550e8400-e29b-41d4-a716-446655440010"
],
- "issues": []
+ "runUnit": "month",
+ "runInterval": 1
+ }
+ },
+ "Streak leaderboard": {
+ "value": {
+ "id": "550e8400-e29b-41d4-a716-446655440101",
+ "name": "Streak Legends",
+ "key": "streak-legends",
+ "status": "active",
+ "rankBy": "streak",
+ "maxParticipants": 1000,
+ "start": "2026-04-27",
+ "breakdownAttributes": []
}
}
}
@@ -5437,8 +5343,8 @@
}
}
},
- "403": {
- "description": "Forbidden",
+ "404": {
+ "description": "Leaderboard Not Found",
"content": {
"application/json": {
"schema": {
@@ -5458,101 +5364,141 @@
}
}
},
- "summary": "Create application API keys for users",
+ "summary": "Get a leaderboard by ID",
"security": [
{
"ApiKeyAuth": []
}
]
- },
- "delete": {
- "description": "Delete application API keys by ID.",
- "operationId": "admin_application_api_keys_delete",
+ }
+ },
+ "/streaks/freezes": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
+ "post": {
+ "description": "Create streak freezes for multiple users.",
+ "operationId": "admin_streaks_freezes_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "applicationApiKeys"
+ "streaks",
+ "freezes"
],
- "x-fern-sdk-method-name": "delete",
+ "x-fern-sdk-method-name": "create",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.applicationApiKeys.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.freezes.create({\n freezes: [\n { userId: 'user-123' },\n { userId: 'user-456' },\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.applicationApiKeys.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.freezes.create({\n \"freezes\": [\n {\"userId\": \"user-123\"},\n {\"userId\": \"user-456\"}\n ]\n})\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.ApplicationApiKeys.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Freezes.Create(context.TODO(), nil)\n"
}
],
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "description": "Application API key IDs (UUIDs returned at creation time). Repeat the query param or provide a comma-separated list. Maximum 100 IDs per request.",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "type": "string",
- "format": "uuid"
- },
- "maxItems": 100
- },
- "style": "form",
- "explode": true,
- "examples": {
- "Single ID": {
- "value": [
- "550e8400-e29b-41d4-a716-446655440000"
- ]
+ "requestBody": {
+ "description": "Array of freezes to create",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateStreakFreezesRequest"
},
- "Multiple IDs": {
- "value": [
- "550e8400-e29b-41d4-a716-446655440000",
- "550e8400-e29b-41d4-a716-446655440001"
- ]
+ "examples": {
+ "Create freezes for multiple users": {
+ "value": {
+ "freezes": [
+ {
+ "userId": "user-123"
+ },
+ {
+ "userId": "user-456"
+ },
+ {
+ "userId": "user-123"
+ }
+ ]
+ }
+ }
}
}
}
- ],
+ },
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "Successful operation (no freezes created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeleteApplicationKeysResponse"
+ "$ref": "#/components/schemas/CreateStreakFreezesResponse"
},
"examples": {
- "Success": {
+ "Success with warnings": {
"value": {
- "deleted": [
+ "issues": [
{
- "id": "550e8400-e29b-41d4-a716-446655440000"
+ "userId": "user-789",
+ "severity": "warning",
+ "message": "Would exceed maximum freeze limit"
}
- ],
- "issues": []
+ ]
}
},
- "Partial success": {
+ "Mixed success and errors": {
"value": {
- "deleted": [
+ "issues": [
{
- "id": "550e8400-e29b-41d4-a716-446655440000"
+ "userId": "non-existent-user",
+ "severity": "error",
+ "message": "User does not exist"
+ },
+ {
+ "userId": "user-456",
+ "severity": "warning",
+ "message": "Would exceed maximum freeze limit"
}
- ],
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created (at least one freeze created)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateStreakFreezesResponse"
+ },
+ "examples": {
+ "Success with no issues": {
+ "value": {
+ "issues": []
+ }
+ },
+ "Mixed success and warnings": {
+ "value": {
"issues": [
{
- "id": "550e8400-e29b-41d4-a716-446655440999",
- "severity": "error",
- "message": "Application API key not found by ID"
+ "userId": "user-456",
+ "severity": "warning",
+ "message": "Would exceed maximum freeze limit"
}
]
}
@@ -5561,8 +5507,8 @@
}
}
},
- "401": {
- "description": "Unauthorized",
+ "400": {
+ "description": "Bad Request",
"content": {
"application/json": {
"schema": {
@@ -5571,8 +5517,8 @@
}
}
},
- "403": {
- "description": "Forbidden",
+ "401": {
+ "description": "Unauthorized",
"content": {
"application/json": {
"schema": {
@@ -5592,7 +5538,7 @@
}
}
},
- "summary": "Delete application API keys",
+ "summary": "Create streak freezes for multiple users",
"security": [
{
"ApiKeyAuth": []
@@ -5600,134 +5546,26 @@
]
}
},
- "/tenants": {
+ "/streaks/pauses": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
"description": "Admin API"
}
],
- "get": {
- "description": "List tenants in the current environment.",
- "operationId": "admin_tenants_list",
- "x-fern-server-name": "admin",
- "x-fern-sdk-group-name": [
- "admin",
- "tenants"
- ],
- "x-fern-sdk-method-name": "list",
- "tags": [
- "Admin"
- ],
- "x-codeSamples": [
- {
- "lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst tenants = await trophy.admin.tenants.list({\n limit: 10,\n skip: 0\n});\n"
- },
- {
- "lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntenants = client.admin.tenants.list(\n limit=10,\n skip=0\n)\n"
- },
- {
- "lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.List(context.TODO(), nil)\n"
- }
- ],
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "description": "Number of records to return.",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 1,
- "maximum": 100,
- "default": 10
- },
- "example": 10
- },
- {
- "name": "skip",
- "in": "query",
- "description": "Number of records to skip from the start of the list.",
- "required": false,
- "schema": {
- "type": "integer",
- "minimum": 0,
- "default": 0
- },
- "example": 0
- }
- ],
- "responses": {
- "200": {
- "description": "Successful operation",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ListTenantsResponse"
- },
- "examples": {
- "Tenants list": {
- "value": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "customerId": "customer_12345",
- "name": "Acme Corp",
- "status": "active",
- "created": "2026-01-15T09:30:00.000Z",
- "updated": "2026-01-15T09:30:00.000Z"
- },
- {
- "id": "550e8400-e29b-41d4-a716-446655440001",
- "customerId": "customer_67890",
- "name": "Globex Inc",
- "status": "active",
- "created": "2026-02-20T14:00:00.000Z",
- "updated": "2026-02-20T14:00:00.000Z"
- }
- ]
- }
- }
- }
- }
- },
- "401": {
- "description": "Unauthorized",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
- "422": {
- "description": "Unprocessible Entity",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- }
- },
- "summary": "List tenants",
- "security": [
- {
- "ApiKeyAuth": []
- }
- ]
- },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
"post": {
- "description": "Create tenants.",
- "operationId": "admin_tenants_create",
+ "description": "Create streak pauses for multiple users. A pause covers a specific date range and maintains the user's streak length during that range instead of ending the streak. Start dates in the past are rejected.",
+ "operationId": "admin_streaks_pauses_create",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "tenants"
+ "streaks",
+ "pauses"
],
"x-fern-sdk-method-name": "create",
"tags": [
@@ -5736,37 +5574,41 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.create([\n {\n customerId: 'customer_12345',\n name: 'Acme Corp'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.pauses.create({\n pauses: [\n { userId: 'user-123', start: '2026-08-20', end: '2026-08-27' },\n { userId: 'user-456', start: '2026-09-01', end: '2026-09-07' },\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.create([\n {\n \"customerId\": \"customer_12345\",\n \"name\": \"Acme Corp\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.pauses.create({\n \"pauses\": [\n {\"userId\": \"user-123\", \"start\": \"2026-08-20\", \"end\": \"2026-08-27\"},\n {\"userId\": \"user-456\", \"start\": \"2026-09-01\", \"end\": \"2026-09-07\"}\n ]\n})\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Create(context.TODO(), api.CreateTenantsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Pauses.Create(context.TODO(), nil)\n"
}
],
"requestBody": {
- "description": "Array of tenants to create. Maximum 100 tenants per request.",
+ "description": "Array of pauses to create",
"required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateTenantsRequest"
+ "$ref": "#/components/schemas/CreateStreakPausesRequest"
},
"examples": {
- "Create tenants": {
- "value": [
- {
- "customerId": "customer_12345",
- "name": "Acme Corp"
- },
- {
- "customerId": "customer_67890",
- "name": "Globex Inc"
- }
- ]
+ "Create pauses for multiple users": {
+ "value": {
+ "pauses": [
+ {
+ "userId": "user-123",
+ "start": "2026-08-20",
+ "end": "2026-08-27"
+ },
+ {
+ "userId": "user-456",
+ "start": "2026-09-01",
+ "end": "2026-09-07"
+ }
+ ]
+ }
}
}
}
@@ -5774,21 +5616,21 @@
},
"responses": {
"200": {
- "description": "Successful operation (no tenants created)",
+ "description": "Successful operation (no pauses created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateTenantsResponse"
+ "$ref": "#/components/schemas/CreateStreakPausesResponse"
},
"examples": {
- "All requests had errors": {
+ "Mixed success and errors": {
"value": {
"created": [],
"issues": [
{
- "index": 0,
+ "userId": "non-existent-user",
"severity": "error",
- "message": "Customer ID \"customer_12345\" already exists in this environment"
+ "message": "User does not exist"
}
]
}
@@ -5798,11 +5640,11 @@
}
},
"201": {
- "description": "Created (at least one tenant created)",
+ "description": "Created (at least one pause created)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/CreateTenantsResponse"
+ "$ref": "#/components/schemas/CreateStreakPausesResponse"
},
"examples": {
"Success with no issues": {
@@ -5810,15 +5652,34 @@
"created": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
- "customerId": "customer_12345",
- "name": "Acme Corp",
- "status": "active",
- "created": "2026-01-15T09:30:00.000Z",
- "updated": "2026-01-15T09:30:00.000Z"
+ "userId": "user-123",
+ "start": "2026-08-20",
+ "end": "2026-08-27",
+ "status": "active"
}
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "userId": "user-123",
+ "start": "2026-08-20",
+ "end": "2026-08-27",
+ "status": "active"
+ }
+ ],
+ "issues": [
+ {
+ "userId": "non-existent-user",
+ "severity": "error",
+ "message": "User does not exist"
+ }
+ ]
+ }
}
}
}
@@ -5845,83 +5706,106 @@
}
}
},
- "summary": "Create tenants",
+ "summary": "Create streak pauses for multiple users",
"security": [
{
"ApiKeyAuth": []
}
]
},
- "patch": {
- "description": "Update tenants by ID.",
- "operationId": "admin_tenants_update",
+ "delete": {
+ "description": "Delete streak pauses by ID.",
+ "operationId": "admin_streaks_pauses_delete",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "tenants"
+ "streaks",
+ "pauses"
],
- "x-fern-sdk-method-name": "update",
+ "x-fern-sdk-method-name": "delete",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Acme Corporation'\n }\n]);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.pauses.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Acme Corporation\"\n }\n])\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.pauses.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Update(context.TODO(), api.UpdateTenantsRequest{})\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Pauses.Delete(context.TODO(), nil)\n"
}
],
- "requestBody": {
- "description": "Array of tenants to update. Each item must include an ID and at least one of customerId or name.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/UpdateTenantsRequest"
+ "parameters": [
+ {
+ "name": "ids",
+ "in": "query",
+ "description": "Streak pause IDs to delete. Repeat the query param or provide a comma-separated list.",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
},
- "examples": {
- "Update tenant name": {
- "value": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corporation"
- }
- ]
- }
+ "minItems": 1,
+ "maxItems": 100
+ },
+ "style": "form",
+ "explode": true,
+ "examples": {
+ "Multiple query params": {
+ "value": [
+ "550e8400-e29b-41d4-a716-446655440000",
+ "550e8400-e29b-41d4-a716-446655440001"
+ ]
}
}
}
- },
+ ],
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/UpdateTenantsResponse"
+ "$ref": "#/components/schemas/DeleteStreakPausesResponse"
},
"examples": {
"Success with no issues": {
"value": {
- "updated": [
+ "deleted": [
{
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "customerId": "customer_12345",
- "name": "Acme Corporation",
- "status": "active",
- "created": "2026-01-15T09:30:00.000Z",
- "updated": "2026-05-16T10:00:00.000Z"
+ "id": "550e8400-e29b-41d4-a716-446655440000"
}
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": [
+ {
+ "id": "not-a-uuid",
+ "severity": "error",
+ "message": "id must be a valid UUID"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440999",
+ "severity": "error",
+ "message": "Streak pause not found by ID"
+ }
+ ]
+ }
}
}
}
@@ -5948,89 +5832,164 @@
}
}
},
- "summary": "Update tenants",
+ "summary": "Delete streak pauses",
"security": [
{
"ApiKeyAuth": []
}
]
- },
- "delete": {
- "description": "Delete tenants by ID.",
- "operationId": "admin_tenants_delete",
+ }
+ },
+ "/streaks/restore": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
+ "post": {
+ "description": "Restore streaks for multiple users to the maximum previously achieved streak length found within the current restore window: the last 90 days for daily streaks, weekly periods starting with the week containing the start of the current calendar year for weekly streaks, and monthly periods starting at the beginning of the previous calendar year for monthly streaks.",
+ "operationId": "admin_streaks_restore",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "tenants"
+ "streaks"
],
- "x-fern-sdk-method-name": "delete",
+ "x-fern-sdk-method-name": "restore",
"tags": [
"Admin"
],
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.streaks.restore({\n users: [{ id: 'user-123' }, { id: 'user-456' }]\n});\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.streaks.restore({\n \"users\": [{\"id\": \"user-123\"}, {\"id\": \"user-456\"}]\n})\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Delete(context.TODO(), nil)\n"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Restore(context.TODO(), nil)\n"
}
],
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "description": "Tenant IDs to delete. Repeat the query param or provide a comma-separated list.",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "type": "string",
- "format": "uuid"
+ "requestBody": {
+ "description": "Array of users to restore streaks for",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RestoreStreaksRequest"
},
- "minItems": 1,
- "maxItems": 100
- },
- "style": "form",
- "explode": true,
- "examples": {
- "Multiple query params": {
- "value": [
- "550e8400-e29b-41d4-a716-446655440000",
- "550e8400-e29b-41d4-a716-446655440001"
- ]
+ "examples": {
+ "Restore streaks for multiple users": {
+ "value": {
+ "users": [
+ {
+ "id": "user-123"
+ },
+ {
+ "id": "user-456"
+ }
+ ]
+ }
+ }
}
}
}
- ],
+ },
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "Successful operation (no streaks restored)",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/DeleteTenantsResponse"
+ "$ref": "#/components/schemas/RestoreStreaksResponse"
},
"examples": {
- "Success with no issues": {
+ "Success with warnings": {
"value": {
- "deleted": [
+ "restoredUsers": [],
+ "issues": [
{
- "id": "550e8400-e29b-41d4-a716-446655440000"
+ "userId": "user-123",
+ "severity": "warning",
+ "message": "No streak to restore"
+ }
+ ]
+ }
+ },
+ "Mixed success and errors": {
+ "value": {
+ "restoredUsers": [],
+ "issues": [
+ {
+ "userId": "non-existent-user",
+ "severity": "error",
+ "message": "User does not exist"
+ },
+ {
+ "userId": "user-789",
+ "severity": "warning",
+ "message": "No streak to restore"
}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created (at least one streak restored)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RestoreStreaksResponse"
+ },
+ "examples": {
+ "Success with no issues": {
+ "value": {
+ "restoredUsers": [
+ "user-123",
+ "user-456"
],
"issues": []
}
+ },
+ "Mixed success and errors": {
+ "value": {
+ "restoredUsers": [
+ "user-123"
+ ],
+ "issues": [
+ {
+ "userId": "non-existent-user",
+ "severity": "error",
+ "message": "User does not exist"
+ }
+ ]
+ }
}
}
}
}
},
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
"401": {
"description": "Unauthorized",
"content": {
@@ -6052,7 +6011,7 @@
}
}
},
- "summary": "Delete tenants",
+ "summary": "Restore streaks for multiple users",
"security": [
{
"ApiKeyAuth": []
@@ -6060,20 +6019,25 @@
]
}
},
- "/tenants/{id}": {
+ "/settings": {
"servers": [
{
"url": "https://admin.trophy.so/v1",
"description": "Admin API"
}
],
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
"get": {
- "description": "Get a tenant by ID.",
- "operationId": "admin_tenants_get",
+ "description": "Get branding, experimentation, and aggregation settings.",
+ "operationId": "admin_settings_get",
"x-fern-server-name": "admin",
"x-fern-sdk-group-name": [
"admin",
- "tenants"
+ "settings"
],
"x-fern-sdk-method-name": "get",
"tags": [
@@ -6082,28 +6046,15 @@
"x-codeSamples": [
{
"lang": "javascript",
- "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst tenant = await trophy.admin.tenants.get(\n '550e8400-e29b-41d4-a716-446655440000'\n);\n"
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst settings = await trophy.admin.settings.get();\n"
},
{
"lang": "python",
- "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntenant = client.admin.tenants.get(\n \"550e8400-e29b-41d4-a716-446655440000\"\n)\n"
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsettings = client.admin.settings.get()\n"
},
{
"lang": "go",
- "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
- }
- ],
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "The UUID of the tenant to retrieve.",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uuid"
- },
- "example": "550e8400-e29b-41d4-a716-446655440000"
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Settings.Get(context.TODO(), nil)\n"
}
],
"responses": {
@@ -6112,17 +6063,26 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/AdminTenant"
+ "$ref": "#/components/schemas/AdminSettings"
},
"examples": {
- "Tenant": {
+ "Default settings": {
"value": {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "customerId": "customer_12345",
- "name": "Acme Corp",
- "status": "active",
- "created": "2026-01-15T09:30:00.000Z",
- "updated": "2026-01-15T09:30:00.000Z"
+ "branding": {
+ "appName": "Trophy",
+ "appUrl": "https://app.example.com",
+ "brandColor": "#1a2b3c",
+ "font": "MODERN_SANS",
+ "logo": {
+ "url": "https://cdn.example.com/logo.png"
+ },
+ "appIcon": null
+ },
+ "experimentation": {
+ "controlRatio": 10,
+ "userActivationWindow": 14
+ },
+ "aggregationPeriod": "weekly"
}
}
}
@@ -6139,16 +6099,6 @@
}
}
},
- "404": {
- "description": "Tenant Not Found",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/AdminErrorBody"
- }
- }
- }
- },
"422": {
"description": "Unprocessible Entity",
"content": {
@@ -6160,39 +6110,1246 @@
}
}
},
- "summary": "Get a tenant",
+ "summary": "Get organization settings",
"security": [
{
"ApiKeyAuth": []
}
]
- }
- }
- },
- "components": {
- "schemas": {
- "AdminErrorBody": {
- "title": "AdminErrorBody",
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- }
- },
- "required": [
- "error"
- ]
},
- "BatchMetricEventUser": {
- "title": "BatchMetricEventUser",
- "type": "object",
- "description": "The user that triggered a batch metric event.",
- "properties": {
- "id": {
- "type": "string",
- "description": "The ID of the user in your database. Must be a string.",
- "example": "user-id"
- },
+ "patch": {
+ "description": "Update branding, experimentation, and aggregation settings.",
+ "operationId": "admin_settings_update",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "settings"
+ ],
+ "x-fern-sdk-method-name": "update",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst settings = await trophy.admin.settings.update({\n branding: {\n appName: 'Trophy',\n appUrl: 'https://app.example.com',\n brandColor: '#1a2b3c'\n },\n experimentation: {\n controlRatio: 10,\n userActivationWindow: 14\n },\n aggregationPeriod: 'weekly'\n});\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsettings = client.admin.settings.update({\n \"branding\": {\n \"app_name\": \"Trophy\",\n \"app_url\": \"https://app.example.com\",\n \"brand_color\": \"#1a2b3c\"\n },\n \"experimentation\": {\n \"control_ratio\": 10,\n \"user_activation_window\": 14\n },\n \"aggregation_period\": \"weekly\"\n})\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Settings.Update(\n context.TODO(),\n &api.UpdateAdminSettingsRequest{},\n)\n"
+ }
+ ],
+ "requestBody": {
+ "description": "Organization settings fields to update.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateAdminSettingsRequest"
+ },
+ "examples": {
+ "Update branding and experimentation": {
+ "value": {
+ "branding": {
+ "appName": "Trophy",
+ "appUrl": "https://app.example.com",
+ "brandColor": "#1a2b3c",
+ "logo": {
+ "url": "https://cdn.example.com/logo.png"
+ }
+ },
+ "experimentation": {
+ "controlRatio": 10,
+ "userActivationWindow": 14
+ },
+ "aggregationPeriod": "weekly"
+ }
+ },
+ "Clear logo": {
+ "value": {
+ "branding": {
+ "logo": null
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminSettings"
+ },
+ "examples": {
+ "Updated settings": {
+ "value": {
+ "branding": {
+ "appName": "Trophy",
+ "appUrl": "https://app.example.com",
+ "brandColor": "#1a2b3c",
+ "font": "MODERN_SANS",
+ "logo": {
+ "url": "https://cdn.example.com/logo.png"
+ },
+ "appIcon": null
+ },
+ "experimentation": {
+ "controlRatio": 10,
+ "userActivationWindow": 14
+ },
+ "aggregationPeriod": "weekly"
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Update organization settings",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ },
+ "/streaks/settings": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/TenantId"
+ }
+ ],
+ "get": {
+ "description": "Get the organization's streak configuration.",
+ "operationId": "admin_streaks_settings_get",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "streaks",
+ "settings"
+ ],
+ "x-fern-sdk-method-name": "get",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst settings = await trophy.admin.streaks.settings.get();\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsettings = client.admin.streaks.settings.get()\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Settings.Get(context.TODO(), nil)\n"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StreakSettings"
+ },
+ "examples": {
+ "Daily streaks with freezes": {
+ "value": {
+ "frequency": "daily",
+ "evaluationMode": "OR",
+ "customizationEnabled": true,
+ "daysOff": [
+ 0,
+ 6
+ ],
+ "metrics": [
+ {
+ "key": "words-written",
+ "threshold": 500
+ }
+ ],
+ "freezes": {
+ "startCount": 1,
+ "maxCount": 2,
+ "autoEarnInterval": 7,
+ "autoEarnAmount": 1
+ }
+ }
+ },
+ "Weekly streaks without freezes": {
+ "value": {
+ "frequency": "weekly",
+ "evaluationMode": "AND",
+ "customizationEnabled": false,
+ "daysOff": [],
+ "metrics": [
+ {
+ "key": "pages-read",
+ "threshold": 1
+ }
+ ],
+ "freezes": null
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Get streak settings",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "patch": {
+ "description": "Update the organization's streak configuration.",
+ "operationId": "admin_streaks_settings_update",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "streaks",
+ "settings"
+ ],
+ "x-fern-sdk-method-name": "update",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst settings = await trophy.admin.streaks.settings.update({\n frequency: 'daily',\n evaluationMode: 'OR',\n customizationEnabled: true,\n daysOff: [0, 6],\n metrics: [{ key: 'words-written', threshold: 500 }],\n freezes: {\n startCount: 1,\n maxCount: 2,\n autoEarnInterval: 7,\n autoEarnAmount: 1\n }\n});\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nsettings = client.admin.streaks.settings.update({\n \"frequency\": \"daily\",\n \"evaluation_mode\": \"OR\",\n \"customization_enabled\": True,\n \"days_off\": [0, 6],\n \"metrics\": [{\"key\": \"words-written\", \"threshold\": 500}],\n \"freezes\": {\n \"start_count\": 1,\n \"max_count\": 2,\n \"auto_earn_interval\": 7,\n \"auto_earn_amount\": 1\n }\n})\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Streaks.Settings.Update(\n context.TODO(),\n &api.UpdateStreakSettingsRequest{},\n)\n"
+ }
+ ],
+ "requestBody": {
+ "description": "Streak settings fields to update.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateStreakSettingsRequest"
+ },
+ "examples": {
+ "Update daily streak settings": {
+ "value": {
+ "frequency": "daily",
+ "evaluationMode": "OR",
+ "customizationEnabled": true,
+ "daysOff": [
+ 0,
+ 6
+ ],
+ "metrics": [
+ {
+ "key": "words-written",
+ "threshold": 500
+ }
+ ],
+ "freezes": {
+ "startCount": 1,
+ "maxCount": 2,
+ "autoEarnInterval": 7,
+ "autoEarnAmount": 1
+ }
+ }
+ },
+ "Disable freezes": {
+ "value": {
+ "freezes": null
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StreakSettings"
+ },
+ "examples": {
+ "Updated settings": {
+ "value": {
+ "frequency": "daily",
+ "evaluationMode": "OR",
+ "customizationEnabled": true,
+ "daysOff": [
+ 0,
+ 6
+ ],
+ "metrics": [
+ {
+ "key": "words-written",
+ "threshold": 500
+ }
+ ],
+ "freezes": {
+ "startCount": 1,
+ "maxCount": 2,
+ "autoEarnInterval": 7,
+ "autoEarnAmount": 1
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Update streak settings",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ },
+ "/application-api-keys": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "post": {
+ "description": "Create application API keys scoped to specific users. Each key can only perform operations on behalf of the user it was created for.",
+ "operationId": "admin_application_api_keys_create",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "applicationApiKeys"
+ ],
+ "x-fern-sdk-method-name": "create",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.applicationApiKeys.create([\n { userId: 'user_123' }\n]);\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.applicationApiKeys.create([\n { \"userId\": \"user_123\" }\n])\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.ApplicationApiKeys.Create(context.TODO(), api.CreateApplicationKeysRequest{})\n"
+ }
+ ],
+ "requestBody": {
+ "description": "Array of users to create application API keys for. Maximum 100 users per request.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateApplicationKeysRequest"
+ },
+ "examples": {
+ "Create application keys": {
+ "value": [
+ {
+ "userId": "user_123"
+ },
+ {
+ "userId": "user_456"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful operation (no keys created)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateApplicationKeysResponse"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created (at least one application API key created)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateApplicationKeysResponse"
+ },
+ "examples": {
+ "Success": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "userId": "user_123",
+ "key": "app_XXXXX.YOUR_API_KEY",
+ "prefix": "app_XXXXX"
+ }
+ ],
+ "issues": []
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Create application API keys for users",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "delete": {
+ "description": "Delete application API keys by ID.",
+ "operationId": "admin_application_api_keys_delete",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "applicationApiKeys"
+ ],
+ "x-fern-sdk-method-name": "delete",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.applicationApiKeys.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.applicationApiKeys.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.ApplicationApiKeys.Delete(context.TODO(), nil)\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "ids",
+ "in": "query",
+ "description": "Application API key IDs (UUIDs returned at creation time). Repeat the query param or provide a comma-separated list. Maximum 100 IDs per request.",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "maxItems": 100
+ },
+ "style": "form",
+ "explode": true,
+ "examples": {
+ "Single ID": {
+ "value": [
+ "550e8400-e29b-41d4-a716-446655440000"
+ ]
+ },
+ "Multiple IDs": {
+ "value": [
+ "550e8400-e29b-41d4-a716-446655440000",
+ "550e8400-e29b-41d4-a716-446655440001"
+ ]
+ }
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeleteApplicationKeysResponse"
+ },
+ "examples": {
+ "Success": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": []
+ }
+ },
+ "Partial success": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440999",
+ "severity": "error",
+ "message": "Application API key not found by ID"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Delete application API keys",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ },
+ "/tenants": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "get": {
+ "description": "List tenants in the current environment.",
+ "operationId": "admin_tenants_list",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "tenants"
+ ],
+ "x-fern-sdk-method-name": "list",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst tenants = await trophy.admin.tenants.list({\n limit: 10,\n skip: 0\n});\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntenants = client.admin.tenants.list(\n limit=10,\n skip=0\n)\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.List(context.TODO(), nil)\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "Number of records to return.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10
+ },
+ "example": 10
+ },
+ {
+ "name": "skip",
+ "in": "query",
+ "description": "Number of records to skip from the start of the list.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "example": 0
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListTenantsResponse"
+ },
+ "examples": {
+ "Tenants list": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "customerId": "customer_12345",
+ "name": "Acme Corp",
+ "status": "active",
+ "created": "2026-01-15T09:30:00.000Z",
+ "updated": "2026-01-15T09:30:00.000Z"
+ },
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "customerId": "customer_67890",
+ "name": "Globex Inc",
+ "status": "active",
+ "created": "2026-02-20T14:00:00.000Z",
+ "updated": "2026-02-20T14:00:00.000Z"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "List tenants",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "post": {
+ "description": "Create tenants.",
+ "operationId": "admin_tenants_create",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "tenants"
+ ],
+ "x-fern-sdk-method-name": "create",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.create([\n {\n customerId: 'customer_12345',\n name: 'Acme Corp'\n }\n]);\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.create([\n {\n \"customerId\": \"customer_12345\",\n \"name\": \"Acme Corp\"\n }\n])\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Create(context.TODO(), api.CreateTenantsRequest{})\n"
+ }
+ ],
+ "requestBody": {
+ "description": "Array of tenants to create. Maximum 100 tenants per request.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateTenantsRequest"
+ },
+ "examples": {
+ "Create tenants": {
+ "value": [
+ {
+ "customerId": "customer_12345",
+ "name": "Acme Corp"
+ },
+ {
+ "customerId": "customer_67890",
+ "name": "Globex Inc"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful operation (no tenants created)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateTenantsResponse"
+ },
+ "examples": {
+ "All requests had errors": {
+ "value": {
+ "created": [],
+ "issues": [
+ {
+ "index": 0,
+ "severity": "error",
+ "message": "Customer ID \"customer_12345\" already exists in this environment"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created (at least one tenant created)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateTenantsResponse"
+ },
+ "examples": {
+ "Success with no issues": {
+ "value": {
+ "created": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "customerId": "customer_12345",
+ "name": "Acme Corp",
+ "status": "active",
+ "created": "2026-01-15T09:30:00.000Z",
+ "updated": "2026-01-15T09:30:00.000Z"
+ }
+ ],
+ "issues": []
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Create tenants",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "patch": {
+ "description": "Update tenants by ID.",
+ "operationId": "admin_tenants_update",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "tenants"
+ ],
+ "x-fern-sdk-method-name": "update",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.update([\n {\n id: '550e8400-e29b-41d4-a716-446655440000',\n name: 'Acme Corporation'\n }\n]);\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.update([\n {\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"name\": \"Acme Corporation\"\n }\n])\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Update(context.TODO(), api.UpdateTenantsRequest{})\n"
+ }
+ ],
+ "requestBody": {
+ "description": "Array of tenants to update. Each item must include an ID and at least one of customerId or name.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateTenantsRequest"
+ },
+ "examples": {
+ "Update tenant name": {
+ "value": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "Acme Corporation"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateTenantsResponse"
+ },
+ "examples": {
+ "Success with no issues": {
+ "value": {
+ "updated": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "customerId": "customer_12345",
+ "name": "Acme Corporation",
+ "status": "active",
+ "created": "2026-01-15T09:30:00.000Z",
+ "updated": "2026-05-16T10:00:00.000Z"
+ }
+ ],
+ "issues": []
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Update tenants",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ },
+ "delete": {
+ "description": "Delete tenants by ID.",
+ "operationId": "admin_tenants_delete",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "tenants"
+ ],
+ "x-fern-sdk-method-name": "delete",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst response = await trophy.admin.tenants.delete({\n ids: [\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n});\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\nresponse = client.admin.tenants.delete(\n ids=[\n '550e8400-e29b-41d4-a716-446655440000',\n '550e8400-e29b-41d4-a716-446655440001'\n ]\n)\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Delete(context.TODO(), nil)\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "ids",
+ "in": "query",
+ "description": "Tenant IDs to delete. Repeat the query param or provide a comma-separated list.",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "minItems": 1,
+ "maxItems": 100
+ },
+ "style": "form",
+ "explode": true,
+ "examples": {
+ "Multiple query params": {
+ "value": [
+ "550e8400-e29b-41d4-a716-446655440000",
+ "550e8400-e29b-41d4-a716-446655440001"
+ ]
+ }
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeleteTenantsResponse"
+ },
+ "examples": {
+ "Success with no issues": {
+ "value": {
+ "deleted": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "issues": []
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Delete tenants",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ },
+ "/tenants/{id}": {
+ "servers": [
+ {
+ "url": "https://admin.trophy.so/v1",
+ "description": "Admin API"
+ }
+ ],
+ "get": {
+ "description": "Get a tenant by ID.",
+ "operationId": "admin_tenants_get",
+ "x-fern-server-name": "admin",
+ "x-fern-sdk-group-name": [
+ "admin",
+ "tenants"
+ ],
+ "x-fern-sdk-method-name": "get",
+ "tags": [
+ "Admin"
+ ],
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "source": "import { TrophyApiClient } from '@trophyso/node';\n\nconst trophy = new TrophyApiClient({\n apiKey: 'YOUR_API_KEY'\n});\n\nconst tenant = await trophy.admin.tenants.get(\n '550e8400-e29b-41d4-a716-446655440000'\n);\n"
+ },
+ {
+ "lang": "python",
+ "source": "from trophy import TrophyApi\n\nclient = TrophyApi(api_key='YOUR_API_KEY')\n\ntenant = client.admin.tenants.get(\n \"550e8400-e29b-41d4-a716-446655440000\"\n)\n"
+ },
+ {
+ "lang": "go",
+ "source": "import (\n \"context\"\n\n api \"github.com/trophyso/trophy-go\"\n trophyclient \"github.com/trophyso/trophy-go/client\"\n \"github.com/trophyso/trophy-go/option\"\n)\n\nclient := trophyclient.NewClient(\n option.WithApiKey(\"YOUR_API_KEY\"),\n)\n\nresponse, err := client.Admin.Tenants.Get(context.TODO(), \"550e8400-e29b-41d4-a716-446655440000\")\n"
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "The UUID of the tenant to retrieve.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "example": "550e8400-e29b-41d4-a716-446655440000"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful operation",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminTenant"
+ },
+ "examples": {
+ "Tenant": {
+ "value": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "customerId": "customer_12345",
+ "name": "Acme Corp",
+ "status": "active",
+ "created": "2026-01-15T09:30:00.000Z",
+ "updated": "2026-01-15T09:30:00.000Z"
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Tenant Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessible Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AdminErrorBody"
+ }
+ }
+ }
+ }
+ },
+ "summary": "Get a tenant by ID",
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "AdminErrorBody": {
+ "title": "AdminErrorBody",
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "error"
+ ]
+ },
+ "BatchMetricEventUser": {
+ "title": "BatchMetricEventUser",
+ "type": "object",
+ "description": "The user that triggered a batch metric event.",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The ID of the user in your database. Must be a string.",
+ "example": "user-id"
+ },
"email": {
"type": "string",
"description": "The user's email address. Required if subscribeToEmails is true.",
@@ -6332,156 +7489,338 @@
}
},
"required": [
- "freezes"
+ "freezes"
+ ]
+ },
+ "CreateStreakFreezesResponse": {
+ "title": "CreateStreakFreezesResponse",
+ "type": "object",
+ "description": "Response containing any issues encountered while creating streak freezes.",
+ "properties": {
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminIssue"
+ },
+ "description": "Array of issues encountered during freeze creation."
+ }
+ },
+ "required": [
+ "issues"
+ ]
+ },
+ "CreateStreakPausesRequest": {
+ "title": "CreateStreakPausesRequest",
+ "type": "object",
+ "description": "Request body for creating streak pauses.",
+ "properties": {
+ "pauses": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "userId": {
+ "type": "string",
+ "description": "The ID of the user to create a pause for.",
+ "example": "user-123"
+ },
+ "start": {
+ "type": "string",
+ "format": "date",
+ "description": "The first date the pause covers, in YYYY-MM-DD format. Must not be before today in the user's timezone.",
+ "example": "2026-08-20"
+ },
+ "end": {
+ "type": "string",
+ "format": "date",
+ "description": "The last date the pause covers, in YYYY-MM-DD format. Must be on or after start.",
+ "example": "2026-08-27"
+ }
+ },
+ "required": [
+ "userId",
+ "start",
+ "end"
+ ]
+ },
+ "description": "Array of pauses to create. Maximum 100 pauses per request.",
+ "maxItems": 100,
+ "minItems": 1
+ }
+ },
+ "required": [
+ "pauses"
+ ]
+ },
+ "AdminStreakPause": {
+ "title": "AdminStreakPause",
+ "type": "object",
+ "description": "A streak pause returned from the admin pauses endpoints.",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid",
+ "description": "The unique ID of the streak pause."
+ },
+ "userId": {
+ "type": "string",
+ "description": "The ID of the user the pause belongs to.",
+ "example": "user-123"
+ },
+ "start": {
+ "type": "string",
+ "format": "date",
+ "description": "The first date the pause covers.",
+ "example": "2026-08-20"
+ },
+ "end": {
+ "type": "string",
+ "format": "date",
+ "description": "The last date the pause covers.",
+ "example": "2026-08-27"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "active",
+ "archived"
+ ],
+ "description": "The status of the pause."
+ }
+ },
+ "required": [
+ "id",
+ "userId",
+ "start",
+ "end",
+ "status"
+ ]
+ },
+ "CreateStreakPausesResponse": {
+ "title": "CreateStreakPausesResponse",
+ "type": "object",
+ "description": "Response containing created streak pauses and any issues encountered.",
+ "properties": {
+ "created": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminStreakPause"
+ },
+ "description": "Array of streak pauses that were created."
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminIssue"
+ },
+ "description": "Array of issues encountered during pause creation."
+ }
+ },
+ "required": [
+ "created",
+ "issues"
+ ]
+ },
+ "DeleteStreakPausesResponse": {
+ "title": "DeleteStreakPausesResponse",
+ "type": "object",
+ "description": "Response containing deleted streak pauses and any issues encountered.",
+ "properties": {
+ "deleted": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DeletedResource"
+ },
+ "description": "Array of deleted streak pause IDs."
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminIssue"
+ },
+ "description": "Array of issues encountered during pause deletion."
+ }
+ },
+ "required": [
+ "deleted",
+ "issues"
+ ]
+ },
+ "CreateAttributesRequest": {
+ "title": "CreateAttributesRequest",
+ "type": "array",
+ "description": "Request body for creating attributes.",
+ "items": {
+ "$ref": "#/components/schemas/CreateAttributeRequestItem"
+ },
+ "minItems": 1,
+ "maxItems": 100
+ },
+ "CreateAttributeRequestItem": {
+ "title": "CreateAttributeRequestItem",
+ "type": "object",
+ "description": "An attribute to create.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The attribute name.",
+ "example": "Plan"
+ },
+ "key": {
+ "type": "string",
+ "pattern": "^[a-zA-Z\\d-_]+$",
+ "description": "The attribute key. Only alphanumeric characters, hyphens, and underscores are permitted.",
+ "example": "plan"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "user",
+ "event"
+ ],
+ "description": "The attribute type.",
+ "example": "user"
+ }
+ },
+ "required": [
+ "name",
+ "key",
+ "type"
+ ]
+ },
+ "AdminAttribute": {
+ "title": "AdminAttribute",
+ "type": "object",
+ "description": "An attribute returned from the admin attributes endpoints.",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid",
+ "description": "The UUID of the attribute."
+ },
+ "name": {
+ "type": "string",
+ "description": "The attribute name."
+ },
+ "key": {
+ "type": "string",
+ "description": "The attribute key."
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "user",
+ "event"
+ ],
+ "description": "The attribute type."
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "key",
+ "type"
]
},
- "CreateStreakFreezesResponse": {
- "title": "CreateStreakFreezesResponse",
+ "CreateAttributesResponse": {
+ "title": "CreateAttributesResponse",
"type": "object",
- "description": "Response containing any issues encountered while creating streak freezes.",
+ "description": "Response containing created attributes and any per-item issues.",
"properties": {
+ "created": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminAttribute"
+ },
+ "description": "Array of successfully created attributes."
+ },
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during freeze creation."
+ "description": "Array of issues encountered during attribute creation."
}
},
"required": [
+ "created",
"issues"
]
},
- "CreateStreakPausesRequest": {
- "title": "CreateStreakPausesRequest",
- "type": "object",
- "description": "Request body for creating streak pauses.",
- "properties": {
- "pauses": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "userId": {
- "type": "string",
- "description": "The ID of the user to create a pause for.",
- "example": "user-123"
- },
- "start": {
- "type": "string",
- "format": "date",
- "description": "The first date the pause covers, in YYYY-MM-DD format. Must not be before today in the user's timezone.",
- "example": "2026-08-20"
- },
- "end": {
- "type": "string",
- "format": "date",
- "description": "The last date the pause covers, in YYYY-MM-DD format. Must be on or after start.",
- "example": "2026-08-27"
- }
- },
- "required": [
- "userId",
- "start",
- "end"
- ]
- },
- "description": "Array of pauses to create. Maximum 100 pauses per request.",
- "maxItems": 100,
- "minItems": 1
- }
+ "UpdateAttributesRequest": {
+ "title": "UpdateAttributesRequest",
+ "type": "array",
+ "description": "Request body for updating attributes.",
+ "items": {
+ "$ref": "#/components/schemas/UpdateAttributeRequestItem"
},
- "required": [
- "pauses"
- ]
+ "minItems": 1,
+ "maxItems": 100
},
- "AdminStreakPause": {
- "title": "AdminStreakPause",
+ "UpdateAttributeRequestItem": {
+ "title": "UpdateAttributeRequestItem",
"type": "object",
- "description": "A streak pause returned from the admin pauses endpoints.",
+ "description": "An attribute update object. `id` is required and `name` is optional. `key` and `type` cannot be changed through this endpoint.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
- "description": "The unique ID of the streak pause."
- },
- "userId": {
- "type": "string",
- "description": "The ID of the user the pause belongs to.",
- "example": "user-123"
- },
- "start": {
- "type": "string",
- "format": "date",
- "description": "The first date the pause covers.",
- "example": "2026-08-20"
- },
- "end": {
- "type": "string",
- "format": "date",
- "description": "The last date the pause covers.",
- "example": "2026-08-27"
+ "description": "The UUID of the attribute to update.",
+ "example": "550e8400-e29b-41d4-a716-446655440000"
},
- "status": {
+ "name": {
"type": "string",
- "enum": [
- "active",
- "archived"
- ],
- "description": "The status of the pause."
+ "description": "The updated attribute name.",
+ "example": "Subscription Plan"
}
},
"required": [
- "id",
- "userId",
- "start",
- "end",
- "status"
+ "id"
]
},
- "CreateStreakPausesResponse": {
- "title": "CreateStreakPausesResponse",
+ "UpdateAttributesResponse": {
+ "title": "UpdateAttributesResponse",
"type": "object",
- "description": "Response containing created streak pauses and any issues encountered.",
+ "description": "Response containing updated attributes and any per-item issues identified by attribute ID.",
"properties": {
- "created": {
+ "updated": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/AdminStreakPause"
+ "$ref": "#/components/schemas/AdminAttribute"
},
- "description": "Array of streak pauses that were created."
+ "description": "Array of successfully updated attributes."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during pause creation."
+ "description": "Array of issues encountered during attribute update."
}
},
"required": [
- "created",
+ "updated",
"issues"
]
},
- "DeleteStreakPausesResponse": {
- "title": "DeleteStreakPausesResponse",
+ "DeleteAttributesResponse": {
+ "title": "DeleteAttributesResponse",
"type": "object",
- "description": "Response containing deleted streak pauses and any issues encountered.",
+ "description": "Response containing deleted attributes represented by ID and any per-item issues, including invalid or missing attribute IDs.",
"properties": {
"deleted": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeletedResource"
},
- "description": "Array of deleted streak pause IDs."
+ "description": "Array of deleted attributes represented by ID."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during pause deletion."
+ "description": "Array of issues encountered during attribute deletion."
}
},
"required": [
@@ -6489,100 +7828,316 @@
"issues"
]
},
- "CreateAttributesRequest": {
- "title": "CreateAttributesRequest",
+ "ListAttributesResponse": {
+ "title": "ListAttributesResponse",
"type": "array",
- "description": "Request body for creating attributes.",
+ "description": "A paginated list of attributes.",
"items": {
- "$ref": "#/components/schemas/CreateAttributeRequestItem"
+ "$ref": "#/components/schemas/AdminAttribute"
+ }
+ },
+ "CreateAchievementsRequest": {
+ "title": "CreateAchievementsRequest",
+ "type": "array",
+ "description": "Request body for creating achievements.",
+ "items": {
+ "$ref": "#/components/schemas/CreateAchievementRequestItem"
},
"minItems": 1,
"maxItems": 100
},
- "CreateAttributeRequestItem": {
- "title": "CreateAttributeRequestItem",
+ "CreateAchievementRequestItem": {
+ "title": "CreateAchievementRequestItem",
"type": "object",
- "description": "An attribute to create.",
+ "description": "An achievement to create. Trigger-specific fields are required based on `trigger`. `status` defaults to `inactive`.",
"properties": {
"name": {
"type": "string",
- "description": "The attribute name.",
- "example": "Plan"
+ "description": "The achievement name.",
+ "example": "First Workout"
+ },
+ "trigger": {
+ "type": "string",
+ "enum": [
+ "metric",
+ "streak",
+ "api",
+ "achievement",
+ "anniversary"
+ ],
+ "description": "The achievement trigger type.",
+ "example": "metric"
+ },
+ "description": {
+ "type": "string",
+ "description": "A short description of the achievement.",
+ "example": "Complete your first workout"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "active",
+ "inactive",
+ "locked"
+ ],
+ "default": "inactive",
+ "description": "The achievement status. Defaults to `inactive`.",
+ "example": "inactive"
+ },
+ "badge": {
+ "type": "object",
+ "description": "An optional badge for the achievement.",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The URL of the badge image.",
+ "example": "https://assets.trophy.so/badge.png"
+ }
+ },
+ "required": [
+ "url"
+ ]
+ },
+ "userAttributes": {
+ "type": "array",
+ "description": "User attribute filters applied to the achievement. Each `attributeId` must be an active user attribute.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "key": {
+ "type": "string",
+ "pattern": "^[a-zA-Z\\d-_]+$",
+ "description": "Required if trigger is `api`. Only alphanumeric characters, hyphens, and underscores are permitted.",
+ "example": "custom-unlock"
+ },
+ "metricId": {
+ "type": "string",
+ "format": "uuid",
+ "description": "Required if trigger is `metric`. The UUID of the metric."
+ },
+ "metricValue": {
+ "type": "number",
+ "description": "Required if trigger is `metric`. The metric threshold users must reach. Must be at least 1.",
+ "example": 1
+ },
+ "eventAttributes": {
+ "type": "array",
+ "description": "Event attribute filters. Only permitted for metric achievements. Each `attributeId` must be an active event attribute.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
},
- "key": {
- "type": "string",
- "pattern": "^[a-zA-Z\\d-_]+$",
- "description": "The attribute key. Only alphanumeric characters, hyphens, and underscores are permitted.",
- "example": "plan"
+ "streakLength": {
+ "type": "integer",
+ "description": "Required if trigger is `streak`. The streak length users must reach. Must be at least 1.",
+ "example": 7
},
- "type": {
- "type": "string",
- "enum": [
- "user",
- "event"
- ],
- "description": "The attribute type.",
- "example": "user"
+ "anniversaryYears": {
+ "type": "integer",
+ "description": "Required if trigger is `anniversary`. The number of years since sign-up. Must be at least 1.",
+ "example": 1
+ },
+ "achievementIds": {
+ "type": "array",
+ "description": "Required if trigger is `achievement`. UUIDs of prerequisite achievements.",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "minItems": 1
}
},
"required": [
"name",
- "key",
- "type"
+ "trigger"
]
},
- "AdminAttribute": {
- "title": "AdminAttribute",
+ "AdminAchievement": {
+ "title": "AdminAchievement",
"type": "object",
- "description": "An attribute returned from the admin attributes endpoints.",
+ "description": "An achievement as returned from admin endpoints. Trigger-specific fields are only present for the matching trigger type.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
- "description": "The UUID of the attribute."
+ "description": "The UUID of the achievement."
},
"name": {
"type": "string",
- "description": "The attribute name."
+ "description": "The achievement name."
},
- "key": {
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "A short description of the achievement."
+ },
+ "trigger": {
"type": "string",
- "description": "The attribute key."
+ "enum": [
+ "metric",
+ "streak",
+ "api",
+ "achievement",
+ "anniversary"
+ ],
+ "description": "The achievement trigger type."
},
- "type": {
+ "status": {
"type": "string",
"enum": [
- "user",
- "event"
+ "active",
+ "inactive",
+ "locked"
],
- "description": "The attribute type."
+ "description": "The achievement status."
+ },
+ "badge": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The URL of the badge image."
+ }
+ },
+ "required": [
+ "url"
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The badge for the achievement, or null if no badge is set."
+ },
+ "userAttributes": {
+ "type": "array",
+ "description": "User attribute filters applied to the achievement.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "key": {
+ "type": "string",
+ "description": "The achievement key. Only present for API achievements."
+ },
+ "metricId": {
+ "type": "string",
+ "format": "uuid",
+ "description": "The UUID of the metric. Only present for metric achievements."
+ },
+ "metricValue": {
+ "type": "number",
+ "description": "The metric threshold. Only present for metric achievements."
+ },
+ "eventAttributes": {
+ "type": "array",
+ "description": "Event attribute filters. Only present for metric achievements.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "streakLength": {
+ "type": "integer",
+ "description": "The streak length. Only present for streak achievements."
+ },
+ "anniversaryYears": {
+ "type": "integer",
+ "description": "The anniversary years. Only present for anniversary achievements."
+ },
+ "achievementIds": {
+ "type": "array",
+ "description": "Prerequisite achievement UUIDs. Only present for achievement achievements.",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
}
},
"required": [
"id",
"name",
- "key",
- "type"
+ "description",
+ "trigger",
+ "status",
+ "badge",
+ "userAttributes"
]
},
- "CreateAttributesResponse": {
- "title": "CreateAttributesResponse",
+ "CreateAchievementsResponse": {
+ "title": "CreateAchievementsResponse",
"type": "object",
- "description": "Response containing created attributes and any per-item issues.",
+ "description": "Response containing created achievements and any per-item issues.",
"properties": {
"created": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/AdminAttribute"
+ "$ref": "#/components/schemas/AdminAchievement"
},
- "description": "Array of successfully created attributes."
+ "description": "Array of successfully created achievements."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during attribute creation."
+ "description": "Array of issues encountered during achievement creation."
}
},
"required": [
@@ -6590,55 +8145,177 @@
"issues"
]
},
- "UpdateAttributesRequest": {
- "title": "UpdateAttributesRequest",
+ "UpdateAchievementsRequest": {
+ "title": "UpdateAchievementsRequest",
"type": "array",
- "description": "Request body for updating attributes.",
+ "description": "Request body for updating achievements.",
"items": {
- "$ref": "#/components/schemas/UpdateAttributeRequestItem"
+ "$ref": "#/components/schemas/UpdateAchievementRequestItem"
},
"minItems": 1,
"maxItems": 100
},
- "UpdateAttributeRequestItem": {
- "title": "UpdateAttributeRequestItem",
+ "UpdateAchievementRequestItem": {
+ "title": "UpdateAchievementRequestItem",
"type": "object",
- "description": "An attribute update object. `id` is required and `name` is optional. `key` and `type` cannot be changed through this endpoint.",
+ "description": "An achievement update object. `id` is required; all other fields are optional. Omitted fields are preserved. Send `null` for `description`, `badge`, or `userAttributes` to clear them.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
- "description": "The UUID of the attribute to update.",
+ "description": "The UUID of the achievement to update.",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
"name": {
"type": "string",
- "description": "The updated attribute name.",
- "example": "Subscription Plan"
+ "description": "The updated achievement name."
+ },
+ "trigger": {
+ "type": "string",
+ "enum": [
+ "metric",
+ "streak",
+ "api",
+ "achievement",
+ "anniversary"
+ ],
+ "description": "The updated trigger type. Changing trigger requires the new trigger's mandatory fields."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "The updated description. Send `null` to clear."
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "active",
+ "inactive",
+ "locked"
+ ],
+ "description": "The updated status."
+ },
+ "badge": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The URL of the badge image."
+ }
+ },
+ "required": [
+ "url"
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The updated badge, or `null` to clear it."
+ },
+ "userAttributes": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "description": "Updated user attribute filters. Send `null` to clear. Each `attributeId` must be an active user attribute.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "key": {
+ "type": "string",
+ "pattern": "^[a-zA-Z\\d-_]+$",
+ "description": "Updated key. Only permitted for API achievements."
+ },
+ "metricId": {
+ "type": "string",
+ "format": "uuid",
+ "description": "Updated metric ID. Only permitted for metric achievements."
+ },
+ "metricValue": {
+ "type": "number",
+ "description": "Updated metric threshold. Only permitted for metric achievements."
+ },
+ "eventAttributes": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "description": "Updated event attribute filters. Only permitted for metric achievements. Send `null` to clear. Each `attributeId` must be an active event attribute.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "streakLength": {
+ "type": "integer",
+ "description": "Updated streak length. Only permitted for streak achievements."
+ },
+ "anniversaryYears": {
+ "type": "integer",
+ "description": "Updated anniversary years. Only permitted for anniversary achievements."
+ },
+ "achievementIds": {
+ "type": "array",
+ "description": "Updated prerequisite achievement UUIDs. Only permitted for achievement achievements.",
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ }
}
},
"required": [
"id"
]
- },
- "UpdateAttributesResponse": {
- "title": "UpdateAttributesResponse",
+ },
+ "UpdateAchievementsResponse": {
+ "title": "UpdateAchievementsResponse",
"type": "object",
- "description": "Response containing updated attributes and any per-item issues identified by attribute ID.",
+ "description": "Response containing updated achievements and any per-item issues identified by achievement ID.",
"properties": {
"updated": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/AdminAttribute"
+ "$ref": "#/components/schemas/AdminAchievement"
},
- "description": "Array of successfully updated attributes."
+ "description": "Array of successfully updated achievements."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during attribute update."
+ "description": "Array of issues encountered during achievement update."
}
},
"required": [
@@ -6646,24 +8323,24 @@
"issues"
]
},
- "DeleteAttributesResponse": {
- "title": "DeleteAttributesResponse",
+ "DeleteAchievementsResponse": {
+ "title": "DeleteAchievementsResponse",
"type": "object",
- "description": "Response containing deleted attributes represented by ID and any per-item issues, including invalid or missing attribute IDs.",
+ "description": "Response containing deleted achievements represented by ID and any per-item issues, including invalid or missing achievement IDs.",
"properties": {
"deleted": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeletedResource"
},
- "description": "Array of deleted attributes represented by ID."
+ "description": "Array of deleted achievements represented by ID."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AdminIssue"
},
- "description": "Array of issues encountered during attribute deletion."
+ "description": "Array of issues encountered during achievement deletion."
}
},
"required": [
@@ -6671,12 +8348,12 @@
"issues"
]
},
- "ListAttributesResponse": {
- "title": "ListAttributesResponse",
+ "ListAchievementsResponse": {
+ "title": "ListAchievementsResponse",
"type": "array",
- "description": "A paginated list of attributes.",
+ "description": "A paginated list of achievements.",
"items": {
- "$ref": "#/components/schemas/AdminAttribute"
+ "$ref": "#/components/schemas/AdminAchievement"
}
},
"CreateLeaderboardsRequest": {
@@ -8299,174 +9976,673 @@
"items": {
"type": "object",
"properties": {
- "attributeId": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "metricId": {
+ "type": "string",
+ "format": "uuid",
+ "description": "Updated metric ID. Only permitted for metric triggers."
+ },
+ "metricThreshold": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Updated metric threshold. Only permitted for metric triggers."
+ },
+ "eventAttributes": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "description": "Updated event attribute filters. Only permitted for metric triggers. Set to null to clear.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "attributeId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "attributeValue": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "attributeId",
+ "attributeValue"
+ ]
+ }
+ },
+ "achievementId": {
+ "type": "string",
+ "format": "uuid",
+ "description": "Updated achievement ID. Only permitted for achievement triggers."
+ },
+ "streakLength": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Updated streak length. Only permitted for streak triggers."
+ },
+ "timeUnit": {
+ "type": "string",
+ "enum": [
+ "hours",
+ "days"
+ ],
+ "description": "Updated time unit. Only permitted for time triggers."
+ },
+ "timeInterval": {
+ "type": "integer",
+ "minimum": 1,
+ "description": "Updated time interval. Only permitted for time triggers."
+ },
+ "blockIfOutOfPoints": {
+ "type": "boolean",
+ "description": "Updated block-if-out-of-points setting."
+ }
+ },
+ "required": [
+ "id"
+ ]
+ },
+ "maxItems": 100,
+ "minItems": 1
+ },
+ "PatchPointsTriggersResponse": {
+ "title": "PatchPointsTriggersResponse",
+ "type": "object",
+ "description": "Response containing updated triggers and any issues encountered.",
+ "properties": {
+ "updated": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminPointsTrigger"
+ },
+ "description": "Array of successfully updated triggers."
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminIssue"
+ },
+ "description": "Array of issues encountered during trigger updates."
+ }
+ },
+ "required": [
+ "updated",
+ "issues"
+ ]
+ },
+ "DeletePointsTriggersResponse": {
+ "title": "DeletePointsTriggersResponse",
+ "type": "object",
+ "description": "Response containing the points triggers that were deleted and any per-item issues.",
+ "properties": {
+ "deleted": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DeletedResource"
+ },
+ "description": "Array of deleted points triggers represented by ID."
+ },
+ "issues": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AdminIssue"
+ },
+ "description": "Array of issues encountered during trigger deletion."
+ }
+ },
+ "required": [
+ "deleted",
+ "issues"
+ ]
+ },
+ "RestoreStreaksRequest": {
+ "title": "RestoreStreaksRequest",
+ "type": "object",
+ "description": "Request body for restoring streaks for multiple users.",
+ "properties": {
+ "users": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The ID of the user to restore streaks for.",
+ "example": "user-123"
+ }
+ },
+ "required": [
+ "id"
+ ]
+ },
+ "description": "Array of users to restore streaks for. Maximum 100 users per request.",
+ "maxItems": 100,
+ "minItems": 1,
+ "example": [
+ {
+ "id": "user-123"
+ },
+ {
+ "id": "user-456"
+ }
+ ]
+ }
+ },
+ "required": [
+ "users"
+ ]
+ },
+ "AdminFontFamily": {
+ "title": "AdminFontFamily",
+ "type": "string",
+ "enum": [
+ "MODERN_SANS",
+ "BOOK_SANS",
+ "ORGANIC_SANS",
+ "GEOMETRIC_SANS",
+ "HEAVY_SANS",
+ "ROUNDED_SANS",
+ "MODERN_SERIF",
+ "BOOK_SERIF",
+ "MONOSPACE"
+ ],
+ "description": "The email brand font. Configured on the email settings form in the dashboard."
+ },
+ "AdminAggregationPeriod": {
+ "title": "AdminAggregationPeriod",
+ "type": "string",
+ "enum": [
+ "weekly",
+ "monthly"
+ ],
+ "description": "How progress is displayed in email chart blocks and how often recap messages send."
+ },
+ "AdminSettingsBranding": {
+ "title": "AdminSettingsBranding",
+ "type": "object",
+ "description": "Organization branding settings.",
+ "properties": {
+ "appName": {
+ "type": "string",
+ "description": "The name of the app or platform.",
+ "example": "Trophy"
+ },
+ "appUrl": {
+ "type": "string",
+ "description": "The URL of the app or platform.",
+ "example": "https://app.example.com"
+ },
+ "brandColor": {
+ "type": "string",
+ "description": "Primary brand color as hex (`#RGB` or `#RRGGBB`), `rgb(r,g,b)`, or `rgba(r,g,b,a)`.",
+ "example": "#1a2b3c"
+ },
+ "font": {
+ "$ref": "#/components/schemas/AdminFontFamily"
+ },
+ "logo": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "description": "The URL of the logo image.",
+ "example": "https://cdn.example.com/logo.png"
+ }
+ },
+ "required": [
+ "url"
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Company logo used in emails, or `null` if none is set."
+ },
+ "appIcon": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "description": "The URL of the app icon image.",
+ "example": "https://cdn.example.com/icon.png"
+ }
+ },
+ "required": [
+ "url"
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "App icon used in push notification previews, or `null` if none is set."
+ }
+ },
+ "required": [
+ "appName",
+ "appUrl",
+ "brandColor",
+ "font",
+ "logo",
+ "appIcon"
+ ]
+ },
+ "AdminSettingsExperimentation": {
+ "title": "AdminSettingsExperimentation",
+ "type": "object",
+ "description": "Experimentation settings.",
+ "properties": {
+ "controlRatio": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "description": "Percentage of new users assigned to the control group.",
+ "example": 10
+ },
+ "userActivationWindow": {
+ "type": "integer",
+ "minimum": 3,
+ "maximum": 30,
+ "description": "Number of days after a user's first event used to measure retention and early engagement.",
+ "example": 14
+ }
+ },
+ "required": [
+ "controlRatio",
+ "userActivationWindow"
+ ]
+ },
+ "AdminSettings": {
+ "title": "AdminSettings",
+ "type": "object",
+ "description": "The organization's branding, experimentation, and aggregation settings.",
+ "properties": {
+ "branding": {
+ "$ref": "#/components/schemas/AdminSettingsBranding"
+ },
+ "experimentation": {
+ "$ref": "#/components/schemas/AdminSettingsExperimentation"
+ },
+ "aggregationPeriod": {
+ "$ref": "#/components/schemas/AdminAggregationPeriod"
+ }
+ },
+ "required": [
+ "branding",
+ "experimentation",
+ "aggregationPeriod"
+ ]
+ },
+ "UpdateAdminSettingsBranding": {
+ "title": "UpdateAdminSettingsBranding",
+ "type": "object",
+ "description": "Branding fields to update. Omitted fields stay as-is.",
+ "properties": {
+ "appName": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The name of the app or platform.",
+ "example": "Trophy"
+ },
+ "appUrl": {
+ "type": "string",
+ "format": "uri",
+ "description": "The URL of the app or platform.",
+ "example": "https://app.example.com"
+ },
+ "brandColor": {
+ "type": "string",
+ "description": "Primary brand color as hex (`#RGB` or `#RRGGBB`), `rgb(r,g,b)`, or `rgba(r,g,b,a)`.",
+ "example": "#1a2b3c"
+ },
+ "font": {
+ "$ref": "#/components/schemas/AdminFontFamily"
+ },
+ "logo": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "url": {
"type": "string",
- "format": "uuid"
- },
- "attributeValue": {
- "type": "string"
+ "format": "uri",
+ "description": "The URL of the logo image.",
+ "example": "https://cdn.example.com/logo.png"
}
},
"required": [
- "attributeId",
- "attributeValue"
+ "url"
]
+ },
+ {
+ "type": "null"
}
- },
- "metricId": {
- "type": "string",
- "format": "uuid",
- "description": "Updated metric ID. Only permitted for metric triggers."
- },
- "metricThreshold": {
- "type": "integer",
- "minimum": 1,
- "description": "Updated metric threshold. Only permitted for metric triggers."
- },
- "eventAttributes": {
- "type": [
- "array",
- "null"
- ],
- "description": "Updated event attribute filters. Only permitted for metric triggers. Set to null to clear.",
- "items": {
+ ],
+ "description": "Company logo, or `null` to clear it."
+ },
+ "appIcon": {
+ "oneOf": [
+ {
"type": "object",
"properties": {
- "attributeId": {
+ "url": {
"type": "string",
- "format": "uuid"
- },
- "attributeValue": {
- "type": "string"
+ "format": "uri",
+ "description": "The URL of the app icon image.",
+ "example": "https://cdn.example.com/icon.png"
}
},
"required": [
- "attributeId",
- "attributeValue"
+ "url"
]
+ },
+ {
+ "type": "null"
}
- },
- "achievementId": {
- "type": "string",
- "format": "uuid",
- "description": "Updated achievement ID. Only permitted for achievement triggers."
- },
- "streakLength": {
- "type": "integer",
- "minimum": 1,
- "description": "Updated streak length. Only permitted for streak triggers."
- },
- "timeUnit": {
- "type": "string",
- "enum": [
- "hours",
- "days"
- ],
- "description": "Updated time unit. Only permitted for time triggers."
- },
- "timeInterval": {
- "type": "integer",
- "minimum": 1,
- "description": "Updated time interval. Only permitted for time triggers."
- },
- "blockIfOutOfPoints": {
- "type": "boolean",
- "description": "Updated block-if-out-of-points setting."
- }
+ ],
+ "description": "App icon, or `null` to clear it."
+ }
+ }
+ },
+ "UpdateAdminSettingsExperimentation": {
+ "title": "UpdateAdminSettingsExperimentation",
+ "type": "object",
+ "description": "Experimentation fields to update. Omitted fields stay as-is.",
+ "properties": {
+ "controlRatio": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "description": "Percentage of new users assigned to the control group.",
+ "example": 10
},
- "required": [
- "id"
- ]
+ "userActivationWindow": {
+ "type": "integer",
+ "minimum": 3,
+ "maximum": 30,
+ "description": "Number of days after a user's first event used to measure retention and early engagement.",
+ "example": 14
+ }
+ }
+ },
+ "UpdateAdminSettingsRequest": {
+ "title": "UpdateAdminSettingsRequest",
+ "type": "object",
+ "description": "Fields to update. Omitted top-level fields stay as-is. `branding` and `experimentation` must be objects when present; `null` is rejected. Nested objects are merged field-by-field.",
+ "properties": {
+ "branding": {
+ "$ref": "#/components/schemas/UpdateAdminSettingsBranding"
+ },
+ "experimentation": {
+ "$ref": "#/components/schemas/UpdateAdminSettingsExperimentation"
+ },
+ "aggregationPeriod": {
+ "$ref": "#/components/schemas/AdminAggregationPeriod"
+ }
+ }
+ },
+ "AdminStreakFrequency": {
+ "title": "AdminStreakFrequency",
+ "type": "string",
+ "enum": [
+ "daily",
+ "weekly",
+ "monthly"
+ ],
+ "description": "The frequency at which streaks are calculated."
+ },
+ "AdminStreakEvaluationMode": {
+ "title": "AdminStreakEvaluationMode",
+ "type": "string",
+ "enum": [
+ "OR",
+ "AND"
+ ],
+ "description": "Whether meeting any single metric threshold (`OR`) or all configured metric thresholds (`AND`) extends the user's streak."
+ },
+ "StreakSettingsMetric": {
+ "title": "StreakSettingsMetric",
+ "type": "object",
+ "description": "A metric that counts toward the organization streak.",
+ "properties": {
+ "key": {
+ "type": "string",
+ "description": "The metric key.",
+ "example": "words-written"
+ },
+ "threshold": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10000,
+ "description": "Minimum metric change in a streak period to count toward the streak.",
+ "example": 500
+ }
},
- "maxItems": 100,
- "minItems": 1
+ "required": [
+ "key",
+ "threshold"
+ ]
},
- "PatchPointsTriggersResponse": {
- "title": "PatchPointsTriggersResponse",
+ "StreakSettingsFreezes": {
+ "title": "StreakSettingsFreezes",
"type": "object",
- "description": "Response containing updated triggers and any issues encountered.",
+ "description": "Organization streak freeze configuration. `null` on the parent object means freezes are disabled.",
"properties": {
- "updated": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/AdminPointsTrigger"
- },
- "description": "Array of successfully updated triggers."
+ "startCount": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "description": "Number of freezes new users start with.",
+ "example": 1
},
- "issues": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/AdminIssue"
- },
- "description": "Array of issues encountered during trigger updates."
+ "maxCount": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "description": "Maximum number of freezes a user can have.",
+ "example": 2
+ },
+ "autoEarnInterval": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1,
+ "maximum": 365,
+ "description": "Days between auto-earned freezes. `null` when auto-earn is off.",
+ "example": 7
+ },
+ "autoEarnAmount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1,
+ "maximum": 10,
+ "description": "Freezes earned per interval. `null` when auto-earn is off.",
+ "example": 1
}
},
"required": [
- "updated",
- "issues"
+ "startCount",
+ "maxCount",
+ "autoEarnInterval",
+ "autoEarnAmount"
]
},
- "DeletePointsTriggersResponse": {
- "title": "DeletePointsTriggersResponse",
+ "UpdateStreakSettingsFreezes": {
+ "title": "UpdateStreakSettingsFreezes",
"type": "object",
- "description": "Response containing the points triggers that were deleted and any per-item issues.",
+ "description": "Replacement freeze configuration. `startCount` and `maxCount` are required. Auto-earn is a pair: both `autoEarnInterval` and `autoEarnAmount` must be set to enable auto-earn, or both omitted/`null` to disable it.",
"properties": {
- "deleted": {
+ "startCount": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "description": "Number of freezes new users start with.",
+ "example": 1
+ },
+ "maxCount": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 100,
+ "description": "Maximum number of freezes a user can have. Must be greater than or equal to `startCount`.",
+ "example": 2
+ },
+ "autoEarnInterval": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1,
+ "maximum": 365,
+ "description": "Days between auto-earned freezes.",
+ "example": 7
+ },
+ "autoEarnAmount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1,
+ "maximum": 10,
+ "description": "Freezes earned per interval.",
+ "example": 1
+ }
+ },
+ "required": [
+ "startCount",
+ "maxCount"
+ ]
+ },
+ "StreakSettings": {
+ "title": "StreakSettings",
+ "type": "object",
+ "description": "The organization's streak configuration.",
+ "properties": {
+ "frequency": {
+ "$ref": "#/components/schemas/AdminStreakFrequency"
+ },
+ "evaluationMode": {
+ "$ref": "#/components/schemas/AdminStreakEvaluationMode"
+ },
+ "customizationEnabled": {
+ "type": "boolean",
+ "description": "Whether users can override streak evaluation mode, metric thresholds, and days off via preferences."
+ },
+ "daysOff": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/DeletedResource"
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 6
},
- "description": "Array of deleted points triggers represented by ID."
+ "uniqueItems": true,
+ "maxItems": 6,
+ "description": "Days of the week that do not count toward the daily streak. Represented as zero-based integers matching JavaScript `Date.getDay()` (0 = Sunday, 6 = Saturday).",
+ "example": [
+ 0,
+ 6
+ ]
},
- "issues": {
+ "metrics": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/AdminIssue"
+ "$ref": "#/components/schemas/StreakSettingsMetric"
},
- "description": "Array of issues encountered during trigger deletion."
+ "description": "Metrics with a streak threshold greater than zero."
+ },
+ "freezes": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/StreakSettingsFreezes"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Freeze configuration, or `null` when streak freezes are disabled."
}
},
"required": [
- "deleted",
- "issues"
+ "frequency",
+ "evaluationMode",
+ "customizationEnabled",
+ "daysOff",
+ "metrics",
+ "freezes"
]
},
- "RestoreStreaksRequest": {
- "title": "RestoreStreaksRequest",
+ "UpdateStreakSettingsRequest": {
+ "title": "UpdateStreakSettingsRequest",
"type": "object",
- "description": "Request body for restoring streaks for multiple users.",
+ "description": "Fields to update. Omitted top-level fields stay as-is.",
"properties": {
- "users": {
+ "frequency": {
+ "$ref": "#/components/schemas/AdminStreakFrequency"
+ },
+ "evaluationMode": {
+ "$ref": "#/components/schemas/AdminStreakEvaluationMode"
+ },
+ "customizationEnabled": {
+ "type": "boolean",
+ "description": "Whether users can override streak evaluation mode, metric thresholds, and days off via preferences."
+ },
+ "daysOff": {
"type": "array",
"items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string",
- "description": "The ID of the user to restore streaks for.",
- "example": "user-123"
- }
- },
- "required": [
- "id"
- ]
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 6
},
- "description": "Array of users to restore streaks for. Maximum 100 users per request.",
- "maxItems": 100,
- "minItems": 1,
+ "uniqueItems": true,
+ "maxItems": 6,
+ "description": "Days of the week that do not count toward the daily streak. A non-empty array is only allowed when the resulting frequency is `daily`. Changing frequency away from `daily` clears stored days off even when this field is omitted.",
"example": [
+ 0,
+ 6
+ ]
+ },
+ "metrics": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "#/components/schemas/StreakSettingsMetric"
+ },
+ "description": "Replacement list of streak metrics. Keys must be unique and must exist on the organization."
+ },
+ "freezes": {
+ "oneOf": [
{
- "id": "user-123"
+ "$ref": "#/components/schemas/UpdateStreakSettingsFreezes"
},
{
- "id": "user-456"
+ "type": "null"
}
- ]
+ ],
+ "description": "Replacement freeze configuration, or `null` to disable freezes."
}
- },
- "required": [
- "users"
- ]
+ }
},
"RestoreStreaksResponse": {
"title": "RestoreStreaksResponse",
diff --git a/openapi/application.json b/openapi/application.json
index 6fe3bdaa..6ed7d1cb 100644
--- a/openapi/application.json
+++ b/openapi/application.json
@@ -2,13 +2,13 @@
"openapi": "3.1.0",
"info": {
"title": "Trophy",
- "version": "1.21.1"
+ "version": "1.24.0"
},
"x-fern-global-headers": [
{
"header": "X-SDK-VERSION",
"name": "sdkVersion",
- "x-fern-default": "1.21.1"
+ "x-fern-default": "1.24.0"
}
],
"paths": {
@@ -132,6 +132,16 @@
"value": "premium"
}
]
+ },
+ {
+ "id": "5100fe51-6bce-6j44-b0hs-bddc4e123685",
+ "trigger": "anniversary",
+ "name": "1 year anniversary",
+ "description": "Celebrate one year on the platform.",
+ "badgeUrl": "https://example.com/badge.png",
+ "anniversaryYears": 1,
+ "completions": 4,
+ "rarity": 40
}
]
}
@@ -847,6 +857,7 @@
"example": {
"email": "user@example.com",
"tz": "Europe/London",
+ "signUpDate": "2020-08-20",
"attributes": {
"department": "engineering",
"role": "developer"
@@ -1128,7 +1139,7 @@
]
},
"patch": {
- "description": "Update a user's notification and streak preferences. Streak preferences require streak customization to be enabled in your Trophy dashboard settings.",
+ "description": "Update a user's notification and streak preferences. Streak preferences other than `streak.enabled` require streak customization to be enabled in your Trophy dashboard settings.",
"operationId": "users_update_preferences",
"x-fern-server-name": "api",
"tags": [
@@ -1192,6 +1203,10 @@
"key": "words-written",
"threshold": 500
}
+ ],
+ "daysOff": [
+ 0,
+ 6
]
}
}
@@ -1290,6 +1305,10 @@
"key": "words-written",
"threshold": 500
}
+ ],
+ "daysOff": [
+ 0,
+ 6
]
}
}
@@ -1892,6 +1911,16 @@
"badgeUrl": "https://example.com/badge2.png",
"completions": 100,
"rarity": 50
+ },
+ {
+ "id": "d01dcbcb-d51e-4c12-b054-dc811dcdc626",
+ "trigger": "anniversary",
+ "name": "1-Year Anniversary",
+ "anniversaryYears": 1,
+ "achievedAt": "2021-04-01T00:00:00Z",
+ "badgeUrl": "https://example.com/badge3.png",
+ "completions": 40,
+ "rarity": 20
}
]
}
@@ -2932,6 +2961,7 @@
"email": "user@example.com",
"name": "John Doe",
"tz": "America/New_York",
+ "signUpDate": "2020-08-20",
"subscribeToEmails": true,
"created": "2024-01-15T10:30:00Z",
"updated": "2024-06-20T14:45:00Z",
@@ -6580,7 +6610,8 @@
"metric",
"streak",
"api",
- "achievement"
+ "achievement",
+ "anniversary"
],
"description": "The trigger of the achievement."
},
@@ -6606,6 +6637,10 @@
"type": "integer",
"description": "The length of the streak required to complete the achievement (only applicable if trigger = 'streak')"
},
+ "anniversaryYears": {
+ "type": "integer",
+ "description": "The number of years after sign-up required to complete the achievement (only applicable if trigger = 'anniversary')"
+ },
"achievementIds": {
"type": "array",
"items": {
@@ -6844,6 +6879,15 @@
"description": "The user's timezone (used for email scheduling).",
"example": "Europe/London"
},
+ "signUpDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "description": "The date the user signed up on your platform, as YYYY-MM-DD. ISO 8601 date-times are accepted and stored as their UTC calendar day. Must not be after today in the user's timezone. Required for anniversary achievements. Users without a signUpDate are not eligible.",
+ "example": "2020-08-20"
+ },
"deviceTokens": {
"type": [
"array",
@@ -6935,6 +6979,15 @@
"description": "The user's timezone.",
"example": "Europe/London"
},
+ "signUpDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "description": "The date the user signed up on your platform, as YYYY-MM-DD. Required for anniversary achievements. Null if not set, in which case the user is not eligible for anniversary achievements.",
+ "example": "2020-08-20"
+ },
"deviceTokens": {
"type": [
"array",
@@ -6989,6 +7042,7 @@
"email",
"name",
"tz",
+ "signUpDate",
"subscribeToEmails",
"attributes",
"control",
@@ -7073,7 +7127,7 @@
"StreakPreferences": {
"title": "StreakPreferences",
"type": "object",
- "description": "Per-user streak configuration. Metric and evaluation mode overrides require streak customization to be enabled in dashboard settings.",
+ "description": "Per-user streak configuration. Metric, evaluation mode, and days off overrides require streak customization to be enabled in dashboard settings.",
"properties": {
"enabled": {
"type": "boolean",
@@ -7089,6 +7143,21 @@
"$ref": "#/components/schemas/StreakMetricPreference"
},
"description": "Metrics and thresholds that count toward this user's streak."
+ },
+ "daysOff": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 6
+ },
+ "uniqueItems": true,
+ "maxItems": 6,
+ "description": "Days of the week that do not count toward the user's daily streak. Represented as zero-based integers matching JavaScript `Date.getDay()` (0 = Sunday, 6 = Saturday). For example, `[0, 6]` means Sunday and Saturday are days off. Only applied when streak frequency is daily. Users can still increase their streak on these days; if they do not, the streak stays paused at its current length instead of being lost.",
+ "example": [
+ 0,
+ 6
+ ]
}
}
},
diff --git a/platform/experimentation.mdx b/platform/experimentation.mdx
index 7a0541ed..188514e3 100644
--- a/platform/experimentation.mdx
+++ b/platform/experimentation.mdx
@@ -26,6 +26,8 @@ Trophy has a built-in capability to automatically A/B test gamification features
Found on the [integration page](https://app.trophy.so/integration/configure) of the Trophy dashboard, the control ratio adjusts the percentage of users that are assigned to the 'control' group versus the 'experimental' group.
+You can also read and update `controlRatio` and `userActivationWindow` with the [organization settings Admin API](/admin-api/endpoints/settings/update-organization-settings).
+