@smartico/public-api 0.0.379 → 0.0.381

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/.nvmrc +1 -1
  2. package/CLAUDE.md +103 -0
  3. package/README.md +53 -2
  4. package/dist/Base/ClassId.d.ts +2 -0
  5. package/dist/Jackpots/JackpotDetails.d.ts +14 -15
  6. package/dist/Jackpots/JackpotPot.d.ts +10 -6
  7. package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
  8. package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
  9. package/dist/Raffle/index.d.ts +2 -0
  10. package/dist/SmarticoAPI.d.ts +6 -1
  11. package/dist/SmarticoLib/index.d.ts +5 -1
  12. package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
  13. package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
  14. package/dist/WSAPI/WSAPI.d.ts +13 -1235
  15. package/dist/WSAPI/WSAPIAvatars.d.ts +296 -0
  16. package/dist/WSAPI/WSAPIBase.d.ts +71 -0
  17. package/dist/WSAPI/WSAPIBonuses.d.ts +240 -0
  18. package/dist/WSAPI/WSAPIClans.d.ts +388 -0
  19. package/dist/WSAPI/WSAPIGamePick.d.ts +593 -0
  20. package/dist/WSAPI/WSAPIGeneral.d.ts +172 -0
  21. package/dist/WSAPI/WSAPIInbox.d.ts +615 -0
  22. package/dist/WSAPI/WSAPIJackpots.d.ts +344 -0
  23. package/dist/WSAPI/WSAPILeaderBoard.d.ts +139 -0
  24. package/dist/WSAPI/WSAPIMiniGames.d.ts +510 -0
  25. package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
  26. package/dist/WSAPI/WSAPIRaffles.d.ts +643 -0
  27. package/dist/WSAPI/WSAPIStore.d.ts +656 -0
  28. package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
  29. package/dist/WSAPI/WSAPITypes.d.ts +376 -205
  30. package/dist/WSAPI/WSAPIUser.d.ts +533 -0
  31. package/dist/index.js +6745 -1661
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.modern.mjs +6324 -1342
  34. package/dist/index.modern.mjs.map +1 -1
  35. package/docs/Callbacks.md +162 -0
  36. package/docs/SmarticoObject.md +445 -0
  37. package/docs/Transforms.md +99 -0
  38. package/docs/api/README.md +82 -2
  39. package/docs/api/classes/WSAPIAvatars.md +344 -0
  40. package/docs/api/classes/WSAPIBonuses.md +271 -0
  41. package/docs/api/classes/WSAPIClans.md +436 -0
  42. package/docs/api/classes/WSAPIGamePick.md +710 -0
  43. package/docs/api/classes/WSAPIGeneral.md +212 -0
  44. package/docs/api/classes/WSAPIInbox.md +801 -0
  45. package/docs/api/classes/WSAPIJackpots.md +439 -0
  46. package/docs/api/classes/WSAPILeaderBoard.md +157 -0
  47. package/docs/api/classes/WSAPIMiniGames.md +612 -0
  48. package/docs/api/classes/WSAPIMissions.md +590 -0
  49. package/docs/api/classes/WSAPIRaffles.md +773 -0
  50. package/docs/api/classes/WSAPIStore.md +719 -0
  51. package/docs/api/classes/WSAPITournaments.md +571 -0
  52. package/docs/api/classes/WSAPIUser.md +637 -0
  53. package/docs/api/documents/Callbacks.md +162 -0
  54. package/docs/api/documents/SmarticoObject.md +445 -0
  55. package/docs/api/documents/Transforms.md +99 -0
  56. package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
  57. package/docs/api/enumerations/BonusStatus-1.md +11 -6
  58. package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
  59. package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
  60. package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
  61. package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
  62. package/docs/api/interfaces/AvatarCustomized.md +25 -0
  63. package/docs/api/interfaces/AvatarDefinition.md +94 -0
  64. package/docs/api/interfaces/AvatarPrompt.md +45 -0
  65. package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
  66. package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
  67. package/docs/api/interfaces/Clan.md +4 -0
  68. package/docs/api/interfaces/ClanInfo.md +109 -0
  69. package/docs/api/interfaces/ClanMember.md +53 -0
  70. package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
  71. package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
  72. package/docs/api/interfaces/ClanPublicMeta.md +4 -0
  73. package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
  74. package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
  75. package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
  76. package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
  77. package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
  78. package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
  79. package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
  80. package/docs/api/interfaces/JackpotDetails.md +14 -15
  81. package/docs/api/interfaces/JackpotPot.md +9 -6
  82. package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
  83. package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
  84. package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
  85. package/docs/api/interfaces/PointsLog.md +43 -0
  86. package/docs/api/interfaces/RaffleWonPrize.md +59 -0
  87. package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
  88. package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
  89. package/docs/api/interfaces/SAWTemplateUI.md +10 -0
  90. package/docs/api/interfaces/TAchCategory.md +14 -4
  91. package/docs/api/interfaces/TAvatarCustomized.md +4 -4
  92. package/docs/api/interfaces/TAvatarDefinition.md +13 -14
  93. package/docs/api/interfaces/TAvatarPrompt.md +6 -6
  94. package/docs/api/interfaces/TBonus.md +16 -8
  95. package/docs/api/interfaces/TBuyStoreItemResult.md +4 -11
  96. package/docs/api/interfaces/TClaimBonusResult.md +5 -5
  97. package/docs/api/interfaces/TClan.md +8 -4
  98. package/docs/api/interfaces/TClanInfo.md +47 -0
  99. package/docs/api/interfaces/TClanJoinResult.md +11 -1
  100. package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
  101. package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
  102. package/docs/api/interfaces/TClans.md +3 -1
  103. package/docs/api/interfaces/TGetTranslations.md +4 -0
  104. package/docs/api/interfaces/TInboxMessage.md +14 -6
  105. package/docs/api/interfaces/TInboxMessageBody.md +18 -12
  106. package/docs/api/interfaces/TLevel.md +17 -20
  107. package/docs/api/interfaces/TLevelCurrent.md +19 -18
  108. package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
  109. package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
  110. package/docs/api/interfaces/TMissionClaimRewardResult.md +6 -3
  111. package/docs/api/interfaces/TMissionOptInResult.md +6 -3
  112. package/docs/api/interfaces/TMissionOrBadge.md +5 -4
  113. package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
  114. package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
  115. package/docs/api/interfaces/TSetAvatarResult.md +3 -3
  116. package/docs/api/interfaces/TStoreItem.md +11 -1
  117. package/docs/api/interfaces/TTournament.md +1 -1
  118. package/docs/api/interfaces/TTournamentDetailed.md +9 -1
  119. package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
  120. package/docs/api/interfaces/TUICustomSection.md +23 -19
  121. package/docs/api/interfaces/TUserProfile.md +18 -16
  122. package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
  123. package/docs/api/interfaces/UserAchievement.md +1 -1
  124. package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
  125. package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
  126. package/docs/native/ADDING_METHODS.md +7 -2
  127. package/docs/native/PROTOCOL.md +337 -0
  128. package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
  129. package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
  130. package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
  131. package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
  132. package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
  133. package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
  134. package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
  135. package/docs/ui/clans/UIGuide_getClans.md +172 -0
  136. package/docs/ui/clans/UIGuide_joinClan.md +196 -0
  137. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
  138. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
  139. package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
  140. package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
  141. package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
  142. package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
  143. package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
  144. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
  145. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
  146. package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
  147. package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
  148. package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
  149. package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
  150. package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
  151. package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
  152. package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
  153. package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
  154. package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
  155. package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
  156. package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
  157. package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
  158. package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
  159. package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
  160. package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
  161. package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
  162. package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
  163. package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
  164. package/docs/ui/missions/UIGuide_getBadges.md +237 -0
  165. package/docs/ui/missions/UIGuide_getMissions.md +268 -0
  166. package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
  167. package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
  168. package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
  169. package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
  170. package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
  171. package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
  172. package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
  173. package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
  174. package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
  175. package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
  176. package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
  177. package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
  178. package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
  179. package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
  180. package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
  181. package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
  182. package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
  183. package/docs/ui/user/UIGuide_getLevels.md +167 -0
  184. package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
  185. package/package.json +3 -3
  186. package/scripts/postdoc-cleanup.js +195 -0
  187. package/src/Base/ClassId.ts +2 -0
  188. package/src/Jackpots/JackpotDetails.ts +14 -15
  189. package/src/Jackpots/JackpotPot.ts +10 -6
  190. package/src/Missions/MissionsUtils.ts +5 -2
  191. package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
  192. package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
  193. package/src/Raffle/index.ts +3 -1
  194. package/src/SmarticoAPI.ts +14 -1
  195. package/src/SmarticoLib/index.ts +4 -0
  196. package/src/Store/BuyStoreItemErrorCode.ts +8 -0
  197. package/src/Store/StoreItem.ts +1 -0
  198. package/src/Store/StoreItemPurchased.ts +1 -0
  199. package/src/Store/StoreItemType.ts +1 -1
  200. package/src/Tournaments/TournamentRegistrationError.ts +4 -0
  201. package/src/WSAPI/WSAPI.ts +27 -2007
  202. package/src/WSAPI/WSAPIAvatars.ts +345 -0
  203. package/src/WSAPI/WSAPIBase.ts +93 -0
  204. package/src/WSAPI/WSAPIBonuses.ts +268 -0
  205. package/src/WSAPI/WSAPIClans.ts +417 -0
  206. package/src/WSAPI/WSAPIGamePick.ts +667 -0
  207. package/src/WSAPI/WSAPIGeneral.ts +199 -0
  208. package/src/WSAPI/WSAPIInbox.ts +711 -0
  209. package/src/WSAPI/WSAPIJackpots.ts +448 -0
  210. package/src/WSAPI/WSAPILeaderBoard.ts +154 -0
  211. package/src/WSAPI/WSAPIMiniGames.ts +597 -0
  212. package/src/WSAPI/WSAPIMissions.ts +572 -0
  213. package/src/WSAPI/WSAPIRaffles.ts +703 -0
  214. package/src/WSAPI/WSAPIStore.ts +732 -0
  215. package/src/WSAPI/WSAPITournaments.ts +541 -0
  216. package/src/WSAPI/WSAPITypes.ts +376 -207
  217. package/src/WSAPI/WSAPIUser.ts +606 -0
  218. package/tsconfig.json +26 -2
  219. package/docs/api/classes/WSAPI.md +0 -1927
