@xpoz/xpoz 0.3.2 → 0.4.0

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.
package/README.md CHANGED
@@ -30,7 +30,7 @@ The SDK wraps Xpoz's [MCP](https://modelcontextprotocol.io) server, abstracting
30
30
 
31
31
  ## Features
32
32
 
33
- - **30 data methods** across Twitter, Instagram, and Reddit
33
+ - **40 data methods** across Twitter, Instagram, Reddit, and TikTok
34
34
  - **Fully async** — all methods return `Promise<T>`
35
35
  - **Automatic operation polling** — long-running queries are abstracted away
36
36
  - **Response types** — choose between fast (immediate), paging (full pagination), or CSV export
@@ -38,7 +38,7 @@ The SDK wraps Xpoz's [MCP](https://modelcontextprotocol.io) server, abstracting
38
38
  - **CSV export** — `exportCsv()` on any paginated result
39
39
  - **Field selection** — request only the fields you need
40
40
  - **TypeScript-first** — fully typed results with autocomplete support
41
- - **Namespaced API** — `client.twitter.*`, `client.instagram.*`, `client.reddit.*`
41
+ - **Namespaced API** — `client.twitter.*`, `client.instagram.*`, `client.reddit.*`, `client.tiktok.*`, `client.tracking.*`
42
42
 
43
43
  ## Quick Start
44
44
 
@@ -200,10 +200,12 @@ The following methods accept both `responseType` and `limit`:
200
200
  - `twitter.getPostsByAuthor()`, `twitter.searchPosts()`, `twitter.getUsersByKeywords()`
201
201
  - `instagram.getPostsByUser()`, `instagram.searchPosts()`, `instagram.getUsersByKeywords()`
202
202
  - `reddit.searchPosts()`
203
+ - `tiktok.getPostsByUser()`, `tiktok.searchPosts()`, `tiktok.getUsersByKeywords()`
203
204
 
204
205
  These methods accept `limit` only:
205
206
 
206
207
  - `twitter.searchUsers()`, `instagram.searchUsers()`, `reddit.searchUsers()`, `reddit.searchSubreddits()`
208
+ - `tiktok.searchUsers()`
207
209
 
208
210
  ## Query Syntax
209
211
 
@@ -574,6 +576,122 @@ const subs = await client.reddit.getSubredditsByKeywords("cryptocurrency");
574
576
 
575
577
  ---
576
578
 
