@dracoonghost/trndup-sdk 1.3.17 → 1.3.18
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/dist/index.d.mts +699 -0
- package/dist/index.d.ts +699 -0
- package/dist/index.js +298 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +298 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -594,6 +594,467 @@ declare namespace Insights {
|
|
|
594
594
|
/** Max number of data points (default: 30, max: 90) */
|
|
595
595
|
limit?: number;
|
|
596
596
|
}
|
|
597
|
+
/**
|
|
598
|
+
* How we calculated this insight - shown to user for transparency
|
|
599
|
+
*/
|
|
600
|
+
interface CalculationExplanation {
|
|
601
|
+
/** Short description of the methodology */
|
|
602
|
+
method: string;
|
|
603
|
+
/** Time range analyzed */
|
|
604
|
+
timeRange: string;
|
|
605
|
+
/** Key factors that influenced the result */
|
|
606
|
+
factors: string[];
|
|
607
|
+
/** Data quality/reliability indicator */
|
|
608
|
+
dataQuality: 'high' | 'medium' | 'low';
|
|
609
|
+
/** Why data quality might be limited */
|
|
610
|
+
dataQualityNote?: string;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Common metadata for all insights
|
|
614
|
+
*/
|
|
615
|
+
interface InsightMeta {
|
|
616
|
+
/** When this insight was calculated */
|
|
617
|
+
calculatedAt: string;
|
|
618
|
+
/** When this insight expires (should be recalculated) */
|
|
619
|
+
validUntil: string;
|
|
620
|
+
/** Algorithm version for tracking changes */
|
|
621
|
+
algorithmVersion: string;
|
|
622
|
+
/** Whether result came from cache */
|
|
623
|
+
fromCache: boolean;
|
|
624
|
+
/** How this was calculated (for transparency) */
|
|
625
|
+
howWeCalculatedThis: CalculationExplanation;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Response when there's not enough data for an insight
|
|
629
|
+
*/
|
|
630
|
+
interface InsufficientDataResponse {
|
|
631
|
+
hasData: false;
|
|
632
|
+
reason: string;
|
|
633
|
+
minimumRequired: string;
|
|
634
|
+
currentAmount: string;
|
|
635
|
+
suggestion: string;
|
|
636
|
+
}
|
|
637
|
+
interface TopVideoData {
|
|
638
|
+
videoId: string;
|
|
639
|
+
title: string;
|
|
640
|
+
thumbnailUrl: string | null;
|
|
641
|
+
publishedAt: string;
|
|
642
|
+
/** Link to watch on YouTube */
|
|
643
|
+
watchUrl: string;
|
|
644
|
+
}
|
|
645
|
+
interface TopVideoMetrics {
|
|
646
|
+
views: number;
|
|
647
|
+
likes: number;
|
|
648
|
+
comments: number;
|
|
649
|
+
estimatedMinutesWatched: number;
|
|
650
|
+
engagementRate: number;
|
|
651
|
+
}
|
|
652
|
+
interface TopVideoComparison {
|
|
653
|
+
/** Performance vs user's average video */
|
|
654
|
+
vsChannelAverage: {
|
|
655
|
+
views: number;
|
|
656
|
+
engagement: number;
|
|
657
|
+
description: string;
|
|
658
|
+
};
|
|
659
|
+
/** Why this video performed well */
|
|
660
|
+
standoutReasons: string[];
|
|
661
|
+
}
|
|
662
|
+
interface BestPerformingVideoData {
|
|
663
|
+
/** Time range analyzed */
|
|
664
|
+
period: {
|
|
665
|
+
start: string;
|
|
666
|
+
end: string;
|
|
667
|
+
days: number;
|
|
668
|
+
};
|
|
669
|
+
/** The top performing video */
|
|
670
|
+
topVideo: TopVideoData;
|
|
671
|
+
/** Video's metrics for this period */
|
|
672
|
+
metrics: TopVideoMetrics;
|
|
673
|
+
/** How it compares to your other content */
|
|
674
|
+
comparison: TopVideoComparison;
|
|
675
|
+
/** Human-readable summary */
|
|
676
|
+
insight: string;
|
|
677
|
+
/** Runner-up videos (for context) */
|
|
678
|
+
runnersUp: Array<{
|
|
679
|
+
videoId: string;
|
|
680
|
+
title: string;
|
|
681
|
+
views: number;
|
|
682
|
+
thumbnailUrl: string | null;
|
|
683
|
+
}>;
|
|
684
|
+
}
|
|
685
|
+
type BestPerformingVideoResponse = (InsufficientDataResponse) | {
|
|
686
|
+
hasData: true;
|
|
687
|
+
data: BestPerformingVideoData;
|
|
688
|
+
_meta: InsightMeta;
|
|
689
|
+
};
|
|
690
|
+
interface DecayingVideo {
|
|
691
|
+
videoId: string;
|
|
692
|
+
title: string;
|
|
693
|
+
thumbnailUrl: string | null;
|
|
694
|
+
publishedAt: string;
|
|
695
|
+
watchUrl: string;
|
|
696
|
+
/** Age of video in days */
|
|
697
|
+
ageInDays: number;
|
|
698
|
+
/** Views in current period */
|
|
699
|
+
currentViews: number;
|
|
700
|
+
/** Views in previous period */
|
|
701
|
+
previousViews: number;
|
|
702
|
+
/** Decay rate as percentage (negative = declining) */
|
|
703
|
+
decayRate: number;
|
|
704
|
+
/** Severity of decay */
|
|
705
|
+
severity: 'severe' | 'moderate' | 'mild';
|
|
706
|
+
/** Actionable suggestion */
|
|
707
|
+
suggestion: string;
|
|
708
|
+
}
|
|
709
|
+
interface ContentDecayData {
|
|
710
|
+
/** Time range analyzed */
|
|
711
|
+
period: {
|
|
712
|
+
current: {
|
|
713
|
+
start: string;
|
|
714
|
+
end: string;
|
|
715
|
+
};
|
|
716
|
+
previous: {
|
|
717
|
+
start: string;
|
|
718
|
+
end: string;
|
|
719
|
+
};
|
|
720
|
+
days: number;
|
|
721
|
+
};
|
|
722
|
+
/** Number of videos analyzed */
|
|
723
|
+
videosAnalyzed: number;
|
|
724
|
+
/** Videos experiencing significant decay */
|
|
725
|
+
decayingVideos: DecayingVideo[];
|
|
726
|
+
/** Summary stats */
|
|
727
|
+
summary: {
|
|
728
|
+
totalDecaying: number;
|
|
729
|
+
severeCount: number;
|
|
730
|
+
moderateCount: number;
|
|
731
|
+
mildCount: number;
|
|
732
|
+
/** Combined view loss from all decaying videos */
|
|
733
|
+
totalViewsLost: number;
|
|
734
|
+
};
|
|
735
|
+
/** Human-readable summary */
|
|
736
|
+
insight: string;
|
|
737
|
+
/** What content decay means */
|
|
738
|
+
whatThisMeans: string;
|
|
739
|
+
}
|
|
740
|
+
type ContentDecayResponse = (InsufficientDataResponse) | {
|
|
741
|
+
hasData: true;
|
|
742
|
+
data: ContentDecayData;
|
|
743
|
+
_meta: InsightMeta;
|
|
744
|
+
};
|
|
745
|
+
interface DayPerformance {
|
|
746
|
+
day: string;
|
|
747
|
+
avgFirstDayViews: number;
|
|
748
|
+
avgEngagement: number;
|
|
749
|
+
videoCount: number;
|
|
750
|
+
/** Confidence in this data */
|
|
751
|
+
confidence: 'high' | 'medium' | 'low';
|
|
752
|
+
}
|
|
753
|
+
interface TimeSlotPerformance {
|
|
754
|
+
slot: string;
|
|
755
|
+
label: string;
|
|
756
|
+
avgFirstDayViews: number;
|
|
757
|
+
videoCount: number;
|
|
758
|
+
confidence: 'high' | 'medium' | 'low';
|
|
759
|
+
}
|
|
760
|
+
interface AudienceActivityData {
|
|
761
|
+
/** How many videos were analyzed */
|
|
762
|
+
videosAnalyzed: number;
|
|
763
|
+
/** Day when your audience is most active */
|
|
764
|
+
mostActiveDay: {
|
|
765
|
+
day: string;
|
|
766
|
+
confidence: 'high' | 'medium' | 'low';
|
|
767
|
+
/** Why this day shows highest activity */
|
|
768
|
+
reason: string;
|
|
769
|
+
};
|
|
770
|
+
/** Time slot when your audience is most active */
|
|
771
|
+
mostActiveTimeSlot: {
|
|
772
|
+
slot: string;
|
|
773
|
+
label: string;
|
|
774
|
+
confidence: 'high' | 'medium' | 'low';
|
|
775
|
+
reason: string;
|
|
776
|
+
};
|
|
777
|
+
/** Full breakdown by day */
|
|
778
|
+
dayBreakdown: DayPerformance[];
|
|
779
|
+
/** Full breakdown by time slot (if enough data) */
|
|
780
|
+
timeBreakdown: TimeSlotPerformance[] | null;
|
|
781
|
+
/** Human-readable summary */
|
|
782
|
+
insight: string;
|
|
783
|
+
/** Disclaimer about the data */
|
|
784
|
+
disclaimer: string;
|
|
785
|
+
}
|
|
786
|
+
type AudienceActivityResponse = (InsufficientDataResponse) | {
|
|
787
|
+
hasData: true;
|
|
788
|
+
data: AudienceActivityData;
|
|
789
|
+
_meta: InsightMeta;
|
|
790
|
+
};
|
|
791
|
+
/** @deprecated Use AudienceActivityData instead */
|
|
792
|
+
type BestUploadTimeData = AudienceActivityData;
|
|
793
|
+
/** @deprecated Use AudienceActivityResponse instead */
|
|
794
|
+
type BestUploadTimeResponse = AudienceActivityResponse;
|
|
795
|
+
interface FadingHitVideo {
|
|
796
|
+
videoId: string;
|
|
797
|
+
title: string;
|
|
798
|
+
thumbnailUrl: string | null;
|
|
799
|
+
publishedAt: string;
|
|
800
|
+
watchUrl: string;
|
|
801
|
+
/** How old the video is in days */
|
|
802
|
+
ageInDays: number;
|
|
803
|
+
/** Performance during peak period (actual peak, not just first 14 days) */
|
|
804
|
+
peakPerformance: {
|
|
805
|
+
/** Average daily views during peak window */
|
|
806
|
+
dailyViews: number;
|
|
807
|
+
/** Comparison to channel average (e.g., "45% above average") */
|
|
808
|
+
vsChannelAverage: string;
|
|
809
|
+
/** Was this a top performer (2x+ channel average)? */
|
|
810
|
+
wasTopPerformer: boolean;
|
|
811
|
+
/** When the actual peak occurred */
|
|
812
|
+
peakPeriod: {
|
|
813
|
+
start: string;
|
|
814
|
+
end: string;
|
|
815
|
+
/** How many days after upload the peak occurred */
|
|
816
|
+
daysAfterUpload: number;
|
|
817
|
+
/** True if video went viral later (not at launch) - delayed virality */
|
|
818
|
+
wasDelayedViral: boolean;
|
|
819
|
+
};
|
|
820
|
+
};
|
|
821
|
+
/** Performance in recent period (last 14 days) */
|
|
822
|
+
currentPerformance: {
|
|
823
|
+
/** Current average daily views */
|
|
824
|
+
dailyViews: number;
|
|
825
|
+
/** Percentage decline from peak (negative number) */
|
|
826
|
+
declineFromPeak: number;
|
|
827
|
+
};
|
|
828
|
+
/** How likely revival efforts would work */
|
|
829
|
+
revivalPotential: 'high' | 'medium' | 'low';
|
|
830
|
+
/** Why this video might be worth reviving */
|
|
831
|
+
whyRevive: string;
|
|
832
|
+
/** Specific suggestions to revive this video */
|
|
833
|
+
suggestions: string[];
|
|
834
|
+
}
|
|
835
|
+
interface FadingHitsData {
|
|
836
|
+
/** Time period for "current" performance check */
|
|
837
|
+
period: {
|
|
838
|
+
current: {
|
|
839
|
+
start: string;
|
|
840
|
+
end: string;
|
|
841
|
+
};
|
|
842
|
+
label: string;
|
|
843
|
+
};
|
|
844
|
+
/** Number of videos analyzed */
|
|
845
|
+
videosAnalyzed: number;
|
|
846
|
+
/** Videos that were performing above average but are now declining */
|
|
847
|
+
fadingHits: FadingHitVideo[];
|
|
848
|
+
/** Summary stats */
|
|
849
|
+
summary: {
|
|
850
|
+
totalFading: number;
|
|
851
|
+
highPotentialCount: number;
|
|
852
|
+
mediumPotentialCount: number;
|
|
853
|
+
lowPotentialCount: number;
|
|
854
|
+
/** Combined daily views being lost */
|
|
855
|
+
totalDailyViewsLost: number;
|
|
856
|
+
};
|
|
857
|
+
/** Human-readable summary */
|
|
858
|
+
insight: string;
|
|
859
|
+
/** What fading hits means */
|
|
860
|
+
whatThisMeans: string;
|
|
861
|
+
}
|
|
862
|
+
type FadingHitsResponse = (InsufficientDataResponse) | {
|
|
863
|
+
hasData: true;
|
|
864
|
+
data: FadingHitsData;
|
|
865
|
+
_meta: InsightMeta;
|
|
866
|
+
};
|
|
867
|
+
type SubscriberQualityLabel = 'excellent' | 'good' | 'fair' | 'needs_attention' | 'concerning';
|
|
868
|
+
interface SubscriberQualityData {
|
|
869
|
+
/** Time range analyzed */
|
|
870
|
+
period: {
|
|
871
|
+
start: string;
|
|
872
|
+
end: string;
|
|
873
|
+
days: number;
|
|
874
|
+
};
|
|
875
|
+
/** Overall quality score (0-100) */
|
|
876
|
+
qualityScore: number;
|
|
877
|
+
/** Score interpretation */
|
|
878
|
+
scoreLabel: SubscriberQualityLabel;
|
|
879
|
+
/** Core metrics */
|
|
880
|
+
metrics: {
|
|
881
|
+
/** Total subscribers gained */
|
|
882
|
+
subscribersGained: number;
|
|
883
|
+
/** Total subscribers lost */
|
|
884
|
+
subscribersLost: number;
|
|
885
|
+
/** Net subscriber change */
|
|
886
|
+
netSubscribers: number;
|
|
887
|
+
/** Retention rate (how many stay) */
|
|
888
|
+
retentionRate: number;
|
|
889
|
+
/** Average watch time per view */
|
|
890
|
+
avgWatchTimeMinutes: number;
|
|
891
|
+
/** Views per subscriber (engagement proxy) */
|
|
892
|
+
viewsPerSubscriber: number;
|
|
893
|
+
};
|
|
894
|
+
/** Comparison to previous period */
|
|
895
|
+
trend: {
|
|
896
|
+
scoreChange: number;
|
|
897
|
+
direction: 'improving' | 'stable' | 'declining';
|
|
898
|
+
description: string;
|
|
899
|
+
};
|
|
900
|
+
/** Human-readable summary */
|
|
901
|
+
insight: string;
|
|
902
|
+
/** Specific recommendations */
|
|
903
|
+
recommendations: string[];
|
|
904
|
+
}
|
|
905
|
+
type SubscriberQualityResponse = (InsufficientDataResponse) | {
|
|
906
|
+
hasData: true;
|
|
907
|
+
data: SubscriberQualityData;
|
|
908
|
+
_meta: InsightMeta;
|
|
909
|
+
};
|
|
910
|
+
type FatigueLevel = 'none' | 'low' | 'moderate' | 'high' | 'critical';
|
|
911
|
+
interface FatigueSignal {
|
|
912
|
+
/** Name of the signal */
|
|
913
|
+
name: string;
|
|
914
|
+
/** Current period value */
|
|
915
|
+
current: number;
|
|
916
|
+
/** Previous period value */
|
|
917
|
+
previous: number;
|
|
918
|
+
/** Change percentage (negative = declining) */
|
|
919
|
+
changePercent: number;
|
|
920
|
+
/** Whether this signal indicates fatigue */
|
|
921
|
+
indicatesFatigue: boolean;
|
|
922
|
+
/** Description of what this means */
|
|
923
|
+
interpretation: string;
|
|
924
|
+
}
|
|
925
|
+
interface AudienceFatigueData {
|
|
926
|
+
/** Time periods compared */
|
|
927
|
+
period: {
|
|
928
|
+
current: {
|
|
929
|
+
start: string;
|
|
930
|
+
end: string;
|
|
931
|
+
};
|
|
932
|
+
previous: {
|
|
933
|
+
start: string;
|
|
934
|
+
end: string;
|
|
935
|
+
};
|
|
936
|
+
daysPerPeriod: number;
|
|
937
|
+
};
|
|
938
|
+
/** Overall fatigue index (0-100, higher = more fatigue) */
|
|
939
|
+
fatigueIndex: number;
|
|
940
|
+
/** Human-readable fatigue level */
|
|
941
|
+
fatigueLevel: FatigueLevel;
|
|
942
|
+
/** Individual signals that contribute to the score */
|
|
943
|
+
signals: {
|
|
944
|
+
watchTimePerView: FatigueSignal;
|
|
945
|
+
engagementRate: FatigueSignal;
|
|
946
|
+
subscriberChurn: FatigueSignal;
|
|
947
|
+
viewsPerVideo: FatigueSignal;
|
|
948
|
+
};
|
|
949
|
+
/** Summary of signals */
|
|
950
|
+
summary: {
|
|
951
|
+
signalsIndicatingFatigue: number;
|
|
952
|
+
totalSignals: number;
|
|
953
|
+
primaryConcern: string | null;
|
|
954
|
+
};
|
|
955
|
+
/** Human-readable insight */
|
|
956
|
+
insight: string;
|
|
957
|
+
/** What to do about it */
|
|
958
|
+
recommendations: string[];
|
|
959
|
+
}
|
|
960
|
+
type AudienceFatigueResponse = (InsufficientDataResponse) | {
|
|
961
|
+
hasData: true;
|
|
962
|
+
data: AudienceFatigueData;
|
|
963
|
+
_meta: InsightMeta;
|
|
964
|
+
};
|
|
965
|
+
interface LengthBucketPerformance {
|
|
966
|
+
/** Bucket name (e.g., "5-10 minutes") */
|
|
967
|
+
bucket: string;
|
|
968
|
+
/** Bucket range in seconds */
|
|
969
|
+
range: {
|
|
970
|
+
min: number;
|
|
971
|
+
max: number | null;
|
|
972
|
+
};
|
|
973
|
+
/** Number of videos in this bucket */
|
|
974
|
+
videoCount: number;
|
|
975
|
+
/** Average retention as percentage */
|
|
976
|
+
avgRetention: number;
|
|
977
|
+
/** Average engagement rate */
|
|
978
|
+
avgEngagement: number;
|
|
979
|
+
/** Average views per video */
|
|
980
|
+
avgViews: number;
|
|
981
|
+
/** Combined performance score (0-100) */
|
|
982
|
+
performanceScore: number;
|
|
983
|
+
/** Is this the optimal bucket? */
|
|
984
|
+
isOptimal: boolean;
|
|
985
|
+
}
|
|
986
|
+
interface OptimalVideoLengthData {
|
|
987
|
+
/** How many videos were analyzed */
|
|
988
|
+
videosAnalyzed: number;
|
|
989
|
+
/** The recommended optimal length range */
|
|
990
|
+
optimalLength: {
|
|
991
|
+
bucket: string;
|
|
992
|
+
range: {
|
|
993
|
+
min: number;
|
|
994
|
+
max: number | null;
|
|
995
|
+
};
|
|
996
|
+
confidence: 'high' | 'medium' | 'low';
|
|
997
|
+
reason: string;
|
|
998
|
+
};
|
|
999
|
+
/** Performance breakdown by length bucket */
|
|
1000
|
+
breakdown: LengthBucketPerformance[];
|
|
1001
|
+
/** Key findings */
|
|
1002
|
+
findings: {
|
|
1003
|
+
bestRetention: {
|
|
1004
|
+
bucket: string;
|
|
1005
|
+
value: number;
|
|
1006
|
+
};
|
|
1007
|
+
bestEngagement: {
|
|
1008
|
+
bucket: string;
|
|
1009
|
+
value: number;
|
|
1010
|
+
};
|
|
1011
|
+
mostCommon: {
|
|
1012
|
+
bucket: string;
|
|
1013
|
+
count: number;
|
|
1014
|
+
};
|
|
1015
|
+
};
|
|
1016
|
+
/** Human-readable insight */
|
|
1017
|
+
insight: string;
|
|
1018
|
+
/** Specific recommendations */
|
|
1019
|
+
recommendations: string[];
|
|
1020
|
+
}
|
|
1021
|
+
type OptimalVideoLengthResponse = (InsufficientDataResponse) | {
|
|
1022
|
+
hasData: true;
|
|
1023
|
+
data: OptimalVideoLengthData;
|
|
1024
|
+
_meta: InsightMeta;
|
|
1025
|
+
};
|
|
1026
|
+
interface AllInsightsData {
|
|
1027
|
+
bestPerformingVideo: BestPerformingVideoResponse;
|
|
1028
|
+
contentDecay: ContentDecayResponse;
|
|
1029
|
+
audienceActivity: AudienceActivityResponse;
|
|
1030
|
+
subscriberQuality: SubscriberQualityResponse;
|
|
1031
|
+
fadingHits: FadingHitsResponse;
|
|
1032
|
+
audienceFatigue: AudienceFatigueResponse;
|
|
1033
|
+
optimalLength: OptimalVideoLengthResponse;
|
|
1034
|
+
}
|
|
1035
|
+
interface AllInsightsResponse {
|
|
1036
|
+
data: AllInsightsData;
|
|
1037
|
+
_meta: {
|
|
1038
|
+
calculatedAt: string;
|
|
1039
|
+
insightsAvailable: string[];
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
interface GetBestVideoParams {
|
|
1043
|
+
/** Number of days to analyze (1-90, default: 30) */
|
|
1044
|
+
period?: number;
|
|
1045
|
+
}
|
|
1046
|
+
interface GetContentDecayParams {
|
|
1047
|
+
/** Days per comparison period (3-14, default: 7) */
|
|
1048
|
+
period?: number;
|
|
1049
|
+
}
|
|
1050
|
+
interface GetSubscriberQualityParams {
|
|
1051
|
+
/** Number of days to analyze (14-180, default: 90) */
|
|
1052
|
+
period?: number;
|
|
1053
|
+
}
|
|
1054
|
+
interface GetAudienceFatigueParams {
|
|
1055
|
+
/** Days per comparison period (14-90, default: 30) */
|
|
1056
|
+
period?: number;
|
|
1057
|
+
}
|
|
597
1058
|
}
|
|
598
1059
|
declare namespace Activity {
|
|
599
1060
|
/**
|
|
@@ -1092,6 +1553,244 @@ declare class InsightsModule {
|
|
|
1092
1553
|
* GET /v1/insights/youtube/momentum/history
|
|
1093
1554
|
*/
|
|
1094
1555
|
getYouTubeMomentumHistory(params?: Insights.GetMomentumHistoryParams): Promise<Insights.MomentumHistoryResponse>;
|
|
1556
|
+
/**
|
|
1557
|
+
* Get the best performing video in a time period
|
|
1558
|
+
*
|
|
1559
|
+
* Identifies your top video by views and explains WHY it performed well.
|
|
1560
|
+
*
|
|
1561
|
+
* @param params - Query parameters
|
|
1562
|
+
* @param params.period - Days to analyze (1-90, default: 30)
|
|
1563
|
+
*
|
|
1564
|
+
* @example
|
|
1565
|
+
* ```typescript
|
|
1566
|
+
* const result = await client.insights.getYouTubeBestVideo({ period: 30 });
|
|
1567
|
+
*
|
|
1568
|
+
* if (result.hasData) {
|
|
1569
|
+
* console.log(`🏆 ${result.data.topVideo.title}`);
|
|
1570
|
+
* console.log(`Views: ${result.data.metrics.views}`);
|
|
1571
|
+
* console.log(`${result.data.comparison.vsChannelAverage.description}`);
|
|
1572
|
+
* console.log(result.data.insight);
|
|
1573
|
+
*
|
|
1574
|
+
* // Show how it was calculated
|
|
1575
|
+
* console.log(result._meta.howWeCalculatedThis.method);
|
|
1576
|
+
* } else {
|
|
1577
|
+
* console.log(result.suggestion);
|
|
1578
|
+
* }
|
|
1579
|
+
* ```
|
|
1580
|
+
*
|
|
1581
|
+
* GET /v1/insights/youtube/best-video
|
|
1582
|
+
*/
|
|
1583
|
+
getYouTubeBestVideo(params?: Insights.GetBestVideoParams): Promise<Insights.BestPerformingVideoResponse>;
|
|
1584
|
+
/**
|
|
1585
|
+
* Find videos that are losing momentum
|
|
1586
|
+
*
|
|
1587
|
+
* Compares current period vs previous period to identify declining videos.
|
|
1588
|
+
* Provides actionable suggestions for each decaying video.
|
|
1589
|
+
*
|
|
1590
|
+
* @param params - Query parameters
|
|
1591
|
+
* @param params.period - Days per comparison period (3-14, default: 7)
|
|
1592
|
+
*
|
|
1593
|
+
* @example
|
|
1594
|
+
* ```typescript
|
|
1595
|
+
* const result = await client.insights.getYouTubeContentDecay({ period: 7 });
|
|
1596
|
+
*
|
|
1597
|
+
* if (result.hasData) {
|
|
1598
|
+
* console.log(result.data.insight);
|
|
1599
|
+
* console.log(`${result.data.summary.totalDecaying} videos declining`);
|
|
1600
|
+
*
|
|
1601
|
+
* for (const video of result.data.decayingVideos) {
|
|
1602
|
+
* console.log(`📉 ${video.title}: ${video.decayRate}%`);
|
|
1603
|
+
* console.log(` ${video.suggestion}`);
|
|
1604
|
+
* }
|
|
1605
|
+
* }
|
|
1606
|
+
* ```
|
|
1607
|
+
*
|
|
1608
|
+
* GET /v1/insights/youtube/content-decay
|
|
1609
|
+
*/
|
|
1610
|
+
getYouTubeContentDecay(params?: Insights.GetContentDecayParams): Promise<Insights.ContentDecayResponse>;
|
|
1611
|
+
/**
|
|
1612
|
+
* Get when your audience is most active
|
|
1613
|
+
*
|
|
1614
|
+
* Unlike generic advice, this is based on YOUR audience's behavior.
|
|
1615
|
+
* Analyzes first-day performance by publish day and time to identify
|
|
1616
|
+
* when your audience is most engaged.
|
|
1617
|
+
*
|
|
1618
|
+
* @example
|
|
1619
|
+
* ```typescript
|
|
1620
|
+
* const result = await client.insights.getYouTubeAudienceActivity();
|
|
1621
|
+
*
|
|
1622
|
+
* if (result.hasData) {
|
|
1623
|
+
* console.log(`📅 Most active day: ${result.data.mostActiveDay.day}`);
|
|
1624
|
+
* console.log(`⏰ Peak time: ${result.data.mostActiveTimeSlot.label}`);
|
|
1625
|
+
* console.log(result.data.insight);
|
|
1626
|
+
*
|
|
1627
|
+
* // Show day breakdown
|
|
1628
|
+
* for (const day of result.data.dayBreakdown) {
|
|
1629
|
+
* console.log(`${day.day}: ${day.avgFirstDayViews} avg views`);
|
|
1630
|
+
* }
|
|
1631
|
+
* }
|
|
1632
|
+
* ```
|
|
1633
|
+
*
|
|
1634
|
+
* GET /v1/insights/youtube/audience-activity
|
|
1635
|
+
*/
|
|
1636
|
+
getYouTubeAudienceActivity(): Promise<Insights.AudienceActivityResponse>;
|
|
1637
|
+
/**
|
|
1638
|
+
* @deprecated Use `getYouTubeAudienceActivity()` instead
|
|
1639
|
+
*/
|
|
1640
|
+
getYouTubeBestUploadTime(): Promise<Insights.BestUploadTimeResponse>;
|
|
1641
|
+
/**
|
|
1642
|
+
* Find videos that were hits but are now declining
|
|
1643
|
+
*
|
|
1644
|
+
* Identifies videos that performed above your channel average initially
|
|
1645
|
+
* but have since lost momentum. These are revival opportunities.
|
|
1646
|
+
*
|
|
1647
|
+
* @example
|
|
1648
|
+
* ```typescript
|
|
1649
|
+
* const result = await client.insights.getYouTubeFadingHits();
|
|
1650
|
+
*
|
|
1651
|
+
* if (result.hasData) {
|
|
1652
|
+
* console.log(result.data.insight);
|
|
1653
|
+
* console.log(`${result.data.summary.totalFading} videos could use a boost`);
|
|
1654
|
+
*
|
|
1655
|
+
* for (const video of result.data.fadingHits) {
|
|
1656
|
+
* console.log(`📉 ${video.title}`);
|
|
1657
|
+
* console.log(` Peak: ${video.peakPeriod.avgDailyViews} views/day`);
|
|
1658
|
+
* console.log(` Now: ${video.currentPeriod.avgDailyViews} views/day`);
|
|
1659
|
+
* console.log(` Decline: ${video.decline.percentage}%`);
|
|
1660
|
+
* console.log(` Revival potential: ${video.revivalPotential}`);
|
|
1661
|
+
* console.log(` ${video.whyRevive}`);
|
|
1662
|
+
* for (const suggestion of video.suggestions) {
|
|
1663
|
+
* console.log(` 💡 ${suggestion}`);
|
|
1664
|
+
* }
|
|
1665
|
+
* }
|
|
1666
|
+
* }
|
|
1667
|
+
* ```
|
|
1668
|
+
*
|
|
1669
|
+
* GET /v1/insights/youtube/fading-hits
|
|
1670
|
+
*/
|
|
1671
|
+
getYouTubeFadingHits(): Promise<Insights.FadingHitsResponse>;
|
|
1672
|
+
/**
|
|
1673
|
+
* Measure subscriber quality score (0-100)
|
|
1674
|
+
*
|
|
1675
|
+
* Analyzes whether new subscribers are engaged or just numbers.
|
|
1676
|
+
* Helps identify fake growth or low-quality audiences.
|
|
1677
|
+
*
|
|
1678
|
+
* @param params - Query parameters
|
|
1679
|
+
* @param params.period - Days to analyze (7-90, default: 30)
|
|
1680
|
+
*
|
|
1681
|
+
* @example
|
|
1682
|
+
* ```typescript
|
|
1683
|
+
* const result = await client.insights.getYouTubeSubscriberQuality({ period: 90 });
|
|
1684
|
+
*
|
|
1685
|
+
* if (result.hasData) {
|
|
1686
|
+
* console.log(`Quality Score: ${result.data.qualityScore}/100 (${result.data.scoreLabel})`);
|
|
1687
|
+
* console.log(`Retention: ${result.data.metrics.retentionRate}%`);
|
|
1688
|
+
* console.log(result.data.insight);
|
|
1689
|
+
*
|
|
1690
|
+
* // Show recommendations
|
|
1691
|
+
* for (const rec of result.data.recommendations) {
|
|
1692
|
+
* console.log(`💡 ${rec}`);
|
|
1693
|
+
* }
|
|
1694
|
+
* }
|
|
1695
|
+
* ```
|
|
1696
|
+
*
|
|
1697
|
+
* GET /v1/insights/youtube/subscriber-quality
|
|
1698
|
+
*/
|
|
1699
|
+
getYouTubeSubscriberQuality(params?: Insights.GetSubscriberQualityParams): Promise<Insights.SubscriberQualityResponse>;
|
|
1700
|
+
/**
|
|
1701
|
+
* Detect if your audience is getting tired of your content
|
|
1702
|
+
*
|
|
1703
|
+
* Compares key engagement metrics between recent and previous periods
|
|
1704
|
+
* to identify declining audience interest before it becomes critical.
|
|
1705
|
+
*
|
|
1706
|
+
* @param params - Query parameters
|
|
1707
|
+
* @param params.period - Days per comparison period (14-90, default: 30)
|
|
1708
|
+
*
|
|
1709
|
+
* @example
|
|
1710
|
+
* ```typescript
|
|
1711
|
+
* const result = await client.insights.getYouTubeAudienceFatigue({ period: 30 });
|
|
1712
|
+
*
|
|
1713
|
+
* if (result.hasData) {
|
|
1714
|
+
* console.log(`Fatigue Index: ${result.data.fatigueIndex}/100`);
|
|
1715
|
+
* console.log(`Level: ${result.data.fatigueLevel}`);
|
|
1716
|
+
* console.log(result.data.insight);
|
|
1717
|
+
*
|
|
1718
|
+
* // Check individual signals
|
|
1719
|
+
* if (result.data.signals.watchTimePerView.indicatesFatigue) {
|
|
1720
|
+
* console.log('⚠️ Watch time is declining');
|
|
1721
|
+
* }
|
|
1722
|
+
*
|
|
1723
|
+
* // Get recommendations
|
|
1724
|
+
* for (const rec of result.data.recommendations) {
|
|
1725
|
+
* console.log(`💡 ${rec}`);
|
|
1726
|
+
* }
|
|
1727
|
+
* }
|
|
1728
|
+
* ```
|
|
1729
|
+
*
|
|
1730
|
+
* GET /v1/insights/youtube/audience-fatigue
|
|
1731
|
+
*/
|
|
1732
|
+
getYouTubeAudienceFatigue(params?: Insights.GetAudienceFatigueParams): Promise<Insights.AudienceFatigueResponse>;
|
|
1733
|
+
/**
|
|
1734
|
+
* Find the ideal video length for YOUR audience
|
|
1735
|
+
*
|
|
1736
|
+
* Unlike generic "8-12 minutes is best" advice, this is personalized
|
|
1737
|
+
* based on how YOUR videos perform at different lengths.
|
|
1738
|
+
*
|
|
1739
|
+
* @example
|
|
1740
|
+
* ```typescript
|
|
1741
|
+
* const result = await client.insights.getYouTubeOptimalLength();
|
|
1742
|
+
*
|
|
1743
|
+
* if (result.hasData) {
|
|
1744
|
+
* console.log(`Optimal: ${result.data.optimalLength.bucket}`);
|
|
1745
|
+
* console.log(`Confidence: ${result.data.optimalLength.confidence}`);
|
|
1746
|
+
* console.log(result.data.insight);
|
|
1747
|
+
*
|
|
1748
|
+
* // Show breakdown by length
|
|
1749
|
+
* for (const bucket of result.data.breakdown) {
|
|
1750
|
+
* const marker = bucket.isOptimal ? '🏆' : ' ';
|
|
1751
|
+
* console.log(`${marker} ${bucket.bucket}: ${bucket.avgRetention}% retention, ${bucket.avgEngagement}% engagement`);
|
|
1752
|
+
* }
|
|
1753
|
+
*
|
|
1754
|
+
* // Recommendations
|
|
1755
|
+
* for (const rec of result.data.recommendations) {
|
|
1756
|
+
* console.log(`💡 ${rec}`);
|
|
1757
|
+
* }
|
|
1758
|
+
* }
|
|
1759
|
+
* ```
|
|
1760
|
+
*
|
|
1761
|
+
* GET /v1/insights/youtube/optimal-length
|
|
1762
|
+
*/
|
|
1763
|
+
getYouTubeOptimalLength(): Promise<Insights.OptimalVideoLengthResponse>;
|
|
1764
|
+
/**
|
|
1765
|
+
* Get all YouTube insights in one call
|
|
1766
|
+
*
|
|
1767
|
+
* Efficient for dashboard display - fetches all insights in parallel.
|
|
1768
|
+
* Each insight has `hasData: boolean` to check availability.
|
|
1769
|
+
*
|
|
1770
|
+
* @example
|
|
1771
|
+
* ```typescript
|
|
1772
|
+
* const all = await client.insights.getYouTubeAllInsights();
|
|
1773
|
+
*
|
|
1774
|
+
* // Check which insights are available
|
|
1775
|
+
* console.log('Available:', all._meta.insightsAvailable);
|
|
1776
|
+
*
|
|
1777
|
+
* // Use each insight
|
|
1778
|
+
* if (all.data.bestPerformingVideo.hasData) {
|
|
1779
|
+
* console.log(`Best: ${all.data.bestPerformingVideo.data.topVideo.title}`);
|
|
1780
|
+
* }
|
|
1781
|
+
*
|
|
1782
|
+
* if (all.data.audienceFatigue.hasData) {
|
|
1783
|
+
* console.log(`Fatigue: ${all.data.audienceFatigue.data.fatigueLevel}`);
|
|
1784
|
+
* }
|
|
1785
|
+
*
|
|
1786
|
+
* if (all.data.optimalLength.hasData) {
|
|
1787
|
+
* console.log(`Optimal Length: ${all.data.optimalLength.data.optimalLength.bucket}`);
|
|
1788
|
+
* }
|
|
1789
|
+
* ```
|
|
1790
|
+
*
|
|
1791
|
+
* GET /v1/insights/youtube/all
|
|
1792
|
+
*/
|
|
1793
|
+
getYouTubeAllInsights(): Promise<Insights.AllInsightsResponse>;
|
|
1095
1794
|
}
|
|
1096
1795
|
|
|
1097
1796
|
/**
|