@@ -0,0 +1,590 @@
1
+ # Class: WSAPIMissions
2
+ ## Methods
3
+
4
+ ### getMissions()
5
+
6
+ > **getMissions**(`params?`): `Promise`\<[`TMissionOrBadge`](../interfaces/TMissionOrBadge.md)[]\>
7
+
8
+ Returns all missions visible to the current user, scoped server-side
9
+ to what the user is qualified to see. Optionally subscribes to live
10
+ updates via `onUpdate`: the callback is invoked with the full, refreshed
11
+ mission array whenever the server pushes a mission-state-changing event.
12
+
13
+ The returned list is the canonical source of truth for mission state
14
+ (`is_opted_in`, `progress`, `is_completed`, `completion_count`, etc.).
15
+ Consumers should NEVER mutate it optimistically — always wait for the
16
+ `onUpdate` callback (or a fresh `getMissions()` call after the 30s cache
17
+ window expires) to observe the new state.
18
+
19
+ #### Parameters
20
+
21
+ ##### params?
22
+
23
+ Optional. Omit to fetch without subscribing.
24
+
25
+ ###### onUpdate?
26
+
27
+ (`data`) => `void`
28
+
29
+ Callback invoked with the full refreshed
30
+ mission array on every server-pushed update
31
+ (after opt-in / claim-reward calls, or when
32
+ the server pushes an asynchronous
33
+ mission-state change). Each call to
34
+ `getMissions` overwrites the prior callback.
35
+ Never fires in visitor mode.
36
+
37
+ #### Returns
38
+
39
+ `Promise`\<[`TMissionOrBadge`](../interfaces/TMissionOrBadge.md)[]\>
40
+
41
+ Promise resolving to the current list of
42
+ missions visible to the user. Empty array if
43
+ the user has no missions (or if the visitor
44
+ proxy user has none configured).
45
+
46
+ #### Remarks
47
+
48
+ **Subscription model (`onUpdate`)**
49
+ The callback receives the FULL refreshed mission array (never a
50
+ diff/patch). Each subsequent call to `getMissions({ onUpdate })`
51
+ REPLACES the prior callback — only one active subscriber at a time.
52
+ Pass `onUpdate: undefined` (or omit it) to keep the prior callback in
53
+ place; the callback is never auto-cleared.
54
+
55
+ **Update triggers** — the callback fires when:
56
+ 1. **Mutation responses**: `requestMissionOptIn(...)` or
57
+ `requestMissionClaimReward(...)` resolves (any `err_code`).
58
+ 2. **Asynchronous server pushes**: a user activity (deposit, bet,
59
+ login, etc.) advances task progress on a task configured to push
60
+ updates, or completes a mission.
61
+ 3. **Visibility changes**: the user's level changes, or other
62
+ gamification visibility tags change.
63
+
64
+ Operator-side BO mission-config edits do NOT push to connected
65
+ clients — those changes surface only on the next cache miss (after
66
+ the 30 s TTL) or alongside the next trigger from (1)–(3).
67
+
68
+ **What's in the returned list / what's filtered server-side**
69
+ The response is pre-filtered by the server. Missions EXCLUDED before
70
+ reaching the SDK:
71
+ - Missions in `DRAFT` or `ARCHIVED` status (see [AchievementStatus](../enumerations/AchievementStatus.md)).
72
+ - Missions where the user fails visibility conditions. Exception:
73
+ completed missions may remain visible after the user no longer
74
+ qualifies (configurable per-brand).
75
+ - `FEATURED_MANUALLY` missions that are still locked — they appear
76
+ only after the user unlocks them.
77
+ - Locked missions configured to hide while locked — UNLESS the
78
+ mission is configured to expose immediately on unlock (then the
79
+ locked mission is included as a teaser).
80
+ - `RECURRING` missions between cycles, until the next cycle starts.
81
+ - `RECURRING_QUANTITY` missions outside their `active_from_ts` /
82
+ `active_till_ts` window.
83
+
84
+ Client-side filtering you may still want: missions with
85
+ `only_in_custom_section: true` are intended for their custom-section
86
+ view only and should be hidden from the main mission list.
87
+
88
+ **Reading state from the returned mission**
89
+ Drive availability chips ("missed", "coming soon", "needs opt-in",
90
+ "in progress", "expired") from `availability_status` (enum
91
+ [AchievementAvailabilityStatus](../enumerations/AchievementAvailabilityStatus.md)) — it's the canonical derived
92
+ state and reflects all server-side timing/visibility rules in one
93
+ field. For time-limited and recurring missions, `dt_start` doubles
94
+ as the opt-in timestamp (for opt-in missions) or unlock timestamp
95
+ (for previously-locked missions); the expiration of a time-limited
96
+ mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
97
+ is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
98
+ is no longer meaningful once the mission's `active_till_ts` has
99
+ passed.
100
+
101
+ **Refresh after a mutation**
102
+ After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`
103
+ resolves, the SDK auto-refreshes the mission cache; the `onUpdate`
104
+ callback fires with the new array shortly after. `is_opted_in`,
105
+ `progress`, and `is_completed` flip on the refreshed mission — do
106
+ NOT mutate them optimistically while the round-trip is pending.
107
+ Render any pending state from your own loading flag.
108
+
109
+ **UI guidance**: see [UI Guide — `getMissions`](../../ui/missions/UIGuide_getMissions.md).
110
+
111
+ #### Example
112
+
113
+ ```ts
114
+ // 1. Initial fetch + subscribe to live updates
115
+ const missions = await window._smartico.api.getMissions({
116
+ onUpdate: (refreshed) => {
117
+ console.log('[smartico] mission list refreshed — re-render the entire mission list UI from this array, do not merge with prior state:', refreshed);
118
+
119
+ // 2. onUpdate fires for: opt-in/claim responses, task-progress
120
+ // pushes that complete a mission or move a "pushToClient" task,
121
+ // and user-level changes. Treat each call as authoritative.
122
+ const claimable = refreshed.filter(m =>
123
+ m.is_completed && m.requires_prize_claim && !m.prize_claimed_date_ts,
124
+ );
125
+ if (claimable.length > 0) {
126
+ console.log('[smartico] there are unclaimed mission prizes — surface a "Claim" CTA on each of these missions:', claimable.map(m => m.id));
127
+ }
128
+ },
129
+ });
130
+
131
+ // 3. Filter/render from the returned list. The server already excludes
132
+ // DRAFT/ARCHIVED missions and ones the user can't see. You may need
133
+ // client-side filters for view-specific concerns (custom sections,
134
+ // completed/missed tabs).
135
+ const generalView = missions
136
+ .filter(m => !m.only_in_custom_section)
137
+ .sort((a, b) => (a.position ?? 0) - (b.position ?? 0));
138
+
139
+ console.log('[smartico] initial mission list ready — render', generalView.length, 'missions sorted by position');
140
+
141
+ // 4. Visitor-mode equivalent: onUpdate is accepted but never fires.
142
+ // Re-poll if you need fresh data.
143
+ // const visitorMissions = await window._smartico.vapi('EN').getMissions();
144
+ // console.log('[smartico] visitor missions are the brand proxy user\'s — per-user fields are not meaningful');
145
+ ```
146
+
147
+ ***
148
+
149
+ ### getBadges()
150
+
151
+ > **getBadges**(): `Promise`\<[`TMissionOrBadge`](../interfaces/TMissionOrBadge.md)[]\>
152
+
153
+ Returns all the badges available to the current user.
154
+
155
+ Badges are completion-tracked achievements that auto-unlock once the user
156
+ meets their criteria — there is no opt-in step, no claim step, and no
157
+ task-description reveal. Contrast with [getMissions](#getmissions), which returns
158
+ the same `TMissionOrBadge[]` shape but represents explicit opt-in flows.
159
+
160
+ #### Returns
161
+
162
+ `Promise`\<[`TMissionOrBadge`](../interfaces/TMissionOrBadge.md)[]\>
163
+
164
+ Promise resolving to `TMissionOrBadge[]`. Every item has
165
+ `type === 'badge'`. Cached for 30 s under the `Badges` key.
166
+
167
+ #### Remarks
168
+
169
+ **Why no `onUpdate` callback?**
170
+ Unlike `getMissions({ onUpdate })`, this method does NOT accept an
171
+ `onUpdate` subscription. Internally the SDK never refreshes the `Badges`
172
+ cache from server pushes: the achievement-related push events
173
+ (mission opt-in / claim / reload) refresh the missions cache, NOT
174
+ the badges cache. The badges cache is flushed only by:
175
+ - its 30-second TTL
176
+ - a full SDK cache wipe at login / logout
177
+
178
+ **How to refresh the badge list**
179
+ If you need near-live badge state, poll manually after the TTL expires.
180
+ The first call inside the 30 s window returns the cached payload; the
181
+ first call after the TTL triggers a fresh server round-trip. Example:
182
+ ```ts
183
+ setInterval(async () => {
184
+ const badges = await window._smartico.api.getBadges();
185
+ console.log('[smartico] badge list polled — re-render badge grid from this array', badges);
186
+ }, 30_000);
187
+ ```
188
+ Alternatively, re-fetch on a domain event your app already handles
189
+ (e.g. after the user finishes a game round or claims a bonus).
190
+
191
+ **Differences from missions** (same `TMissionOrBadge` shape, different
192
+ feature)
193
+ The opt-in, claim, recurring-cycle, and unlock-description fields on
194
+ the returned objects are not populated for badges; treat their values
195
+ as undefined / default. Time windows are absolute calendar timestamps
196
+ (`active_from_ts` / `active_till_ts`), not opt-in-relative durations —
197
+ drive availability chips from the SDK-computed `badgeTimeLimitState`
198
+ (enum [BadgesTimeLimitStates](../enumerations/BadgesTimeLimitStates.md)), not `time_limit_ms`. Locking for
199
+ badges is purely time-based: `is_locked` is `true` only when
200
+ `badgeTimeLimitState === BadgesTimeLimitStates.BeforeStartDate` (the
201
+ time window hasn't started yet). The primary navigation field is
202
+ `category_ids` — call [getAchCategories](#getachcategories) to resolve category
203
+ metadata and group badges by category.
204
+
205
+ **Idempotency / Side effects**: fetch-only; safe to call repeatedly.
206
+ The cache layer deduplicates concurrent calls within the TTL window.
207
+
208
+ **UI guidance**: see [UI Guide — `getBadges`](../../ui/missions/UIGuide_getBadges.md).
209
+
210
+ #### Example
211
+
212
+ ```ts
213
+ const [badges, categories] = await Promise.all([
214
+ window._smartico.api.getBadges(),
215
+ window._smartico.api.getAchCategories(),
216
+ ]);
217
+
218
+ console.log('[smartico] badges fetched — render grouped grid with', badges.length, 'badges across', categories.length, 'categories');
219
+
220
+ for (const category of categories) {
221
+ const inCategory = badges.filter(b => b.category_ids?.includes(category.id));
222
+ const completed = inCategory.filter(b => b.is_completed).length;
223
+ console.log(`[smartico] render category section "${category.name}" header showing ${completed}/${inCategory.length}`);
224
+
225
+ for (const badge of inCategory) {
226
+ // Use badgeTimeLimitState (not time_limit_ms) for availability chip
227
+ if (badge.badgeTimeLimitState === 0) { // BadgesTimeLimitStates.BeforeStartDate
228
+ console.log('[smartico] badge not yet started — render grayscaled card with "Starts on" chip for badge', badge.id);
229
+ } else if (badge.is_completed) {
230
+ console.log('[smartico] badge completed — render with completed styling and check-mark for badge', badge.id);
231
+ } else {
232
+ console.log('[smartico] badge in progress — render with stage counter (completed_tasks / total) for badge', badge.id);
233
+ }
234
+ }
235
+ }
236
+
237
+ // No onUpdate available — poll if live state matters
238
+ setInterval(async () => {
239
+ try {
240
+ const fresh = await window._smartico.api.getBadges();
241
+ console.log('[smartico] badge poll tick — diff against previous list and re-render any changed badge cards', fresh);
242
+ } catch (e) {
243
+ console.error('[smartico] badge poll failed — keep showing last known state, retry on next tick:', e);
244
+ }
245
+ }, 30_000);
246
+ ```
247
+
248
+ ***
249
+
250
+ ### getAchCategories()
251
+
252
+ > **getAchCategories**(): `Promise`\<[`TAchCategory`](../interfaces/TAchCategory.md)[]\>
253
+
254
+ Returns the list of active mission/badge categories configured for the current label.
255
+ Categories are operator-defined groupings used to organize missions and badges into
256
+ sections, tabs, or filter chips in the gamification UI. The same category list serves
257
+ BOTH missions and badges — there is no separate "mission categories" vs "badge
258
+ categories" split on the server.
259
+
260
+ #### Returns
261
+
262
+ `Promise`\<[`TAchCategory`](../interfaces/TAchCategory.md)[]\>
263
+
264
+ Array of `{ id, name, order }`. Empty array if no active categories are
265
+ configured for the label. `name` is pre-translated. Order is NOT applied — caller
266
+ must sort.
267
+
268
+ #### Remarks
269
+
270
+ **What categories are**
271
+ - Operator-defined groupings, configured per-label by the brand operator.
272
+ Only active categories are returned; inactive/deleted ones are filtered out.
273
+ - Each `TAchCategory` exposes `{ id, name, order }`. `name` is the display label;
274
+ `order` is the relative position (lower = appears first).
275
+ - The same array covers BOTH missions and badges — categories are not filtered by
276
+ entity type on the server.
277
+
278
+ **Localization / translation**
279
+ - `name` is **pre-translated server-side** to the authenticated user's stored language.
280
+ In visitor mode, the language passed to `_smartico.vapi(lang)` drives the
281
+ translation. Consumers never need to translate `name` themselves.
282
+ - Fallback if no translation exists for the user's language: the brand's EN value
283
+ is returned. The field is never null.
284
+
285
+ **Sort order**
286
+ The server does NOT pre-sort. Sort client-side before rendering:
287
+ `categories.sort((a, b) => a.order - b.order)`.
288
+
289
+ **How missions/badges join to categories**
290
+ Each `TMissionOrBadge` exposes `category_ids: number[]` (zero-or-more,
291
+ many-to-many). A single mission/badge can belong to multiple categories
292
+ simultaneously, or to none. To render a "category → items" view:
293
+ `missions.filter(m => m.category_ids.includes(cat.id))`.
294
+
295
+ **Uncategorized items**
296
+ Items with `category_ids: []` are NOT represented by a synthetic "Other" entry.
297
+ If your UI needs one, generate it client-side by checking
298
+ `item.category_ids.length === 0`.
299
+
300
+ **Empty categories**
301
+ A category may be returned even if zero missions/badges reference it. Filter
302
+ out empty categories on the consumer side if you don't want to render section
303
+ headers for them.
304
+
305
+ **Refresh cadence / cache**
306
+ - The SDK caches the response for 30 seconds. Subsequent calls within that
307
+ window return the cached array without a network round-trip.
308
+ - The cache is NOT invalidated by mission/badge push events — operator-driven
309
+ category changes propagate at the next 30 s cache miss.
310
+ - Cache is fully cleared on login / logout.
311
+ - In **visitor mode** additional server-side caching applies on top of the
312
+ SDK cache; worst-case staleness for an edited/added category is on the order
313
+ of a few minutes for anonymous viewers.
314
+
315
+ **Idempotency**: safe. Read-only metadata fetch. Cache de-duplicates concurrent calls.
316
+
317
+ **Side effects**: none — pure metadata read.
318
+
319
+ **UI guidance**: see [UI Guide — `getAchCategories`](../../ui/missions/UIGuide_getAchCategories.md).
320
+
321
+ #### Example
322
+
323
+ ```ts
324
+ const categories = await window._smartico.api.getAchCategories();
325
+
326
+ if (categories.length === 0) {
327
+ console.log('[smartico] no categories configured — render missions/badges as a flat list without section headers');
328
+ } else {
329
+ const sorted = [...categories].sort((a, b) => a.order - b.order);
330
+ console.log('[smartico] categories loaded — render one tab/section per entry in this order:', sorted.map(c => c.name));
331
+
332
+ // Join to missions: render each category as a section
333
+ const missions = await window._smartico.api.getMissions();
334
+ for (const cat of sorted) {
335
+ const items = missions.filter(m => m.category_ids.includes(cat.id));
336
+ if (items.length === 0) {
337
+ console.log('[smartico] category has no missions — skip rendering its section header:', cat.name);
338
+ continue;
339
+ }
340
+ console.log(`[smartico] render section "${cat.name}" with ${items.length} mission(s)`);
341
+ }
342
+
343
+ // Uncategorized items: surface in a caller-provided "Other" bucket if needed
344
+ const uncategorized = missions.filter(m => m.category_ids.length === 0);
345
+ if (uncategorized.length > 0) {
346
+ console.log('[smartico] uncategorized missions exist — render a caller-provided "Other" section; server does NOT return id:-1:', uncategorized.length);
347
+ }
348
+ }
349
+
350
+ // Visitor mode — same shape, language driven by vapi(lang) argument
351
+ const visitorCats = await window._smartico.vapi('DE').getAchCategories();
352
+ console.log('[smartico] visitor-mode categories (names translated to DE):', visitorCats);
353
+ ```
354
+
355
+ ***
356
+
357
+ ### requestMissionOptIn()
358
+
359
+ > **requestMissionOptIn**(`mission_id`): `Promise`\<[`TMissionOptInResult`](../interfaces/TMissionOptInResult.md)\>
360
+
361
+ Opt the current user in to a mission. The mission must have
362
+ `is_requires_optin: true` (from `getMissions()`) and must not already
363
+ be opted-in or locked. After a successful opt-in, the user's task
364
+ progress starts counting toward this mission — events fired BEFORE
365
+ opt-in do not count retroactively (except `UNLOCK_ACHIEVEMENT` tasks,
366
+ which are exempt and can fire pre-opt-in).
367
+
368
+ #### Parameters
369
+
370
+ ##### mission\_id
371
+
372
+ `number`
373
+
374
+ The mission `id` (from `getMissions()`)
375
+
376
+ #### Returns
377
+
378
+ `Promise`\<[`TMissionOptInResult`](../interfaces/TMissionOptInResult.md)\>
379
+
380
+ `{ err_code, err_message }`; success when `err_code === 0`
381
+
382
+ #### Remarks
383
+
384
+ **Preconditions**
385
+ Only call when the mission has `is_requires_optin === true`,
386
+ `is_opted_in === false`, and `is_locked === false`. Calling on a
387
+ mission that does not require opt-in is wasted; calling twice returns
388
+ `40010`.
389
+
390
+ **Error codes** (in `err_code`)
391
+ - `0` — success; task progress counting begins
392
+ - `105` — wrong mission id (different label) OR visibility conditions
393
+ not met. Same code covers both; use `err_message` to disambiguate.
394
+ - `40010` — already opted-in. Safe to treat as "no-op success"; usually
395
+ means local mission state was stale (e.g. user opted in from another
396
+ session/tab).
397
+ - `40013` — mission not opt-in-able: missing `requires_optin`, in
398
+ DRAFT/ARCHIVED state, or outside its `active_from_ts` /
399
+ `active_till_ts` window.
400
+ - `40014` — mission is locked; user has unlock-tasks remaining.
401
+ Surface the mission's `unlock_mission_description` to guide them.
402
+ - other non-zero — generic server error. Surface `err_message` if any.
403
+
404
+ **Time-limited missions**
405
+ For missions with `time_limit_ms > 0`, the countdown begins at opt-in
406
+ time, not at mission creation. Server records expiration as
407
+ `optin_date + time_limit_ms`.
408
+
409
+ **Refresh after success**
410
+ The SDK refreshes its mission cache automatically on opt-in response;
411
+ any `onUpdate` callback passed to a prior `getMissions({ onUpdate })`
412
+ fires with the new state shortly after. No manual re-fetch needed.
413
+
414
+ **Idempotency**: not idempotent. A second call returns `40010`. Guard
415
+ the call site against double-clicks.
416
+
417
+ **Side effects**: does NOT award points / badges / levels directly.
418
+ Rewards come from task completion, which is itself gated on opt-in.
419
+ May affect visibility of other missions whose visibility conditions
420
+ depend on this opt-in.
421
+
422
+ **UI guidance**: see [UI Guide — `requestMissionOptIn`](../../ui/missions/UIGuide_requestMissionOptIn.md).
423
+
424
+ **Visitor mode: not supported**
425
+
426
+ #### Example
427
+
428
+ ```ts
429
+ const missions = await window._smartico.api.getMissions({
430
+ onUpdate: (m) => console.log('[smartico] mission list updated — re-render mission UI from this new array', m),
431
+ });
432
+ const mission = missions.find(m => m.id === missionId);
433
+
434
+ if (!mission || !mission.is_requires_optin || mission.is_opted_in || mission.is_locked) {
435
+ console.log('[smartico] opt-in not applicable — keep UI as-is');
436
+ return;
437
+ }
438
+
439
+ console.log('[smartico] opt-in starting — show loading spinner on opt-in button and disable it to prevent double-clicks');
440
+ const r = await window._smartico.api.requestMissionOptIn(mission.id);
441
+ console.log('[smartico] opt-in response received — clear loading spinner');
442
+
443
+ if (r.err_code === 0 || r.err_code === 40010) {
444
+ console.log('[smartico] opt-in succeeded (or was already done) — onUpdate above will fire with refreshed mission state; no manual re-fetch needed');
445
+ } else if (r.err_code === 40014) {
446
+ console.error('[smartico] mission is locked — surface the unlock description as guidance:', mission.unlock_mission_description);
447
+ } else {
448
+ console.error('[smartico] opt-in failed — show an error toast with this message to the user:', r.err_message);
449
+ }
450
+ ```
451
+
452
+ ***
453
+
454
+ ### requestMissionClaimReward()
455
+
456
+ > **requestMissionClaimReward**(`mission_id`, `ach_completed_id`): `Promise`\<[`TMissionClaimRewardResult`](../interfaces/TMissionClaimRewardResult.md)\>
457
+
458
+ Claim the prize for a completed mission. This is the step that runs
459
+ AFTER `requestMissionOptIn()` (when applicable) and AFTER the user has
460
+ completed all of the mission's tasks. Only call when the mission has
461
+ `requires_prize_claim === true`, `is_completed === true`, and the prize
462
+ has not already been claimed.
463
+
464
+ The points / bonuses / badge grants associated with the mission are
465
+ awarded server-side synchronously inside this call (before the response
466
+ is returned), so a successful response (`err_code === 0`) means the
467
+ reward has already landed in the user's account.
468
+
469
+ #### Parameters
470
+
471
+ ##### mission\_id
472
+
473
+ `number`
474
+
475
+ The mission `ach_id` (from `getMissions()`).
476
+
477
+ ##### ach\_completed\_id
478
+
479
+ `number`
480
+
481
+ The completion-row identifier, read from
482
+ `mission.ach_completed_id` on the same mission
483
+ object fetched via `getMissions()`. Never
484
+ fabricate or cache across sessions.
485
+
486
+ #### Returns
487
+
488
+ `Promise`\<[`TMissionClaimRewardResult`](../interfaces/TMissionClaimRewardResult.md)\>
489
+
490
+ `{ err_code, err_message }`; success when `err_code === 0`
491
+ (or `40017` when treated as idempotent no-op).
492
+
493
+ #### Remarks
494
+
495
+ **Preconditions**
496
+ Only call when, on the mission object from `getMissions()`:
497
+ - `is_completed === true`
498
+ - `requires_prize_claim === true`
499
+ - `prize_claimed_date_ts == null` (i.e. not already claimed)
500
+ - `prize_claim_expiration_date` is `null` OR still in the future
501
+
502
+ The `ach_completed_id` argument must be passed straight from the same
503
+ mission object (`mission.ach_completed_id`). It is a server-side primary
504
+ key identifying the specific completion row; the SDK consumer should
505
+ never synthesise or cache it across sessions — always re-read it from a
506
+ fresh `getMissions()` result.
507
+
508
+ **Error codes** (in `err_code`)
509
+ - `0` — success; the prize was claimed and rewards have been credited.
510
+ - `1` — generic server error. Covers several distinct underlying
511
+ conditions, all collapsed into the same code: stale or wrong
512
+ `ach_completed_id` (does not match user / mission), the mission no
513
+ longer requiring a prize claim, the mission being archived/draft,
514
+ label mismatch, or the completion being too old (server enforces a
515
+ freshness window of several months). Recovery: re-fetch missions
516
+ with `getMissions()`; if the mission still appears claimable,
517
+ surface a generic error.
518
+ - `40015` — claim window expired (`prize_claim_expiration_date` has
519
+ passed). Show a "claim period ended" message; do not retry.
520
+ - `40016` — mission is not completed yet. Indicates a race or a stale
521
+ local cache. Re-fetch via `getMissions()`; if `is_completed` is still
522
+ false, the UI should hide the claim button.
523
+ - `40017` — prize already claimed. Treat as idempotent success: refresh
524
+ the mission list (auto-refresh will fire) and hide the claim button.
525
+ Usually means another tab/session already claimed it.
526
+ - other non-zero — generic server error. Surface `err_message` if any.
527
+
528
+ **Recurring missions**
529
+ The server transparently handles both one-shot and recurring mission
530
+ completions. The SDK consumer passes a single `ach_completed_id`
531
+ regardless of mission type; the server resolves the correct completion.
532
+
533
+ **Refresh after success**
534
+ On any claim response (success OR failure), the SDK automatically
535
+ re-fetches the mission list and fires any `onUpdate` callback
536
+ registered via `getMissions({ onUpdate })`. No manual re-fetch needed.
537
+ Note: points balance, badges, and level state arrive through their
538
+ own push channels — subscribe to them separately if your UI shows
539
+ those values.
540
+
541
+ **Idempotency**: not idempotent at the row level. A second call on the
542
+ same `ach_completed_id` returns `40017` (already claimed). For a stale
543
+ `ach_completed_id` the second call returns `1`. Guard the call site
544
+ against double-clicks; the SDK does not enforce its own in-flight lock.
545
+
546
+ **Side effects** (consumer-observable effects of a successful claim):
547
+ - Points credited to the user's balance.
548
+ - CRM-rule activities executed (may grant bonuses, badges; may unlock
549
+ follow-up missions, which arrive as a later mission auto-refresh).
550
+ - Analytics / automation events fired downstream; not directly observable
551
+ in the response, but visible via the mission auto-refresh and any
552
+ subsequent bonus / badge updates.
553
+
554
+ **UI guidance**: see [UI Guide — `requestMissionClaimReward`](../../ui/missions/UIGuide_requestMissionClaimReward.md).
555
+
556
+ #### Example
557
+
558
+ ```ts
559
+ const missions = await window._smartico.api.getMissions({
560
+ onUpdate: (m) => console.log('[smartico] mission list updated — re-render mission UI from this new array', m),
561
+ });
562
+ const mission = missions.find(m => m.ach_id === missionId);
563
+
564
+ if (
565
+ !mission ||
566
+ !mission.is_completed ||
567
+ !mission.requires_prize_claim ||
568
+ mission.prize_claimed_date_ts ||
569
+ (mission.prize_claim_expiration_date && Date.now() >= mission.prize_claim_expiration_date)
570
+ ) {
571
+ console.log('[smartico] claim not applicable — keep claim button hidden');
572
+ return;
573
+ }
574
+
575
+ console.log('[smartico] claim starting — show loading spinner on claim button and disable it to prevent double-clicks');
576
+ const r = await window._smartico.api.requestMissionClaimReward(mission.ach_id, mission.ach_completed_id);
577
+ console.log('[smartico] claim response received — clear loading spinner');
578
+
579
+ if (r.err_code === 0 || r.err_code === 40017) {
580
+ console.log('[smartico] claim succeeded (or was already claimed) — points/bonuses are credited; mission list auto-refresh will fire via the onUpdate above; hide the claim button');
581
+ } else if (r.err_code === 40015) {
582
+ console.error('[smartico] claim window expired — show a "claim period ended" message and remove the claim button:', mission.prize_claim_expiration_date);
583
+ } else if (r.err_code === 40016) {
584
+ console.error('[smartico] mission reported as not completed by server — local state was stale; auto-refresh will reconcile, do not retry');
585
+ } else {
586
+ console.error('[smartico] claim failed — show an error toast with this message to the user (and re-fetch missions to recover from a stale ach_completed_id):', r.err_message);
587
+ }
588
+ ```
589
+
590
+ ***