579
+ ### TikTok — `client.tiktok`
580
+
581
+ #### `getUser(identifier, options?) -> Promise<TiktokUser>`
582
+
583
+ ```typescript
584
+ const user = await client.tiktok.getUser("charlidamelio");
585
+ console.log(`${user.nickname} — ${user.followerCount?.toLocaleString()} followers`);
586
+
587
+ // By numeric ID
588
+ const user = await client.tiktok.getUser("123456789", { identifierType: "id" });
589
+ ```
590
+
591
+ #### `searchUsers(name, options?) -> Promise<TiktokUser[]>`
592
+
593
+ Search users by name. Use `limit` to adjust the number of results.
594
+
595
+ ```typescript
596
+ const users = await client.tiktok.searchUsers("charli");
597
+ const topFive = await client.tiktok.searchUsers("charli", { limit: 5 });
598
+ ```
599
+
600
+ #### `getUsersByKeywords(query, options?) -> Promise<PaginatedResult<TiktokUser>>`
601
+
602
+ Find users who authored posts matching a keyword query. Supports `responseType` and `limit`.
603
+
604
+ ```typescript
605
+ const users = await client.tiktok.getUsersByKeywords('"machine learning"', {
606
+ responseType: ResponseType.Fast,
607
+ limit: 20,
608
+ });
609
+ ```
610
+
611
+ #### `getPostsByIds(postIds, options?) -> Promise<TiktokPost[]>`
612
+
613
+ Get 1-100 posts by their IDs.
614
+
615
+ ```typescript
616
+ const posts = await client.tiktok.getPostsByIds(["7123456789012345678"]);
617
+ ```
618
+
619
+ #### `getPostsByUser(identifier, options?) -> Promise<PaginatedResult<TiktokPost>>`
620
+
621
+ Get all posts by a user. Supports `responseType` and `limit`.
622
+
623
+ ```typescript
624
+ const results = await client.tiktok.getPostsByUser("charlidamelio", {
625
+ startDate: "2025-01-01",
626
+ responseType: ResponseType.Fast,
627
+ limit: 50,
628
+ });
629
+ ```
630
+
631
+ #### `searchPosts(query, options?) -> Promise<PaginatedResult<TiktokPost>>`
632
+
633
+ Full-text search with filters. Supports `responseType` and `limit`.
634
+
635
+ ```typescript
636
+ const results = await client.tiktok.searchPosts("travel vlog", {
637
+ startDate: "2025-01-01",
638
+ responseType: ResponseType.Fast,
639
+ limit: 30,
640
+ });
641
+ ```
642
+
643
+ #### `getComments(postId, options?) -> Promise<PaginatedResult<TiktokComment>>`
644
+
645
+ ```typescript
646
+ const comments = await client.tiktok.getComments("7123456789012345678");
647
+ ```
648
+
649
+ ---
650
+
651
+ ### Tracking — `client.tracking`
652
+
653
+ Manage tracked items (keywords, users, subreddits) that Xpoz monitors on your behalf. Import the enums to build items:
654
+
655
+ ```typescript
656
+ import { XpozClient, TrackedItemType, TrackedItemPlatform } from "@xpoz/xpoz";
657
+ ```
658
+
659
+ #### `getTrackedItems() -> Promise<TrackedItem[]>`
660
+
661
+ List all currently tracked items on your account.
662
+
663
+ ```typescript
664
+ const items = await client.tracking.getTrackedItems();
665
+ for (const item of items) {
666
+ console.log(`${item.platform} / ${item.type}: ${item.phrase}`);
667
+ }
668
+ ```
669
+
670
+ #### `addTrackedItems(items) -> Promise<AddTrackedItemsResult>`
671
+
672
+ Add one or more items to track.
673
+
674
+ ```typescript
675
+ const result = await client.tracking.addTrackedItems([
676
+ { phrase: "bitcoin", type: TrackedItemType.Keyword, platform: TrackedItemPlatform.Twitter },
677
+ { phrase: "nasa", type: TrackedItemType.User, platform: TrackedItemPlatform.Instagram },
678
+ ]);
679
+ console.log(`Added ${result.addedCount} items (${result.currentCount}/${result.maxTrackedItems} used)`);
680
+ ```
681
+
682
+ #### `removeTrackedItems(items) -> Promise<RemoveTrackedItemsResult>`
683
+
684
+ Remove one or more tracked items.
685
+
686
+ ```typescript
687
+ const result = await client.tracking.removeTrackedItems([
688
+ { phrase: "bitcoin", type: TrackedItemType.Keyword, platform: TrackedItemPlatform.Twitter },
689
+ ]);
690
+ console.log(`Removed ${result.removedCount} items`);
691
+ ```
692
+
693
+ ---
694
+
577
695
  ## Type Models
578
696
 
579
697
  All fields are optional and typed as their respective TypeScript types. Unknown fields are preserved on the object.
@@ -731,6 +849,88 @@ All fields are optional and typed as their respective TypeScript types. Unknown
731
849
  | `over18` | `boolean` | NSFW flag |
732
850
  | `createdAtDate` | `string` | Creation date |
733
851
 
