okdata 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,1329 @@
1
+ """Generated by scripts/generate.ts from @okdata/catalog. Do not edit by hand.
2
+
3
+ The objects endpoints return, as TypedDicts over the JSON: a Post has the same keys on Douyin and on
4
+ YouTube. Keys outside view=compact may be absent, and fields= keeps only what you ask for.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, Dict, List, Literal, Optional, TypedDict
9
+
10
+
11
+ class Account(TypedDict, total=False):
12
+ id: str
13
+ """Account ID on the platform."""
14
+ url: str
15
+ """Profile link."""
16
+ username: Optional[str]
17
+ """Handle, where the platform has one."""
18
+ name: str
19
+ """Display name."""
20
+ bio: Optional[str]
21
+ """Profile bio."""
22
+ avatar_url: Optional[str]
23
+ """Avatar image URL. (view=standard and up)"""
24
+ verified: Optional[bool]
25
+ """Whether the platform shows a verification badge. (view=standard and up)"""
26
+ followers: Optional[int]
27
+ """Followers."""
28
+ following: Optional[int]
29
+ """Accounts it follows."""
30
+ posts: Optional[int]
31
+ """Posts, videos, notes or articles published."""
32
+ likes: Optional[int]
33
+ """Total likes received, where the platform shows it."""
34
+ ext: Dict[str, Any]
35
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
36
+
37
+
38
+ class AccountChange(TypedDict, total=False):
39
+ followers: Optional[float]
40
+ """Change in net followers gained."""
41
+ likes: Optional[float]
42
+ """Change in likes received."""
43
+ comments: Optional[float]
44
+ """Change in comments received."""
45
+ shares: Optional[float]
46
+ """Change in shares received."""
47
+ posts: Optional[float]
48
+ """Change in posts published."""
49
+
50
+
51
+ class AccountGain(TypedDict, total=False):
52
+ followers: Optional[int]
53
+ """Net followers gained; negative when the account lost followers."""
54
+ likes: Optional[int]
55
+ """Likes received."""
56
+ comments: Optional[int]
57
+ """Comments received."""
58
+ shares: Optional[int]
59
+ """Shares received."""
60
+ posts: Optional[int]
61
+ """Posts published."""
62
+
63
+
64
+ class AccountHistory(TypedDict, total=False):
65
+ id: str
66
+ """The account's numeric ID (the one asked about)."""
67
+ name: Optional[str]
68
+ """Display name."""
69
+ url: Optional[str]
70
+ """Profile link."""
71
+ avatar_url: Optional[str]
72
+ """Avatar. (view=standard and up)"""
73
+ days: int
74
+ """How many of the most recent days the figures cover."""
75
+ gained: AccountGain
76
+ """What the account gained over the period."""
77
+ change: AccountChange
78
+ """Each gain against the same length of time before, as a ratio: 0.3 is 30% more, -0.5 is half."""
79
+ totals: Optional[AccountTotals]
80
+ """Totals as of now. (view=standard and up)"""
81
+ ext: Dict[str, Any]
82
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
83
+
84
+
85
+ class AccountOwner(TypedDict, total=False):
86
+ name: Optional[str]
87
+ """The owner's name: a company's or body's full name, or a person's name."""
88
+ type: Optional[Literal["company", "government", "media", "individual", "other"]]
89
+ """What the owner is."""
90
+ registration_id: Optional[str]
91
+ """Registration number (unified social credit code, licence or organisation code); null where none is given."""
92
+ country: Optional[str]
93
+ """Country or region, in the platform's words. (view=standard and up)"""
94
+ verification: Optional[Literal["verified", "unverified", "expired"]]
95
+ """Verification state of the account."""
96
+ verification_type: Optional[str]
97
+ """Kind of verification, in the platform's words; null when not verified. (view=standard and up)"""
98
+ verified_at: Optional[str]
99
+ """Date the verification was granted, as 00:00 UTC. (view=standard and up)"""
100
+ account_id: str
101
+ """ID of the account asked about."""
102
+ account_created_at: Optional[str]
103
+ """Date the account was registered, as 00:00 UTC. (view=standard and up)"""
104
+ authorized_services: Optional[List[str]]
105
+ """Third-party services the account has authorised, in the platform's words. (view=full and up)"""
106
+ ext: Dict[str, Any]
107
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
108
+
109
+
110
+ class AccountRef(TypedDict, total=False):
111
+ id: str
112
+ """Account ID on the platform."""
113
+ username: Optional[str]
114
+ """Handle, where the platform has one."""
115
+ name: Optional[str]
116
+ """Display name."""
117
+ avatar_url: Optional[str]
118
+ """Avatar image URL. (view=standard and up)"""
119
+ followers: Optional[int]
120
+ """Follower count at fetch time. (view=standard and up)"""
121
+ verified: Optional[bool]
122
+ """Whether the platform shows a verification badge. (view=standard and up)"""
123
+
124
+
125
+ class AccountTotals(TypedDict, total=False):
126
+ followers: Optional[int]
127
+ """Followers now. (view=standard and up)"""
128
+ likes: Optional[int]
129
+ """Likes received in all. (view=standard and up)"""
130
+ posts: Optional[int]
131
+ """Posts in all. (view=standard and up)"""
132
+
133
+
134
+ class Ad(TypedDict, total=False):
135
+ id: str
136
+ """Ad ID in the library."""
137
+ url: str
138
+ """Link to the ad in the library."""
139
+ advertiser: AdvertiserRef
140
+ """Who runs the ad."""
141
+ title: Optional[str]
142
+ """Headline, where the ad has one."""
143
+ text: str
144
+ """Ad copy as plain text; empty when the ad has none."""
145
+ format: Optional[Literal["image", "video", "carousel", "text", "dynamic"]]
146
+ """Creative format; dynamic means the platform assembles it per viewer (catalog ads)."""
147
+ images: Optional[List[str]]
148
+ """Image URLs of the creative. (view=standard and up)"""
149
+ videos: Optional[List[str]]
150
+ """Video URLs of the creative. (view=full and up)"""
151
+ landing_url: Optional[str]
152
+ """Where the ad leads. (view=standard and up)"""
153
+ cta: Optional[str]
154
+ """Call-to-action button text. (view=standard and up)"""
155
+ platforms: Optional[List[str]]
156
+ """Where it is delivered, e.g. facebook, instagram. (view=standard and up)"""
157
+ active: Optional[bool]
158
+ """Whether the ad is still running."""
159
+ first_shown_at: Optional[str]
160
+ """First time or day shown, ISO 8601 in UTC."""
161
+ last_shown_at: Optional[str]
162
+ """Last time or day shown, ISO 8601 in UTC."""
163
+ reach: Optional[str]
164
+ """People reached, as the library publishes it: a bracket such as 1K-10K, or a count (the EU reach of a Meta ad); null where none is published. (view=standard and up)"""
165
+ ext: Dict[str, Any]
166
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
167
+
168
+
169
+ class Advertiser(TypedDict, total=False):
170
+ id: str
171
+ """Advertiser ID in the library."""
172
+ url: str
173
+ """The advertiser's page in the library."""
174
+ name: str
175
+ """The name the library shows, often the legal entity."""
176
+ region: Optional[str]
177
+ """Country or region it is registered in (ISO code)."""
178
+ ads: Optional[int]
179
+ """The library's estimate of how many ads it has. (view=standard and up)"""
180
+ ext: Dict[str, Any]
181
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
182
+
183
+
184
+ class AdvertiserRef(TypedDict, total=False):
185
+ id: Optional[str]
186
+ """The advertiser's ID in the library."""
187
+ name: Optional[str]
188
+ """The advertiser's name."""
189
+ url: Optional[str]
190
+ """The advertiser's page. (view=standard and up)"""
191
+
192
+
193
+ class Audience(TypedDict, total=False):
194
+ creator_id: str
195
+ """The creator ID asked about."""
196
+ measured_at: Optional[str]
197
+ """The day the figures are of, as 00:00 China time."""
198
+ gender: Optional[List[AudienceSegment]]
199
+ """By gender."""
200
+ age: Optional[List[AudienceSegment]]
201
+ """By age group."""
202
+ province: Optional[List[AudienceSegment]]
203
+ """By province."""
204
+ city: Optional[List[AudienceSegment]]
205
+ """By city, the largest only."""
206
+ interest: Optional[List[AudienceSegment]]
207
+ """By interest."""
208
+ device: Optional[List[AudienceSegment]]
209
+ """By phone brand."""
210
+ city_tier: Optional[List[AudienceSegment]]
211
+ """By city tier."""
212
+ crowd: Optional[List[AudienceSegment]]
213
+ """By the consumer groups the platform sorts people into."""
214
+ purchase_category: Optional[List[AudienceSegment]]
215
+ """By the category of goods bought."""
216
+ purchase_amount: Optional[List[AudienceSegment]]
217
+ """By the amount spent per order."""
218
+ ext: Dict[str, Any]
219
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
220
+
221
+
222
+ class AudienceSegment(TypedDict, total=False):
223
+ name: str
224
+ """The segment, in the platform's words (genders come as lower-case English)."""
225
+ share: Optional[float]
226
+ """The segment's share of the segments listed, 0 to 1."""
227
+ count: Optional[int]
228
+ """Followers in the segment."""
229
+
230
+
231
+ class BrandBenchmark(TypedDict, total=False):
232
+ scope: Literal["all", "top3", "top5", "top10", "top15", "top30"]
233
+ """Which brands the average is over: the whole industry, or its top 3, 5, 10, 15 or 30."""
234
+ search_index: Optional[int]
235
+ """Their daily average search index."""
236
+ content_index: Optional[int]
237
+ """Their daily average content index."""
238
+ spread_index: Optional[int]
239
+ """Their daily average spread index."""
240
+
241
+
242
+ class BrandHistory(TypedDict, total=False):
243
+ brand: str
244
+ """The brand's name."""
245
+ category: Optional[str]
246
+ """The industry the platform files the brand under, in its words."""
247
+ points: List[BrandPoint]
248
+ """One entry a day, oldest first."""
249
+ ext: Dict[str, Any]
250
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
251
+
252
+
253
+ class BrandMetrics(TypedDict, total=False):
254
+ brand: str
255
+ """The brand's name."""
256
+ category: Optional[str]
257
+ """The industry the platform files the brand under, in its words."""
258
+ search_index: Optional[int]
259
+ """Daily average search index over the period."""
260
+ content_index: Optional[int]
261
+ """Daily average content index over the period."""
262
+ spread_index: Optional[int]
263
+ """Daily average spread index over the period."""
264
+ benchmarks: Optional[List[BrandBenchmark]]
265
+ """The same averages for the whole industry and for its leading brands."""
266
+ ext: Dict[str, Any]
267
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
268
+
269
+
270
+ class BrandPoint(TypedDict, total=False):
271
+ date: str
272
+ """The day: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
273
+ search_index: Optional[int]
274
+ """Search index: search interest in the brand, not a count of searches."""
275
+ content_index: Optional[int]
276
+ """Content index: how much content there was about the brand, not a count of posts."""
277
+ spread_index: Optional[int]
278
+ """Spread index: how far that content travelled, not a count."""
279
+
280
+
281
+ class CategoryShare(TypedDict, total=False):
282
+ category: str
283
+ """The content category, in the platform's words. (view=standard and up)"""
284
+ share: Optional[float]
285
+ """The category's share of the creator's notes, 0 to 1. (view=standard and up)"""
286
+
287
+
288
+ class ChannelsCollection(TypedDict, total=False):
289
+ id: str
290
+ """The collection's ID; pass it as is to the endpoint that lists its videos."""
291
+ name: str
292
+ """Name of the collection."""
293
+ description: Optional[str]
294
+ """What the collection says it is about; null when nothing."""
295
+ cover_url: Optional[str]
296
+ """Cover image. (view=standard and up)"""
297
+ updated_at: Optional[str]
298
+ """When the collection was last updated."""
299
+ metrics: CollectionMetrics
300
+ """Counts at fetch time."""
301
+ ext: Dict[str, Any]
302
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
303
+
304
+
305
+ class ChannelsShareLink(TypedDict, total=False):
306
+ id: str
307
+ """The video's ID."""
308
+ url: str
309
+ """The share link (weixin.qq.com/sph/…)."""
310
+ ext: Dict[str, Any]
311
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
312
+
313
+
314
+ class CollectionMetrics(TypedDict, total=False):
315
+ videos: Optional[int]
316
+ """Videos in the collection."""
317
+
318
+
319
+ class Comment(TypedDict, total=False):
320
+ id: str
321
+ """Comment ID."""
322
+ post_id: str
323
+ """ID of the post it is under."""
324
+ parent_id: Optional[str]
325
+ """The comment it replies to; null for top-level comments."""
326
+ text: str
327
+ """Comment text."""
328
+ published_at: str
329
+ """When it was posted, ISO 8601 in UTC."""
330
+ author: AccountRef
331
+ """Who wrote it."""
332
+ likes: Optional[int]
333
+ """Likes on the comment."""
334
+ replies: Optional[int]
335
+ """Replies under it."""
336
+ ip_location: Optional[str]
337
+ """Region label the platform shows next to the comment, if any. (view=standard and up)"""
338
+ ext: Dict[str, Any]
339
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
340
+
341
+
342
+ class Community(TypedDict, total=False):
343
+ id: str
344
+ """ID; pass it as is to the endpoints that take one."""
345
+ name: str
346
+ """Name of the community."""
347
+ url: Optional[str]
348
+ """Link to the community."""
349
+ description: Optional[str]
350
+ """What the community says it is about."""
351
+ avatar_url: Optional[str]
352
+ """Icon of the community. (view=standard and up)"""
353
+ nsfw: Optional[bool]
354
+ """Whether it is marked as adult content. (view=standard and up)"""
355
+ created_at: Optional[str]
356
+ """When the community was created. (view=standard and up)"""
357
+ metrics: CommunityMetrics
358
+ """Counts at fetch time."""
359
+ ext: Dict[str, Any]
360
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
361
+
362
+
363
+ class CommunityMetrics(TypedDict, total=False):
364
+ members: Optional[int]
365
+ """Members."""
366
+
367
+
368
+ class ContentShare(TypedDict, total=False):
369
+ name: str
370
+ """The content category, in the platform's words."""
371
+ share: Optional[float]
372
+ """The category's share of the videos counted, 0 to 1."""
373
+ videos: Optional[int]
374
+ """Videos in the category."""
375
+
376
+
377
+ class Creator(TypedDict, total=False):
378
+ id: str
379
+ """The marketplace's creator ID; the other marketplace endpoints take it."""
380
+ url: str
381
+ """The creator's page on the marketplace."""
382
+ account_id: Optional[str]
383
+ """The creator's own account ID on the platform, where the marketplace gives it: on Douyin the sec_uid (MS4w…) that douyin.users.get takes, on Xiaohongshu the user ID."""
384
+ username: Optional[str]
385
+ """Handle on the platform, where given."""
386
+ name: str
387
+ """Display name."""
388
+ avatar_url: Optional[str]
389
+ """Avatar image URL. (view=standard and up)"""
390
+ location: Optional[str]
391
+ """Where the creator says they are. (view=standard and up)"""
392
+ gender: Optional[Literal["female", "male"]]
393
+ """The creator's gender as the marketplace lists it. (view=standard and up)"""
394
+ followers: Optional[int]
395
+ """Followers."""
396
+ categories: Optional[List[str]]
397
+ """Content categories in the marketplace’s own words."""
398
+ engagement_rate: Optional[float]
399
+ """Interactions per view of recent posts, 0 to 1 (0.038 is 3.8%)."""
400
+ median_views: Optional[int]
401
+ """Median views or reads of recent everyday posts."""
402
+ median_engagements: Optional[int]
403
+ """Median interactions (likes, comments, saves, shares) of recent everyday posts."""
404
+ rates: Optional[List[Rate]]
405
+ """Published rates for sponsored work; null when the marketplace hides them."""
406
+ ext: Dict[str, Any]
407
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
408
+
409
+
410
+ class CreatorKeyword(TypedDict, total=False):
411
+ keyword: str
412
+ """The keyword."""
413
+ mentions: Optional[int]
414
+ """How often the marketplace counted it; small numbers, good for ordering only."""
415
+
416
+
417
+ class CreatorRate(TypedDict, total=False):
418
+ creator_id: str
419
+ """The marketplace creator ID."""
420
+ url: str
421
+ """The creator's page on the marketplace."""
422
+ rates: List[Rate]
423
+ """Every offering on the rate card."""
424
+ industries: Optional[List[str]]
425
+ """Industries the marketplace files the creator under."""
426
+ ext: Dict[str, Any]
427
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
428
+
429
+
430
+ class CreatorScore(TypedDict, total=False):
431
+ score: Optional[float]
432
+ """The score, 0 to 100."""
433
+ average: Optional[float]
434
+ """Average score of comparable creators."""
435
+ rank: Optional[int]
436
+ """Rank on this score, 1 is the highest."""
437
+ rank_share: Optional[float]
438
+ """How far from the top the rank is, 0 to 1 (0.05 is the top 5%); to four decimals, so the top hundred or so read 0."""
439
+
440
+
441
+ class FollowerHistory(TypedDict, total=False):
442
+ creator_id: str
443
+ """The creator ID asked about."""
444
+ days: int
445
+ """How many of the most recent days the figures cover."""
446
+ gained: Optional[int]
447
+ """Net followers gained over the period; negative when the creator lost followers."""
448
+ growth: Optional[float]
449
+ """The net gain as a share of the followers at the start: 0.01 is 1% more."""
450
+ points: List[FollowerPoint]
451
+ """One entry a day, oldest first."""
452
+ ext: Dict[str, Any]
453
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
454
+
455
+
456
+ class FollowerPoint(TypedDict, total=False):
457
+ date: str
458
+ """The day: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
459
+ followers: Optional[int]
460
+ """Followers that day."""
461
+
462
+
463
+ class IndexCreatorMetrics(TypedDict, total=False):
464
+ creator_id: str
465
+ """The account's numeric ID (the one asked about)."""
466
+ average_7d: Optional[IndexDailyAverages]
467
+ """Daily averages over the last 7 days."""
468
+ average_30d: Optional[IndexDailyAverages]
469
+ """Daily averages over the last 30 days."""
470
+ change_7d: Optional[IndexDailyChange]
471
+ """The last 7 days against the 7 before, as a ratio: 0.3 is 30% more."""
472
+ change_30d: Optional[IndexDailyChange]
473
+ """The last 30 days against the 30 before, as a ratio."""
474
+ ext: Dict[str, Any]
475
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
476
+
477
+
478
+ class IndexDailyAverages(TypedDict, total=False):
479
+ likes: Optional[float]
480
+ """New likes a day, on average."""
481
+ follows: Optional[float]
482
+ """Follows a day, on average (the platform's own count of follows, not the net change in followers)."""
483
+ shares: Optional[float]
484
+ """New shares a day, on average."""
485
+ comments: Optional[float]
486
+ """New comments a day, on average."""
487
+
488
+
489
+ class IndexDailyChange(TypedDict, total=False):
490
+ likes: Optional[float]
491
+ """Change in new likes a day."""
492
+ follows: Optional[float]
493
+ """Change in follows a day (the platform's own count of follows, not the net change in followers)."""
494
+ shares: Optional[float]
495
+ """Change in new shares a day."""
496
+ comments: Optional[float]
497
+ """Change in new comments a day."""
498
+
499
+
500
+ class KeywordAudience(TypedDict, total=False):
501
+ keyword: str
502
+ """The keyword."""
503
+ age: Optional[List[KeywordSegment]]
504
+ """By age group."""
505
+ gender: Optional[List[KeywordSegment]]
506
+ """By gender."""
507
+ province: Optional[List[KeywordSegment]]
508
+ """By province."""
509
+ city: Optional[List[KeywordSegment]]
510
+ """By city: the largest only, so the shares need not add up to 1."""
511
+ city_tier: Optional[List[KeywordSegment]]
512
+ """By city tier."""
513
+ interest: Optional[List[KeywordSegment]]
514
+ """By interest; the shares need not add up to 1."""
515
+ ext: Dict[str, Any]
516
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
517
+
518
+
519
+ class KeywordHistory(TypedDict, total=False):
520
+ keyword: str
521
+ """The keyword."""
522
+ points: List[KeywordPoint]
523
+ """One entry a day, oldest first."""
524
+ ext: Dict[str, Any]
525
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
526
+
527
+
528
+ class KeywordPoint(TypedDict, total=False):
529
+ date: str
530
+ """The day: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
531
+ search_index: Optional[int]
532
+ """That day's search index: the platform's measure of search interest, not a count of searches."""
533
+ composite_index: Optional[int]
534
+ """That day's composite index: the platform's measure of attention to content about the keyword, not a count."""
535
+ notes: Optional[int]
536
+ """Posts about the keyword that day. (view=standard and up)"""
537
+ impressions: Optional[int]
538
+ """Times those posts were shown that day. (view=standard and up)"""
539
+ views: Optional[int]
540
+ """Times those posts were read that day. (view=standard and up)"""
541
+ engagements: Optional[int]
542
+ """Interactions with those posts that day. (view=standard and up)"""
543
+
544
+
545
+ class KeywordRelated(TypedDict, total=False):
546
+ keyword: str
547
+ """The related keyword."""
548
+ related_to: str
549
+ """The keyword asked about."""
550
+ relation: Optional[Literal["query", "posts", "prior", "after", "suggestion"]]
551
+ """How it relates: searched together (query), appears together in content (posts), searched before (prior) or after (after), or suggested as you type (suggestion)."""
552
+ rank: Optional[int]
553
+ """Position among the keywords of the same relation, from 1."""
554
+ relevance: Optional[float]
555
+ """How closely it is related, 0 to 1."""
556
+ search_index: Optional[int]
557
+ """Its search index (the platform's measure, not a count); null where the platform gives none."""
558
+ composite_index: Optional[int]
559
+ """Its composite index (the platform's measure of attention, not a count)."""
560
+ ext: Dict[str, Any]
561
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
562
+
563
+
564
+ class KeywordSegment(TypedDict, total=False):
565
+ label: str
566
+ """The group, in the platform's words."""
567
+ share: Optional[float]
568
+ """The group's share of the keyword's audience, 0 to 1."""
569
+ tgi: Optional[float]
570
+ """TGI: how strongly the group leans to the keyword; 100 is the platform average."""
571
+
572
+
573
+ class Metrics(TypedDict, total=False):
574
+ views: Optional[int]
575
+ """Views or plays."""
576
+ likes: Optional[int]
577
+ """Likes."""
578
+ comments: Optional[int]
579
+ """Comments."""
580
+ shares: Optional[int]
581
+ """Shares."""
582
+ favorites: Optional[int]
583
+ """Saves or favorites."""
584
+ reposts: Optional[int]
585
+ """Reposts, retweets or forwards."""
586
+
587
+
588
+ class Miniprogram(TypedDict, total=False):
589
+ id: str
590
+ """Original ID (gh_…)."""
591
+ app_id: Optional[str]
592
+ """AppID (wx…), used to open or link to it; null where none is given."""
593
+ name: str
594
+ """Name."""
595
+ description: Optional[str]
596
+ """Description."""
597
+ icon_url: Optional[str]
598
+ """Icon. (view=standard and up)"""
599
+ owner_name: Optional[str]
600
+ """The company or body that runs it."""
601
+ owner_verified: Optional[bool]
602
+ """Whether the owner is verified. (view=standard and up)"""
603
+ recent_users: Optional[int]
604
+ """Recent users as the platform shows them; a figure like 1万+ is a lower bound; null where none is shown. (view=standard and up)"""
605
+ is_game: Optional[bool]
606
+ """Whether it is a mini game. (view=standard and up)"""
607
+ ext: Dict[str, Any]
608
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
609
+
610
+
611
+ class PgyComponentClicks(TypedDict, total=False):
612
+ comment_area: Optional[Literal["normal", "high", "very_high"]]
613
+ """Click-through band of the comment-area component: normal (under 2%), high (2-10%) or very_high (over 10%); null when the note has none. (view=standard and up)"""
614
+ content: Optional[Literal["normal", "high", "very_high"]]
615
+ """Click-through band of the in-text component: normal (under 2%), high (2-10%) or very_high (over 10%); null when the note has none. (view=standard and up)"""
616
+ note_bottom: Optional[Literal["normal", "high", "very_high"]]
617
+ """Click-through band of the component at the end of the note: normal (under 2%), high (2-10%) or very_high (over 10%); null when the note has none. (view=standard and up)"""
618
+
619
+
620
+ class PgyCostPoint(TypedDict, total=False):
621
+ date: str
622
+ """The day: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
623
+ cpm: Optional[float]
624
+ """Cost of a thousand impressions, in yuan; null where there is none."""
625
+ cpe: Optional[float]
626
+ """Cost of one interaction, in yuan; null where there is none."""
627
+ cpv: Optional[float]
628
+ """Cost of one read, in yuan, as the trend chart works it out; null where there is none."""
629
+ shop_visit_cost: Optional[float]
630
+ """Cost per shop visitor a note brings, in yuan; null where there is none."""
631
+ median_impressions: Optional[int]
632
+ """Median impressions of a note."""
633
+ median_reads: Optional[int]
634
+ """Median reads of a note."""
635
+ median_engagements: Optional[int]
636
+ """Median interactions of a note."""
637
+ median_shop_visits: Optional[int]
638
+ """Median shop visitors a note brings; a note that brought none counts as 0."""
639
+
640
+
641
+ class PgyCreatorCostHistory(TypedDict, total=False):
642
+ creator_id: str
643
+ """PGY creator ID."""
644
+ days: int
645
+ """How many of the most recent days the figures cover."""
646
+ currency: Optional[str]
647
+ """Currency of the costs (ISO 4217)."""
648
+ date: Optional[str]
649
+ """The last day the figures run to: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
650
+ cpm: Optional[float]
651
+ """Cost of a thousand impressions, in yuan; null where there is none."""
652
+ cpe: Optional[float]
653
+ """Cost of one interaction, in yuan; null where there is none."""
654
+ cpv: Optional[float]
655
+ """Cost of one read, in yuan, as the trend chart works it out; null where there is none."""
656
+ shop_visit_cost: Optional[float]
657
+ """Cost per shop visitor a note brings, in yuan; null where there is none."""
658
+ median_impressions: Optional[int]
659
+ """Median impressions of a note."""
660
+ median_reads: Optional[int]
661
+ """Median reads of a note."""
662
+ median_engagements: Optional[int]
663
+ """Median interactions of a note."""
664
+ median_shop_visits: Optional[int]
665
+ """Median shop visitors a note brings; a note that brought none counts as 0."""
666
+ points: List[PgyCostPoint]
667
+ """The figures day by day, oldest first."""
668
+ ext: Dict[str, Any]
669
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
670
+
671
+
672
+ class PgyCreatorCosts(TypedDict, total=False):
673
+ creator_id: str
674
+ """PGY creator ID."""
675
+ date: Optional[str]
676
+ """The day the figures are of: a calendar day in China time (UTC+8), written as 00:00 UTC of that date."""
677
+ currency: Optional[str]
678
+ """Currency of the costs (ISO 4217)."""
679
+ image_cpm: Optional[float]
680
+ """Estimated CPM (cost of a thousand impressions) of a image note, in yuan; null where PGY has no estimate."""
681
+ image_cpm_percentile: Optional[float]
682
+ """Share of comparable creators whose image note CPM (cost of a thousand impressions) is higher, 0 to 1. (view=standard and up)"""
683
+ video_cpm: Optional[float]
684
+ """Estimated CPM (cost of a thousand impressions) of a video note, in yuan; null where PGY has no estimate."""
685
+ video_cpm_percentile: Optional[float]
686
+ """Share of comparable creators whose video note CPM (cost of a thousand impressions) is higher, 0 to 1. (view=standard and up)"""
687
+ image_cpe: Optional[float]
688
+ """Estimated cost per interaction of a image note, in yuan; null where PGY has no estimate."""
689
+ image_cpe_percentile: Optional[float]
690
+ """Share of comparable creators whose image note cost per interaction is higher, 0 to 1. (view=standard and up)"""
691
+ video_cpe: Optional[float]
692
+ """Estimated cost per interaction of a video note, in yuan; null where PGY has no estimate."""
693
+ video_cpe_percentile: Optional[float]
694
+ """Share of comparable creators whose video note cost per interaction is higher, 0 to 1. (view=standard and up)"""
695
+ image_read_cost: Optional[float]
696
+ """Estimated cost per read of a image note, in yuan; null where PGY has no estimate."""
697
+ image_read_cost_percentile: Optional[float]
698
+ """Share of comparable creators whose image note cost per read is higher, 0 to 1. (view=standard and up)"""
699
+ video_read_cost: Optional[float]
700
+ """Estimated cost per read of a video note, in yuan; null where PGY has no estimate."""
701
+ video_read_cost_percentile: Optional[float]
702
+ """Share of comparable creators whose video note cost per read is higher, 0 to 1. (view=standard and up)"""
703
+ image_shop_visit_cost: Optional[float]
704
+ """Estimated cost per shop visitor of a image note, in yuan; null where PGY has no estimate."""
705
+ image_shop_visit_cost_percentile: Optional[float]
706
+ """Share of comparable creators whose image note cost per shop visitor is higher, 0 to 1. (view=standard and up)"""
707
+ video_shop_visit_cost: Optional[float]
708
+ """Estimated cost per shop visitor of a video note, in yuan; null where PGY has no estimate."""
709
+ video_shop_visit_cost_percentile: Optional[float]
710
+ """Share of comparable creators whose video note cost per shop visitor is higher, 0 to 1. (view=standard and up)"""
711
+ median_impressions: Optional[int]
712
+ """Median impressions of a note."""
713
+ median_impressions_percentile: Optional[float]
714
+ """Share of comparable creators this one beats on median impressions, 0 to 1. (view=standard and up)"""
715
+ median_reads: Optional[int]
716
+ """Median reads of a note."""
717
+ median_reads_percentile: Optional[float]
718
+ """Share of comparable creators this one beats on median reads, 0 to 1. (view=standard and up)"""
719
+ median_engagements: Optional[int]
720
+ """Median interactions of a note."""
721
+ median_engagements_percentile: Optional[float]
722
+ """Share of comparable creators this one beats on median interactions, 0 to 1. (view=standard and up)"""
723
+ median_shop_visits: Optional[int]
724
+ """Median shop visitors a note brings."""
725
+ median_shop_visits_percentile: Optional[float]
726
+ """Share of comparable creators this one beats on median shop visitors, 0 to 1. (view=standard and up)"""
727
+ follower_growth: Optional[float]
728
+ """Follower growth over the last 30 days: 0.037 is 3.7% more; negative when followers were lost. (view=standard and up)"""
729
+ follower_growth_percentile: Optional[float]
730
+ """Share of comparable creators this one beats on follower growth, 0 to 1. (view=standard and up)"""
731
+ invite_reply_rate: Optional[float]
732
+ """Share of collaboration invitations answered within 48 hours, 0 to 1. (view=standard and up)"""
733
+ easy_to_reach: Optional[bool]
734
+ """Whether PGY marks the creator as easy to reach (好联系). (view=standard and up)"""
735
+ active_days_7d: Optional[int]
736
+ """Days active in the last 7. (view=standard and up)"""
737
+ is_active: Optional[bool]
738
+ """Whether PGY marks the creator as active (活跃). (view=standard and up)"""
739
+ notes_30d: Optional[int]
740
+ """Notes published in the last 30 days, everyday and sponsored alike. (view=standard and up)"""
741
+ highlight: Optional[str]
742
+ """The strength PGY credits the creator with, in its words; null when none. (view=standard and up)"""
743
+ highlight_reason: Optional[str]
744
+ """PGY's reason for that strength, in its words. (view=standard and up)"""
745
+ content_mix: Optional[List[CategoryShare]]
746
+ """Share of the creator's notes per content category, largest first. (view=standard and up)"""
747
+ industries: Optional[List[str]]
748
+ """Industries the creator has worked with, in the platform's words. (view=standard and up)"""
749
+ ext: Dict[str, Any]
750
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
751
+
752
+
753
+ class PgyCreatorFollowers(TypedDict, total=False):
754
+ creator_id: str
755
+ """PGY creator ID."""
756
+ followers: Optional[int]
757
+ """Followers."""
758
+ gained: Optional[int]
759
+ """Net followers gained over the last 30 days; negative when followers were lost."""
760
+ growth: Optional[float]
761
+ """Follower growth over the last 30 days: 0.008 is 0.8% more."""
762
+ growth_percentile: Optional[float]
763
+ """Share of comparable creators this one beats on follower growth, 0 to 1. (view=standard and up)"""
764
+ active_followers: Optional[int]
765
+ """Active followers: active on Xiaohongshu in the last 28 days."""
766
+ active_share: Optional[float]
767
+ """Active followers as a share of all followers, 0 to 1."""
768
+ active_percentile: Optional[float]
769
+ """Share of comparable creators this one beats on share of active followers, 0 to 1. (view=standard and up)"""
770
+ engaged_followers: Optional[int]
771
+ """Engaged followers: interacted with the creator's notes in the last 30 days."""
772
+ engaged_share: Optional[float]
773
+ """Engaged followers as a share of all followers, 0 to 1."""
774
+ engaged_percentile: Optional[float]
775
+ """Share of comparable creators this one beats on share of engaged followers, 0 to 1. (view=standard and up)"""
776
+ reading_followers: Optional[int]
777
+ """Reading followers: read the creator's notes in the last 30 days."""
778
+ reading_share: Optional[float]
779
+ """Reading followers as a share of all followers, 0 to 1."""
780
+ reading_percentile: Optional[float]
781
+ """Share of comparable creators this one beats on share of reading followers, 0 to 1. (view=standard and up)"""
782
+ buying_followers: Optional[int]
783
+ """Buying followers: bought something on Xiaohongshu in the last 30 days."""
784
+ buying_share: Optional[float]
785
+ """Buying followers as a share of all followers, 0 to 1."""
786
+ ext: Dict[str, Any]
787
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
788
+
789
+
790
+ class PgyCreatorMetrics(TypedDict, total=False):
791
+ creator_id: str
792
+ """PGY creator ID."""
793
+ notes: Optional[int]
794
+ """Notes in the period."""
795
+ median_impressions: Optional[int]
796
+ """Median impressions of a note."""
797
+ median_reads: Optional[int]
798
+ """Median reads of a note."""
799
+ median_engagements: Optional[int]
800
+ """Median interactions of a note."""
801
+ median_likes: Optional[int]
802
+ """Median likes of a note. (view=standard and up)"""
803
+ median_favorites: Optional[int]
804
+ """Median saves of a note. (view=standard and up)"""
805
+ median_comments: Optional[int]
806
+ """Median comments of a note. (view=standard and up)"""
807
+ median_shares: Optional[int]
808
+ """Median shares of a note. (view=standard and up)"""
809
+ engagement_rate: Optional[float]
810
+ """Interactions per read, 0 to 1."""
811
+ video_completion_rate: Optional[float]
812
+ """Completion rate of video notes, 0 to 1. (view=standard and up)"""
813
+ image_3s_read_rate: Optional[float]
814
+ """Share of image-note reads that lasted 3 seconds, 0 to 1. (view=standard and up)"""
815
+ hundred_like_share: Optional[float]
816
+ """Share of notes with 100 likes or more, 0 to 1. (view=standard and up)"""
817
+ thousand_like_share: Optional[float]
818
+ """Share of notes with 1,000 likes or more, 0 to 1. (view=standard and up)"""
819
+ impressions_percentile: Optional[float]
820
+ """Share of comparable creators this one beats on median impressions, 0 to 1. (view=standard and up)"""
821
+ reads_percentile: Optional[float]
822
+ """Share of comparable creators this one beats on median reads, 0 to 1. (view=standard and up)"""
823
+ engagements_percentile: Optional[float]
824
+ """Share of comparable creators this one beats on median interactions, 0 to 1. (view=standard and up)"""
825
+ video_notes: Optional[int]
826
+ """Video notes in the period (included in notes). (view=standard and up)"""
827
+ video_completion_percentile: Optional[float]
828
+ """Share of comparable creators this one beats on video completion rate, 0 to 1. (view=standard and up)"""
829
+ median_follows: Optional[int]
830
+ """Median new followers a note brought. (view=standard and up)"""
831
+ traffic_sources: Optional[PgyTrafficSources]
832
+ """Where the notes got their impressions and reads; each set adds up to 1. (view=standard and up)"""
833
+ long_term: Optional[PgyLongTerm]
834
+ """Long-term performance of notes from about half a year back: recent and long-term reads, standing and sources. (view=full and up)"""
835
+ note_list: Optional[List[PgyNoteFigures]]
836
+ """The period's notes one by one, oldest first, 15 at most; null when there is none. (view=full and up)"""
837
+ ext: Dict[str, Any]
838
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
839
+
840
+
841
+ class PgyCreatorPost(TypedDict, total=False):
842
+ id: str
843
+ """Note ID."""
844
+ title: Optional[str]
845
+ """The note's title."""
846
+ type: Optional[Literal["image", "video"]]
847
+ """Image note or video note."""
848
+ published_at: Optional[str]
849
+ """Publication day, as 00:00 China time (the platform gives the day only)."""
850
+ cover_url: Optional[str]
851
+ """Cover image. (view=standard and up)"""
852
+ is_sponsored: Optional[bool]
853
+ """Whether it was made for a brand (see brand)."""
854
+ brand: Optional[str]
855
+ """The brand it was made for, in the platform's words; null when not sponsored."""
856
+ is_promoted: Optional[bool]
857
+ """Whether paid promotion sent traffic to it (含推广流量); not the same as sponsored."""
858
+ metrics: PgyPostMetrics
859
+ """The note's figures."""
860
+ ext: Dict[str, Any]
861
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
862
+
863
+
864
+ class PgyLongTerm(TypedDict, total=False):
865
+ published_from: Optional[str]
866
+ """First publication day of the notes counted: a calendar day in China time (UTC+8), written as 00:00 UTC of that date. (view=full and up)"""
867
+ published_to: Optional[str]
868
+ """Last publication day of the notes counted, written the same way. (view=full and up)"""
869
+ notes: Optional[int]
870
+ """Notes published in that span; when 0 the figures below are null. (view=full and up)"""
871
+ recent_reads: Optional[int]
872
+ """Reads of a typical note soon after publication, the platform's representative figure. (view=full and up)"""
873
+ recent_reads_percentile: Optional[float]
874
+ """Share of comparable creators this one beats on recent reads, 0 to 1. (view=full and up)"""
875
+ long_term_reads: Optional[int]
876
+ """Reads of a typical note in the long term, after the recent part. (view=full and up)"""
877
+ long_term_reads_percentile: Optional[float]
878
+ """Share of comparable creators this one beats on long-term reads, 0 to 1. (view=full and up)"""
879
+ recent_sources: Optional[PgyReadSources]
880
+ """Where the recent reads came from. (view=full and up)"""
881
+ long_term_sources: Optional[PgyReadSources]
882
+ """Where the long-term reads came from. (view=full and up)"""
883
+
884
+
885
+ class PgyNote(TypedDict, total=False):
886
+ id: str
887
+ """Note ID."""
888
+ url: Optional[str]
889
+ """Link to the note, with the access token that makes it open."""
890
+ type: Optional[Literal["image", "video"]]
891
+ """Image note or video note."""
892
+ title: Optional[str]
893
+ """The note's title."""
894
+ text: Optional[str]
895
+ """The note's text. (view=standard and up)"""
896
+ published_at: Optional[str]
897
+ """When it was published."""
898
+ images: Optional[List[str]]
899
+ """Picture links in order. (view=standard and up)"""
900
+ creator_id: Optional[str]
901
+ """The creator's PGY ID."""
902
+ creator_name: Optional[str]
903
+ """The creator's name."""
904
+ brand: Optional[str]
905
+ """The sponsoring brand, in the platform's words; null when it is not a reported sponsored note."""
906
+ brand_id: Optional[str]
907
+ """That brand's Xiaohongshu account ID; null when none. (view=standard and up)"""
908
+ metrics: PgyNoteMetrics
909
+ """The note's figures on PGY."""
910
+ component_clicks: Optional[PgyComponentClicks]
911
+ """Click-through bands of the components the brand added; null when there are none. (view=standard and up)"""
912
+ ext: Dict[str, Any]
913
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
914
+
915
+
916
+ class PgyNoteFigures(TypedDict, total=False):
917
+ id: str
918
+ """Note ID. (view=full and up)"""
919
+ title: Optional[str]
920
+ """The note's title. (view=full and up)"""
921
+ type: Optional[Literal["image", "video"]]
922
+ """Image note or video note. (view=full and up)"""
923
+ published_at: Optional[str]
924
+ """Publication day, as 00:00 China time (the platform gives the day only). (view=full and up)"""
925
+ cover_url: Optional[str]
926
+ """Cover image. (view=full and up)"""
927
+ impressions: Optional[int]
928
+ """Impressions. (view=full and up)"""
929
+ reads: Optional[int]
930
+ """Reads. (view=full and up)"""
931
+ engagements: Optional[int]
932
+ """Interactions. (view=full and up)"""
933
+ likes: Optional[int]
934
+ """Likes. (view=full and up)"""
935
+ favorites: Optional[int]
936
+ """Saves. (view=full and up)"""
937
+ impressions_vs_median: Optional[float]
938
+ """The note's impressions against the creator's median for the period: 0.5 is 50% above, -0.3 is 30% below. (view=full and up)"""
939
+ reads_vs_median: Optional[float]
940
+ """The note's reads against the creator's median for the period: 0.5 is 50% above, -0.3 is 30% below. (view=full and up)"""
941
+ engagements_vs_median: Optional[float]
942
+ """The note's interactions against the creator's median for the period: 0.5 is 50% above, -0.3 is 30% below. (view=full and up)"""
943
+ likes_vs_median: Optional[float]
944
+ """The note's likes against the creator's median for the period: 0.5 is 50% above, -0.3 is 30% below. (view=full and up)"""
945
+ favorites_vs_median: Optional[float]
946
+ """The note's saves against the creator's median for the period: 0.5 is 50% above, -0.3 is 30% below. (view=full and up)"""
947
+
948
+
949
+ class PgyNoteMetrics(TypedDict, total=False):
950
+ impressions: Optional[int]
951
+ """Impressions."""
952
+ views: Optional[int]
953
+ """Reads."""
954
+ likes: Optional[int]
955
+ """Likes."""
956
+ favorites: Optional[int]
957
+ """Saves."""
958
+ comments: Optional[int]
959
+ """Comments."""
960
+ shares: Optional[int]
961
+ """Shares."""
962
+ follows: Optional[int]
963
+ """New followers the note brought."""
964
+
965
+
966
+ class PgyPostMetrics(TypedDict, total=False):
967
+ views: Optional[int]
968
+ """Reads."""
969
+ likes: Optional[int]
970
+ """Likes."""
971
+ favorites: Optional[int]
972
+ """Saves."""
973
+ shop_visits: Optional[int]
974
+ """Shop visitors the note brought (cross-domain sponsored notes only; 0 for others). (view=standard and up)"""
975
+
976
+
977
+ class PgyReadSources(TypedDict, total=False):
978
+ homefeed: Optional[float]
979
+ """Share of the reads that came from the explore feed, 0 to 1. (view=full and up)"""
980
+ search: Optional[float]
981
+ """Share of the reads that came from search, 0 to 1. (view=full and up)"""
982
+ profile: Optional[float]
983
+ """Share of the reads that came from the creator's profile page, 0 to 1. (view=full and up)"""
984
+ follow: Optional[float]
985
+ """Share of the reads that came from the following feed, 0 to 1. (view=full and up)"""
986
+ other: Optional[float]
987
+ """Share of the reads that came from anywhere else, 0 to 1. (view=full and up)"""
988
+
989
+
990
+ class PgySourceShares(TypedDict, total=False):
991
+ homefeed: Optional[float]
992
+ """Share of the traffic that came from the explore feed, 0 to 1. (view=standard and up)"""
993
+ search: Optional[float]
994
+ """Share of the traffic that came from search, 0 to 1. (view=standard and up)"""
995
+ follow: Optional[float]
996
+ """Share of the traffic that came from the following feed, 0 to 1. (view=standard and up)"""
997
+ detail: Optional[float]
998
+ """Share of the traffic that came from note detail pages, 0 to 1. (view=standard and up)"""
999
+ nearby: Optional[float]
1000
+ """Share of the traffic that came from the nearby feed, 0 to 1. (view=standard and up)"""
1001
+ other: Optional[float]
1002
+ """Share of the traffic that came from anywhere else, 0 to 1. (view=standard and up)"""
1003
+
1004
+
1005
+ class PgyTrafficSources(TypedDict, total=False):
1006
+ impressions: Optional[PgySourceShares]
1007
+ """Where the impressions came from. (view=standard and up)"""
1008
+ reads: Optional[PgySourceShares]
1009
+ """Where the reads came from. (view=standard and up)"""
1010
+
1011
+
1012
+ class Post(TypedDict, total=False):
1013
+ id: str
1014
+ """Post ID on the platform."""
1015
+ url: str
1016
+ """Link to the post."""
1017
+ type: Literal["video", "image", "text", "article"]
1018
+ """What kind of post it is."""
1019
+ title: Optional[str]
1020
+ """Title, where the platform has one (videos, notes, articles)."""
1021
+ text: str
1022
+ """Caption, body or description as plain text; articles come as Markdown."""
1023
+ lang: Optional[str]
1024
+ """Language code, as reported or detected. (view=standard and up)"""
1025
+ published_at: Optional[str]
1026
+ """When it was published, ISO 8601 in UTC; null only where the source gives no time (wechat_mp.articles.metrics, wechat_channels.videos.metrics, youtube.channels.videos.list with type=short), then listed in meta.unavailable."""
1027
+ author: AccountRef
1028
+ """Who posted it."""
1029
+ metrics: Metrics
1030
+ """Counts at fetch time; a count the platform hides is null."""
1031
+ images: Optional[List[str]]
1032
+ """Image URLs for image posts and notes. (view=standard and up)"""
1033
+ hashtags: Optional[List[str]]
1034
+ """Hashtags or topics, without the # sign. (view=standard and up)"""
1035
+ ext: Dict[str, Any]
1036
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1037
+
1038
+
1039
+ class Product(TypedDict, total=False):
1040
+ id: str
1041
+ """Product ID in the shop."""
1042
+ url: str
1043
+ """Product page."""
1044
+ title: str
1045
+ """Product title."""
1046
+ price: Optional[float]
1047
+ """Current price (the lowest variant), in the currency given."""
1048
+ original_price: Optional[float]
1049
+ """List price before discount, where shown. (view=standard and up)"""
1050
+ currency: Optional[str]
1051
+ """ISO 4217 currency code."""
1052
+ sold: Optional[int]
1053
+ """Units sold, as the shop shows it."""
1054
+ rating: Optional[float]
1055
+ """Average stars, 0 to 5."""
1056
+ reviews: Optional[int]
1057
+ """Number of reviews."""
1058
+ images: Optional[List[str]]
1059
+ """Product image URLs. (view=standard and up)"""
1060
+ shop: ShopRef
1061
+ """Who sells it."""
1062
+ ext: Dict[str, Any]
1063
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1064
+
1065
+
1066
+ class Rate(TypedDict, total=False):
1067
+ type: Literal["integrated_video", "custom_video", "image_note", "video_note", "other"]
1068
+ """Kind of sponsored work, normalised across platforms."""
1069
+ name: str
1070
+ """The platform's own name for it."""
1071
+ price: Optional[float]
1072
+ """Listed price, in the currency given; null when not published."""
1073
+ currency: str
1074
+ """ISO 4217 currency code."""
1075
+ available: Optional[bool]
1076
+ """Whether the creator takes this kind of order now."""
1077
+ settlement: Optional[str]
1078
+ """How it is settled, in the platform’s words."""
1079
+
1080
+
1081
+ class Review(TypedDict, total=False):
1082
+ id: str
1083
+ """Review ID."""
1084
+ product_id: str
1085
+ """ID of the product reviewed."""
1086
+ rating: Optional[float]
1087
+ """Stars, 1 to 5."""
1088
+ text: str
1089
+ """Review text; empty when the buyer left only stars."""
1090
+ published_at: Optional[str]
1091
+ """When it was posted, ISO 8601 in UTC (a day for platforms that show only the date)."""
1092
+ author_name: Optional[str]
1093
+ """Reviewer name as the shop shows it, often masked."""
1094
+ variant: Optional[str]
1095
+ """The variant bought. (view=standard and up)"""
1096
+ images: Optional[List[str]]
1097
+ """Photos attached to the review. (view=standard and up)"""
1098
+ likes: Optional[int]
1099
+ """Likes on the review. (view=standard and up)"""
1100
+ verified_purchase: Optional[bool]
1101
+ """Whether the shop marks it as a verified purchase. (view=standard and up)"""
1102
+
1103
+
1104
+ class SalesCategory(TypedDict, total=False):
1105
+ name: str
1106
+ """The category of goods, in the platform's words."""
1107
+ share: Optional[float]
1108
+ """The category's share, 0 to 1."""
1109
+ sales_range: Optional[str]
1110
+ """Band of the category's sales, in the platform's words."""
1111
+
1112
+
1113
+ class Segment(TypedDict, total=False):
1114
+ start: float
1115
+ """Start, in seconds from the beginning. (view=standard and up)"""
1116
+ end: float
1117
+ """End, in seconds from the beginning. (view=standard and up)"""
1118
+ text: str
1119
+ """What is said in this segment. (view=standard and up)"""
1120
+
1121
+
1122
+ class ShopRef(TypedDict, total=False):
1123
+ id: Optional[str]
1124
+ """Shop or seller ID."""
1125
+ name: Optional[str]
1126
+ """Shop name."""
1127
+ url: Optional[str]
1128
+ """Shop page. (view=standard and up)"""
1129
+
1130
+
1131
+ class Topic(TypedDict, total=False):
1132
+ id: str
1133
+ """ID; pass it as is to the endpoints that take one."""
1134
+ name: str
1135
+ """Name of the topic."""
1136
+ url: Optional[str]
1137
+ """Link to the topic page."""
1138
+ description: Optional[str]
1139
+ """What the topic page says it is about; null when it says nothing."""
1140
+ metrics: TopicMetrics
1141
+ """Counts at fetch time."""
1142
+ ext: Dict[str, Any]
1143
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1144
+
1145
+
1146
+ class TopicMetrics(TypedDict, total=False):
1147
+ views: Optional[int]
1148
+ """Views of the topic page."""
1149
+ posts: Optional[int]
1150
+ """Posts under the topic."""
1151
+
1152
+
1153
+ class Transcript(TypedDict, total=False):
1154
+ video_id: str
1155
+ """ID of the video."""
1156
+ lang: str
1157
+ """Language of this transcript."""
1158
+ segments: List[Segment]
1159
+ """Timed segments in order. (view=standard and up)"""
1160
+ text: str
1161
+ """All segments joined as plain text."""
1162
+
1163
+
1164
+ class Trend(TypedDict, total=False):
1165
+ rank: int
1166
+ """Position on the board, 1 is the top."""
1167
+ name: str
1168
+ """The topic or search term."""
1169
+ heat: Optional[float]
1170
+ """The heat score the platform shows; scales differ by platform."""
1171
+ url: Optional[str]
1172
+ """Link to the topic page, if there is one."""
1173
+
1174
+
1175
+ class XingtuCampaign(TypedDict, total=False):
1176
+ id: str
1177
+ """Campaign ID."""
1178
+ name: str
1179
+ """Name of the campaign."""
1180
+ description: Optional[str]
1181
+ """What the campaign is."""
1182
+ category: Optional[Literal["platform_event", "ecommerce", "seasonal", "creative", "industry"]]
1183
+ """Kind of campaign: platform event, e-commerce moment, seasonal moment, creative marketing or industry campaign."""
1184
+ stage: Optional[Literal["preparing", "open", "live", "ended"]]
1185
+ """Where it stands: being prepared, open for sign-up, live or ended."""
1186
+ signup_starts_at: Optional[str]
1187
+ """When sign-up opens."""
1188
+ signup_ends_at: Optional[str]
1189
+ """When sign-up closes."""
1190
+ starts_at: Optional[str]
1191
+ """When the campaign starts."""
1192
+ ends_at: Optional[str]
1193
+ """When the campaign ends."""
1194
+ image_url: Optional[str]
1195
+ """The campaign's main image. (view=standard and up)"""
1196
+ ext: Dict[str, Any]
1197
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1198
+
1199
+
1200
+ class XingtuCreatorContentMix(TypedDict, total=False):
1201
+ creator_id: str
1202
+ """Xingtu creator ID."""
1203
+ categories: List[ContentShare]
1204
+ """One entry per content category."""
1205
+ ext: Dict[str, Any]
1206
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1207
+
1208
+
1209
+ class XingtuCreatorConversion(TypedDict, total=False):
1210
+ creator_id: str
1211
+ """Xingtu creator ID."""
1212
+ videos: Optional[int]
1213
+ """Videos counted: those that carry products."""
1214
+ median_views: Optional[int]
1215
+ """Median views of those videos."""
1216
+ products: Optional[int]
1217
+ """Products recommended."""
1218
+ currency: Optional[str]
1219
+ """Currency of the money bands (ISO 4217)."""
1220
+ sales_range: Optional[str]
1221
+ """Band of the average sales of a video, in the platform's words."""
1222
+ gpm_range: Optional[str]
1223
+ """Band of sales per thousand views (GPM), in the platform's words."""
1224
+ product_price_range: Optional[str]
1225
+ """Band of the prices of the products recommended, in the platform's words."""
1226
+ click_cost_range: Optional[str]
1227
+ """Band of the cost per click (CPC), in the platform's words."""
1228
+ clicks_range: Optional[str]
1229
+ """Band of clicks on a video's product link, in the platform's words."""
1230
+ click_rate_range: Optional[str]
1231
+ """Band of the click rate of a video's product link, in the platform's words."""
1232
+ categories: Optional[List[SalesCategory]]
1233
+ """One entry per category of goods sold."""
1234
+ ext: Dict[str, Any]
1235
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1236
+
1237
+
1238
+ class XingtuCreatorKeywords(TypedDict, total=False):
1239
+ creator_id: str
1240
+ """Xingtu creator ID."""
1241
+ keywords: List[CreatorKeyword]
1242
+ """One entry per keyword."""
1243
+ ext: Dict[str, Any]
1244
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1245
+
1246
+
1247
+ class XingtuCreatorMetrics(TypedDict, total=False):
1248
+ creator_id: str
1249
+ """Xingtu creator ID."""
1250
+ videos: Optional[int]
1251
+ """Videos in the period."""
1252
+ median_views: Optional[int]
1253
+ """Median views of a video."""
1254
+ average_likes: Optional[int]
1255
+ """Average likes of a video."""
1256
+ average_comments: Optional[int]
1257
+ """Average comments of a video."""
1258
+ average_shares: Optional[int]
1259
+ """Average shares of a video."""
1260
+ engagement_rate: Optional[float]
1261
+ """Interactions per view, 0 to 1."""
1262
+ engagement_rate_percentile: Optional[float]
1263
+ """Share of comparable creators this one beats on engagement rate, 0 to 1. (view=standard and up)"""
1264
+ completion_rate: Optional[float]
1265
+ """Share of views watched to the end, 0 to 1."""
1266
+ completion_rate_percentile: Optional[float]
1267
+ """Share of comparable creators this one beats on completion rate, 0 to 1. (view=standard and up)"""
1268
+ currency: Optional[str]
1269
+ """Currency of the costs below (ISO 4217)."""
1270
+ cpm_integrated: Optional[float]
1271
+ """Expected cost per thousand views of an integrated video (植入视频)."""
1272
+ cpm_custom: Optional[float]
1273
+ """Expected cost per thousand views of a custom video (定制视频)."""
1274
+ cpe_integrated: Optional[float]
1275
+ """Expected cost per interaction of an integrated video."""
1276
+ cpe_custom: Optional[float]
1277
+ """Expected cost per interaction of a custom video."""
1278
+ ext: Dict[str, Any]
1279
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1280
+
1281
+
1282
+ class XingtuCreatorPost(TypedDict, total=False):
1283
+ id: str
1284
+ """Video ID, the one the Douyin video endpoints take."""
1285
+ url: Optional[str]
1286
+ """Link to the video."""
1287
+ title: Optional[str]
1288
+ """The video's caption."""
1289
+ published_at: Optional[str]
1290
+ """When it was published."""
1291
+ duration: Optional[float]
1292
+ """Length in seconds. (view=standard and up)"""
1293
+ metrics: XingtuPostMetrics
1294
+ """The video's figures."""
1295
+ ext: Dict[str, Any]
1296
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1297
+
1298
+
1299
+ class XingtuCreatorScores(TypedDict, total=False):
1300
+ creator_id: str
1301
+ """Xingtu creator ID."""
1302
+ overall: Optional[CreatorScore]
1303
+ """The overall Xingtu score."""
1304
+ reach: Optional[CreatorScore]
1305
+ """Reach score."""
1306
+ seeding: Optional[CreatorScore]
1307
+ """Seeding score: how well the creator's videos raise interest in products."""
1308
+ conversion: Optional[CreatorScore]
1309
+ """Conversion score."""
1310
+ cooperation: Optional[CreatorScore]
1311
+ """Cooperation score."""
1312
+ value_for_money: Optional[CreatorScore]
1313
+ """Value-for-money score."""
1314
+ ext: Dict[str, Any]
1315
+ """Platform-specific extras. Only returned with view=full. (view=full and up)"""
1316
+
1317
+
1318
+ class XingtuPostMetrics(TypedDict, total=False):
1319
+ views: Optional[int]
1320
+ """Views."""
1321
+ likes: Optional[int]
1322
+ """Likes."""
1323
+ comments: Optional[int]
1324
+ """Comments."""
1325
+ completion_rate: Optional[float]
1326
+ """Share of views watched to the end, 0 to 1."""
1327
+ engagement_rate: Optional[float]
1328
+ """Interactions per view, 0 to 1."""
1329
+