# Tuberalytics API Reference > YouTube niche research + Skool revenue intelligence for content creators. Base URL: https://tuberalytics.com/api/v1 Authentication: Bearer token via Authorization header Format: JSON request and response bodies Rate limits: 20 req/min (GET), 5 req/min (POST/PATCH/DELETE) --- ## Authentication Include API key as Bearer token: Authorization: Bearer sk_live_your_api_key Generate keys at: https://tuberalytics.com/api_keys Errors: 401 - Missing API key: "Missing API key. Include 'Authorization: Bearer sk_live_...' header." 401 - Invalid key: "Invalid or revoked API key." --- ## Response Format Success (single resource): { "data": { ... } } Success (collection, paginated): { "data": [ ... ], "meta": { "current_page": 1, "per_page": 25, "total_pages": 10, "total_count": 250 } } Error: { "error": "Human-readable message" } Pagination params: page (default: 1), per_page (default: 25, max: 100) --- ## Rate Limit Headers X-RateLimit-Limit: 20 X-RateLimit-Remaining: 17 X-RateLimit-Reset: 1711843200 429 response: { "error": "Rate limit exceeded. Retry after X seconds.", "retry_after": X } --- ## Error Codes 200 OK - Success 201 Created - Resource created 202 Accepted - Async action queued 400 Bad Request - Missing parameter: { "error": "Missing parameter: name" } 401 Unauthorized - Auth failure 404 Not Found - { "error": "Not found: Channel" } 422 Unprocessable Entity - Validation error 429 Too Many Requests - Rate limit or usage limit exceeded --- ## CHANNELS ### GET /api/v1/channels/search Search channels by keyword. Params: q (string, required) - Search query (title or handle) min_subs (integer) - Minimum subscriber count max_subs (integer) - Maximum subscriber count tier (string) - Quality tier: dormant, steady, rising, established, viral, mega_viral, mega_channel has_skool (string) - "true" to filter channels with Skool sort_by (string) - subscribers (default), views, outliers, skool_mrr page, per_page - Pagination Response fields: id, youtube_channel_id, title, handle, thumbnail_url, country, subscriber_count, view_count, video_count, average_views, quality_classification, has_skool, skool_estimated_mrr, positive_outliers_count ### GET /api/v1/channels/:id Get channel details. Response fields: id, youtube_channel_id, title, handle, thumbnail_url, banner_url, country, description, subscriber_count, view_count, video_count, average_views, median_views, quality_classification, has_skool, skool_estimated_mrr, positive_outliers_count, avg_views_to_subs_ratio, is_faceless, is_verified, is_viral, last_published_at, channel_created_at, niches, created_at, updated_at ### GET /api/v1/channels/:id/profile Get AI-generated channel profile. Response fields: summary, language, content_style, title_writing_style, content_angles, title_formulas, thumbnail_styles Returns 404 if channel not yet analyzed. ### GET /api/v1/channels/:id/videos List channel videos. Params: kind (string) - Filter by video kind outliers (string) - "true" for positive outliers only page, per_page - Pagination Response fields: id, youtube_video_id, title, published_at, view_count, like_count, comment_count, is_positive_outlier, average_views_ratio, views_per_day ### GET /api/v1/channels/:id/competitors List channel competitors. Response fields: id, title, handle, subscriber_count, tracked, keyword_overlap_count, niche_overlap_count ### GET /api/v1/channels/:id/keywords Get channel and audience keywords. Response: { data: { channel_keywords: [{ name, position }], audience_keywords: [{ name, position }] } } ### GET /api/v1/channels/:id/skool Get Skool community data. Response fields: name, url, member_count, price_cents, is_paid, estimated_mrr_cents --- ## VIDEOS ### GET /api/v1/videos/search Search videos by title. Params: q (string, required) - Search query kind (string) - Filter by kind outliers (string) - "true" for positive outliers min_views (integer) - Minimum view count sort_by (string) - published (default), views, outlier_ratio, likes page, per_page - Pagination Response fields: id, youtube_video_id, channel_id, title, thumbnail_url, published_at, duration_seconds, view_count, like_count, comment_count, kind, is_positive_outlier, average_views_ratio, views_per_day ### GET /api/v1/videos/:id Get video details. Response fields: id, youtube_video_id, channel_id, title, thumbnail_url, published_at, duration_seconds, view_count, like_count, comment_count, kind, is_positive_outlier, is_negative_outlier, average_views_ratio, views_per_day, vsr, z_score, description, tags, channel { id, title, handle }, created_at, updated_at ### GET /api/v1/videos/:id/transcript Get video transcript. Response fields: text, language_code, word_count, fetched_at Returns 404 if no transcript available. ### GET /api/v1/videos/:id/comments List video comments. Params: page, per_page Response fields: id, author, text, like_count, reply_count, is_pinned, published_at --- ## NICHES ### GET /api/v1/niches/search Search niches by name. Params: q (string, required) - Search query market_type (string) - Filter by market type min_channels (integer) - Minimum channel count has_skool (string) - "true" for niches with Skool sort_by (string) - channels (default), demand, supply, monetization, skool_mrr page, per_page - Pagination Response fields: id, name, slug, channels_count, market_type, supply_score, demand_score, monetization_score, total_skool_mrr, avg_views_per_video ### GET /api/v1/niches/:id Get niche details. Response fields: id, name, slug, channels_count, market_type, supply_score, demand_score, monetization_score, total_skool_mrr, avg_views_per_video, description, youtube_revenue_score, niche_rpm, total_videos, total_subscribers, median_channel_subscribers, skool_channels_count, market_dynamics_computed_at, created_at, updated_at ### GET /api/v1/niches/:id/channels List channels in niche (paginated, sorted by subscriber_count desc). Params: page, per_page ### GET /api/v1/niches/:id/keywords Get niche keywords. Response fields: name, rank, autocompletes, suggestions ### GET /api/v1/niches/:id/videos List niche videos. Params: outliers (string) - "true" for positive outliers page, per_page --- ## LEADERBOARDS ### GET /api/v1/leaderboards/channels Top channels ranked. Params: sort_by (string) - subscribers (default), outliers, ratio, revenue, skool_mrr page, per_page ### GET /api/v1/leaderboards/videos Top videos ranked. Params: sort_by (string) - views (default), outlier_ratio, likes, vpd page, per_page ### GET /api/v1/leaderboards/niches Top niches ranked. Params: sort_by (string) - channels (default), demand, supply, monetization, skool_mrr page, per_page --- ## ACCOUNT ### GET /api/v1/me Get your profile. Response fields: id, email, name, plan_tier, created_at ### GET /api/v1/me/channels List your tracked channels. Response fields: id, youtube_channel_id, title, handle, subscriber_count, average_views, quality_classification, has_skool ### GET /api/v1/me/usage Get current usage stats. Response: { data: { tier, period_start, period_end, usage: { channel_analysis: { current, limit }, competitor_search: { current, limit }, keyword_generation: { current, limit }, niche_creation: { current, limit }, channels: { current, limit } } } } --- ## ACTIONS (Write Endpoints) All return HTTP 202 Accepted with { data: { status: "pending", message: "..." } } ### POST /api/v1/channels/:id/analyze Run AI channel analysis. No body required. Usage limit: channel_analysis Webhook: channel.analysis.completed, channel.analysis.failed ### POST /api/v1/channels/:id/competitors/discover Discover channel competitors. No body required. Usage limit: competitor_search Webhook: competitors.discovered ### POST /api/v1/channels/:id/keywords/generate Generate niche keywords. No body required. Usage limit: keyword_generation Error 422 if channel has no niche. Webhook: keywords.generated ### POST /api/v1/niches Create a new niche. Body: { name: "string" } (required) Usage limit: niche_creation Requires at least one tracked channel. Webhook: niche.synthesis.completed ### POST /api/v1/me/channels Add channel to tracking. Body: { youtube_url: "string" } (required) Accepted URL formats: youtube.com/channel/UCxxx, youtube.com/@handle, youtube.com/c/name Usage limit: channels Returns 201 Created. --- ## WEBHOOKS ### GET /api/v1/webhooks List webhook endpoints. Response fields: id, url, events, enabled, failure_count, last_triggered_at, created_at ### POST /api/v1/webhooks Create webhook endpoint. Body: { url: "https://..." (required), events: ["event.type"] (optional) } Returns 201 with signing_secret (only shown once). ### PATCH /api/v1/webhooks/:id Update webhook endpoint. Body: { url, events, enabled } (all optional) ### DELETE /api/v1/webhooks/:id Delete webhook endpoint. --- ## Webhook Events channel.analysis.completed - AI analysis finished successfully channel.analysis.failed - AI analysis failed niche.synthesis.completed - Niche synthesis completed niche.research.completed - Niche research run completed keywords.generated - Keyword generation completed competitors.discovered - Competitor discovery completed outlier.detected.niche - Outlier video in tracked niche outlier.detected.competitor - Outlier video from competitor video.new.competitor - New video from competitor Payload format: { "event": "event.type", "data": { ... }, "timestamp": "ISO8601" } Headers: X-Tuberalytics-Signature: sha256= X-Tuberalytics-Event: event.type X-Tuberalytics-Delivery: delivery_id Signature verification: HMAC-SHA256(signing_secret, JSON payload body) Retry policy: 1 min, 5 min, 30 min. Auto-disable after 10 consecutive failures. --- ## Usage Limits by Tier Starter Pro Unlimited channel_analysis 12/mo 40/mo 100/mo competitor_search 3/mo 10/mo 30/mo keyword_generation 6/mo 20/mo 50/mo niche_creation 1/mo 5/mo 15/mo channels 3/mo 10/mo 20/mo Limits shared between web UI and API. Reset on 1st of each month (UTC). 429 when exceeded: { "error": "Monthly limit reached for action", "usage": { "current": N, "limit": N, "tier": "tier", "resets_at": "ISO8601" } }