852
+ ### TiktokPost
853
+
854
+ | Field | Type | Description |
855
+ | ---------------------------- | --------- | ---------------------------- |
856
+ | `id` | `string` | Post ID |
857
+ | `description` | `string` | Post caption/description |
858
+ | `descriptionLanguage` | `string` | Language of description |
859
+ | `userId` | `string` | Author user ID |
860
+ | `username` | `string` | Author username |
861
+ | `nickname` | `string` | Author display name |
862
+ | `likeCount` | `number` | Number of likes |
863
+ | `commentCount` | `number` | Number of comments |
864
+ | `playCount` | `number` | Video play count |
865
+ | `collectCount` | `number` | Number of collects/saves |
866
+ | `downloadCount` | `number` | Number of downloads |
867
+ | `forwardCount` | `number` | Number of forwards/shares |
868
+ | `videoThumbnail` | `string` | Thumbnail URL |
869
+ | `postType` | `number` | Post type code |
870
+ | `isPrivate` | `boolean` | Private post flag |
871
+ | `createdAt` | `string` | Creation timestamp |
872
+ | `createdAtDate` | `string` | Creation date (YYYY-MM-DD) |
873
+
874
+ ### TiktokUser
875
+
876
+ | Field | Type | Description |
877
+ | ---------------- | --------- | ------------------------ |
878
+ | `id` | `string` | User ID |
879
+ | `username` | `string` | Username |
880
+ | `nickname` | `string` | Display name |
881
+ | `signature` | `string` | Bio text |
882
+ | `secUid` | `string` | Secure user ID |
883
+ | `avatar` | `string` | Profile picture URL |
884
+ | `isPrivate` | `boolean` | Private account |
885
+ | `isVerified` | `boolean` | Verified status |
886
+ | `followerCount` | `number` | Number of followers |
887
+ | `followingCount` | `number` | Number of following |
888
+ | `likeCount` | `number` | Total likes received |
889
+ | `postCount` | `number` | Total posts |
890
+ | `language` | `string` | Profile language |
891
+ | `region` | `string` | Account region |
892
+ | `createdAt` | `string` | Account creation date |
893
+
894
+ ### TiktokComment
895
+
896
+ | Field | Type | Description |
897
+ | --------------- | -------- | ------------------------ |
898
+ | `id` | `string` | Comment ID |
899
+ | `postId` | `string` | Parent post ID |
900
+ | `userId` | `string` | Author user ID |
901
+ | `username` | `string` | Author username |
902
+ | `text` | `string` | Comment text |
903
+ | `likeCount` | `number` | Number of likes |
904
+ | `createdAt` | `string` | Creation timestamp |
905
+ | `createdAtDate` | `string` | Creation date (YYYY-MM-DD) |
906
+
907
+ ### TrackedItem
908
+
909
+ | Field | Type | Description |
910
+ | ---------- | ---------------------- | -------------------------------------------------------- |
911
+ | `phrase` | `string` | Keyword, username, or subreddit name to track |
912
+ | `type` | `TrackedItemType` | `"keyword"`, `"user"`, or `"subreddit"` |
913
+ | `platform` | `TrackedItemPlatform` | `"twitter"`, `"instagram"`, `"reddit"`, or `"tiktok"` |
914
+
915
+ ### AddTrackedItemsResult
916
+
917
+ | Field | Type | Description |
918
+ | ----------------- | --------- | ---------------------------------- |
919
+ | `success` | `boolean` | Whether the operation succeeded |
920
+ | `addedCount` | `number` | Number of items added |
921
+ | `message` | `string` | Status message |
922
+ | `currentCount` | `number` | Total tracked items after addition |
923
+ | `maxTrackedItems` | `number` | Plan limit for tracked items |
924
+ | `planName` | `string` | Current plan name |
925
+
926
+ ### RemoveTrackedItemsResult
927
+
928
+ | Field | Type | Description |
929
+ | -------------- | --------- | ------------------------------- |
930
+ | `success` | `boolean` | Whether the operation succeeded |
931
+ | `removedCount` | `number` | Number of items removed |
932
+ | `message` | `string` | Status message |
933
+
734
934
  ### Composite Types
735
935
 
736
936
  **`RedditPostWithComments`** — returned by `getPostWithComments()`:
package/dist/index.cjs CHANGED
@@ -296,7 +296,7 @@ function coerce(value) {
296
296
  }
297
297
 
298
298
  // src/version.ts
299
- var VERSION = "0.3.2";
299
+ var VERSION = "0.4.0";
300
300
 
301
301
  // src/mcp/transport.ts
302
302
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -439,14 +439,14 @@ async function waitForResult(callTool, operationId, timeoutMs = DEFAULT_TIMEOUT_
439
439
  while (true) {
440
440
  const result = await callTool("checkOperationStatus", { operationId });
441
441
  const status = result["status"];
442
- if (status === "failed") {
442
+ if (status === "error") {
443
443
  const error = result["error"] ?? "Unknown error";
444
444
  throw new OperationFailedError(operationId, String(error));
445
445
  }
446
446
  if (status === "cancelled") {
447
447
  throw new OperationCancelledError(operationId);
448
448
  }
449
- if (status === "completed" || "results" in result || "downloadUrl" in result) {
449
+ if (status === "success" || status === "no_data" || "results" in result || "downloadUrl" in result) {
450
450
  return result;
451
451
  }
452
452
  const elapsed = Date.now() - start;
@@ -534,7 +534,13 @@ var BaseNamespace = class {
534
534
  }
535
535
  async callAndMaybePoll(toolName, args) {
536
536
  const result = await this.callTool(toolName, args);
537
- if ("results" in result) {
537
+ if (result["status"] === "error") {
538
+ throw new OperationFailedError(
539
+ "",
540
+ String(result["error"] ?? "Unknown error")
541
+ );
542
+ }
543
+ if (result["status"] === "success" || "results" in result) {
538
544
  return result;
539
545
  }
540
546
  const operationId = result["operationId"];
package/dist/index.d.cts CHANGED
@@ -758,7 +758,7 @@ declare class OperationCancelledError extends XpozError {
758
758
  constructor(operationId: string);
759
759
  }
760
760
 
761
- declare const VERSION = "0.3.2";
761
+ declare const VERSION = "0.4.0";
762
762
 
763
763
  declare function checkForUpdates(): Promise<void>;
764
764
 
package/dist/index.d.ts CHANGED
@@ -758,7 +758,7 @@ declare class OperationCancelledError extends XpozError {
758
758
  constructor(operationId: string);
759
759
  }
760
760
 
761
- declare const VERSION = "0.3.2";
761
+ declare const VERSION = "0.4.0";
762
762
 
763
763
  declare function checkForUpdates(): Promise<void>;
764
764
 
package/dist/index.js CHANGED
@@ -248,7 +248,7 @@ function coerce(value) {
248
248
  }
249
249
 
250
250
  // src/version.ts
251
- var VERSION = "0.3.2";
251
+ var VERSION = "0.4.0";
252
252
 
253
253
  // src/mcp/transport.ts
254
254
  var USER_AGENT = `xpoz-ts-sdk/${VERSION}`;
@@ -391,14 +391,14 @@ async function waitForResult(callTool, operationId, timeoutMs = DEFAULT_TIMEOUT_
391
391
  while (true) {
392
392
  const result = await callTool("checkOperationStatus", { operationId });
393
393
  const status = result["status"];
394
- if (status === "failed") {
394
+ if (status === "error") {
395
395
  const error = result["error"] ?? "Unknown error";
396
396
  throw new OperationFailedError(operationId, String(error));
397
397
  }
398
398
  if (status === "cancelled") {
399
399
  throw new OperationCancelledError(operationId);
400
400
  }
401
- if (status === "completed" || "results" in result || "downloadUrl" in result) {
401
+ if (status === "success" || status === "no_data" || "results" in result || "downloadUrl" in result) {
402
402
  return result;
403
403
  }
404
404
  const elapsed = Date.now() - start;
@@ -486,7 +486,13 @@ var BaseNamespace = class {
486
486
  }
487
487
  async callAndMaybePoll(toolName, args) {
488
488
  const result = await this.callTool(toolName, args);
489
- if ("results" in result) {
489
+ if (result["status"] === "error") {
490
+ throw new OperationFailedError(
491
+ "",
492
+ String(result["error"] ?? "Unknown error")
493
+ );
494
+ }
495
+ if (result["status"] === "success" || "results" in result) {
490
496
  return result;
491
497
  }
492
498
  const operationId = result["operationId"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpoz/xpoz",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "TypeScript SDK for the Xpoz social media intelligence platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",