Data & Analytics
Overview
viral.app tracks and analyzes UGC performance across TikTok, Instagram, YouTube, and Facebook. This plugin connects ChatGPT and Codex to your viral.app workspace: query tracked account and video analytics, build leaderboards and KPI reports, manage tracking, organize content with tags and tag workflows, read Creator Hub campaigns, and pull live platform data when you need current numbers. Sign-in runs through OAuth and is scoped to one viral.app organization; tools that spend billable credits always quote their cost first and only execute after you confirm. Requires a viral.app account with API access.
Tools
Appends videos to the end of a brief's sample list — the organization's tracked videos by platform and platform video id, or viral-library videos by libraryVideoId (tracked as reference-only samples, hidden from analytics and payouts) — each with an optional label creators see above it. Videos the brief already lists are skipped. Silent by default; with notify=true and at least one video appended, the brief is re-published (version bump) and every creator in its audience is notified.
add_tracked_account_tags_bulk
ChatGPTAdds the given tags to multiple tracked accounts (union — nothing is removed) and backfills their existing videos in one pass. Tags ACCOUNTS in bulk — NOT individual videos. To tag one specific video, use add_video_tags.
add_tracked_accounts
ChatGPTStart tracking new social media accounts for the organization. Accounts the organization already tracks are skipped and left completely unchanged (their existing video limit is kept, no re-sync, no quota consumed) and are reported under alreadyTracked with their current limit. Write operation: consumes plan quota and triggers an initial sync for newly added accounts only. Tracking is ASYNCHRONOUS. After adding, the account's videos are NOT immediately available — they sync over the next few minutes via a background pipeline. Do NOT poll get_tracking_status or list_videos in a loop waiting for them. Add the account, then tell the user it is being fetched and that you will continue once it has synced. Already-tracked accounts are NEVER modified by this tool: re-adding does not change their video limit and does not trigger a new sync — they come back under alreadyTracked with their current limit, so report them as already tracked. To change an existing account's limit use update_account_max_videos; to force a fresh sync use refresh_tracked_accounts. BULK IMPORTS (CSV / long lists): accounts takes MANY entries per call. Do NOT list the org's tracked accounts to diff first — the alreadyTracked dedupe above does that for you, so send EVERYTHING and split the report from the responses (accounts = newly added, alreadyTracked = skipped). Size batches by how many UNKNOWN handles a call carries, not by its total: handles the org already tracks are matched in the database at no cost, while genuinely new handles are validated live at a fixed internal concurrency, so keep the NEW handles in one call to ~50-100 or it runs several minutes. Matching list sizes prove nothing about overlap, so the FIRST call carries at most ~100 entries whatever the roster looks like; read its response (alreadyTracked vs accounts counts) and only then scale: if most came back already tracked, send up to ~300 per call; if most were new, stay at ~50-100. Re-check after EVERY call, not only the first: rosters often keep their new rows together, so as soon as a call comes back mostly new, drop back to ~50-100 until calls come back mostly already tracked again. Validation is all-or-nothing per call — if the call errors with a list of invalid entries, remove EXACTLY those entries, retry the remaining batch once (validated handles are cached, so the retry costs no lookups), and list the removed entries in your final report instead of retrying them. facebook.com/share/… links are opaque — resolve them FIRST with resolve_facebook_share_urls and add the returned usernames; only plain-text names (no URL, no handle) are truly unresolvable. If the import is too large to finish in one go, finish what you can and tell the user precisely which rows are left. Only rows you actually submitted count as checked — never report the rest as verified.
add_tracked_videos
ChatGPTStarts tracking INDIVIDUAL videos (own or competitor) by platform + platform-native videoId. Extract the videoId from a full video URL (e.g. tiktok.com/@user/video/<id>); for TikTok short links (vm.tiktok.com) resolve first via resolve_tiktok_short_url. Counts against the tracked-videos plan meter. Tracking is ASYNCHRONOUS. After adding, the video's metrics are NOT immediately available — they sync in the background over the next few minutes. Do NOT poll list_videos waiting for them; tell the user it is being fetched.
add_video_tags
ChatGPTAssigns tags to a single video. Tags ONE specific video. The video must already be tracked AND synced (present in list_videos). If it is not there yet, do NOT retry — tell the user it is still syncing and you will tag it once ready. Each item in
tags is exactly { scope, tagId } — e.g. { scope: 'org', tagId: 'orgtag_…' }. Use the id field from create_tag / list_tags / resolve_tags results as tagId (scope 'org' for orgtag_ ids, 'project' for orgproj_ ids, 'system' for systag_ ids). Never pass tag names or whole tag objects.add_video_tags_bulk
ChatGPTAssigns the given tags to up to 100 videos in one call. Tags specific videos that must already be tracked and synced. Do NOT retry if the videos are not present yet. Each item in
tags is exactly { scope, tagId } — e.g. { scope: 'org', tagId: 'orgtag_…' }. Use the id field from create_tag / list_tags / resolve_tags results as tagId (scope 'org' for orgtag_ ids, 'project' for orgproj_ ids, 'system' for systag_ ids). Never pass tag names or whole tag objects.analyze_video
ChatGPTWatch a specific tracked video with Gemini and analyze its actual content. Provide
platform + platformVideoId (from a get_video / list_videos / get_top_videos result), a prompt describing what to analyze (hook, pacing, comment-bait, a virality score, on-screen text, etc.), and OPTIONALLY an outputSchema — a JSON Schema object of the exact fields you want back so the result is structured. Shape the prompt and outputSchema from the user's request. To compare SEVERAL videos, call this once per video, then synthesize the pattern yourself. Only call this when the user asks about videos' real content. Spends 11 viral.app credits per analyzed video, charged only when the analysis succeeds.apply_tag_workflow_to_past_videos
ChatGPTEnqueues a background run to apply the workflow to historical videos. Metric workflows are free; AI workflows send every matched video to the model once, capped per run. ⚠️ Consumes extra credits: 11 credits ($0.011) per evaluated video; cached evaluations are free. Metric workflows consume none.
assign_creators_to_campaign
ChatGPTAssigns one or more creators to a campaign from a start basis: prev, current or next for a fixed-anchor campaign (dates from get_assignment_options), custom with startDate for a rolling one (the day they join, today by default). A creator holds one running or scheduled assignment at a time. creatorIds are orgcre_… ids from list_creators, campaignId an orgcamp_… id from list_campaigns. One call carries many creators — never loop per creator. Runs only after get_assignment_options and the start question. customRates (only when the user asks for different rates for these creators) needs preview_creator_custom_rates with mode merge first and its previewHash as customRatesPreviewHash.
calculate_payout_preview
ChatGPTRuns the payout engine for ONE creator + billing window and returns the calculated amount with line items — a preview only, it never initiates payment. Computationally heavy (live analytics queries): call once per creator/window the user asks about, never in bulk loops.
count_applications
ChatGPTReturns the number of applications per brand tab: open, in review, and closed.
count_jobs
ChatGPTReturns the total number of job postings matching optional filters.
create_brief
ChatGPTCreates a brief from markdown (contentMarkdown) and returns its id. Optional: ordered sample videos from the organization's tracked videos, and who reads it — campaignIds to link (a campaign holds one brief, so linking moves it off any other brief), creatorIds to send it to creators directly (from list_creators), or allCreators=true for everyone at the organization (alone, never with campaigns or creators). Every creator it reaches must read it on their next visit. Viral-library videos are attached afterwards with add_brief_sample_videos. notify=true also notifies them (in the app and by email): only when the user asked for it. Show the user the full draft before calling.
create_campaign
ChatGPTCreates a campaign from a spec: name, schedule (interval, intervalCount, anchor rolling|fixed, optional startsOn), videoTarget, optional briefId and payouts (fixedSalary, basePayouts, cpmPayouts, flatBonuses, performanceCap, eligibility). Amounts are major units (10 = 10.00); tiers are half-open [from, to). Returns the campaign with its sentences. Only after preview_campaign returned ok and the user saw its sentences; send exactly the spec it returned plus its previewHash — the call is refused without one (PREVIEW_REQUIRED) and on a mismatch. briefId attaches a brief (none by default).
create_creator
ChatGPTCreates a creator in the organization (firstName, lastName, email). Optionally links tracked accounts (accountIds) and sends the invitation email in the same call (invite: true). Counts against the active-creators plan meter. ONBOARDING CHAIN: to also link social handles, first add_tracked_accounts(handles), then list_tracked_accounts to fetch the new orgacc_ ids (the add result does not include them), then pass those as accountIds here. Setting invite: true SENDS THE INVITATION EMAIL immediately — state the exact recipient email in your message before this call so the user approves knowingly.
create_job
ChatGPTCreates a job posting for the creator marketplace as a DRAFT and returns it: the product (productTitle, productDescription, logoUrl), who may apply (niches, formats, countries, languages, age, platforms, weekly hours or videos), the application challenge as markdown (challengeBriefMarkdown), the pay (currency, payFrequency, amounts) and the posting body as markdown (bodyMarkdown). Creators see nothing until set_job_status publishes it with status "public": show the user the draft and ask before publishing.
create_tag
ChatGPTCreates a new organization tag.
create_tag_workflow
ChatGPTCreates a new tag workflow and, with
applyToPastVideos, enqueues a one-time backfill over existing videos. Without it the workflow only sees videos that sync in afterwards. ⚠️ Consumes extra credits: 11 credits ($0.011) per evaluated video; cached evaluations are free. Metric workflows consume none, and a workflow created without a backfill consumes nothing up front.delete_brief
ChatGPTPermanently deletes a brief. Its audience links, sample references, and read receipts cascade; sample videos the brief created (and nothing else references) are untracked. Silent, like unlinking a campaign: the brief's audience is not notified.
delete_event_subscription
ChatGPTDeletes one MCP event subscription (automation) by its id (
mcpsub_…, from list_event_subscriptions): its events stop at once. You can delete your own; owners and admins any in the organization. Returns deleted: false when there is no such subscription you may delete.delete_tag
ChatGPTDeletes an organization tag. Refused with 400 while an active workflow still assigns the tag, and with 409
CONFLICT while a campaign's payout conditions (ended campaigns included) name it; data.campaigns lists those campaigns.delete_tag_workflow
ChatGPTSoft deletes a workflow. Applied tag assignments are kept unless deleteAssignments is set.
delete_tags_bulk
ChatGPTDeletes multiple organization tags. Tags still assigned by workflows, or named in a campaign's payout conditions (ended campaigns included), are skipped and reported in
blocked with the reason.duplicate_job
ChatGPTClones an existing job posting into a new draft under a new title. The copy keeps the source configuration and always starts as a draft.
end_campaign
ChatGPTSets a campaign's end date on a cycle boundary: endBasis prev, current or next (the dates come from get_campaign_end_context), or custom with endDate. Assignments reaching past the end make the call fail unless the user consented to endAssignments (each moves to its last full period before the end) or revokeAssignments (rows that cannot keep one full period are deleted). Relay the returned warnings: Highest Tier bonus tiers the end keeps from paying. Pass endAssignments / revokeAssignments only when the user chose them in the consent question. Without consent the call fails on assignments reaching past the end (ASSIGNMENTS_ACTIVE, ASSIGNMENTS_AFTER_END) — report that, do not retry with flags the user did not choose.
find_similar_viral_videos
ChatGPTLibrary videos most similar to ONE viral-library video — same kind of app, format, hook and what happens on screen — ranked by the dossier embedding. Use the
id from a search result as videoId when the user likes one example and wants more of that kind; for a fresh topic use search_viral_video_library instead.get_account
ChatGPTGet profile and lifetime analytics detail for a single tracked account by platform (tiktok | instagram | youtube | facebook | snapchat) and the platform's native account ID.
get_account_history
ChatGPTGet an aggregated time series (day/week/month buckets) of a tracked account's metrics: views, likes, comments, shares, bookmarks, posts, paid/organic views, engagement rate, and follower/following levels over time.
get_analytics_kpis
ChatGPTGet organization-wide KPI metrics (views, likes, comments, shares, engagement) across all tracked accounts and videos for a date range. Best first call for questions like 'how did we perform last week'. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.get_application
ChatGPTRetrieves one application with the applicant's discovery profile, portfolio, challenge submissions, and social accounts. Contact details are only included once the application is accepted.
get_assignment_options
ChatGPTPreflight for assign_creators_to_campaign: the cycle start dates a fixed-anchor campaign offers behind startBasis prev, current and next (startOptions; a basis the assign would refuse is null, and the whole object is null for rolling campaigns, which start on a custom day), today, and per creator whether an archived status or a running or scheduled assignment already blocks the assign (blockedBy) and which campaign they are on. Read it before assign_creators_to_campaign. Fixed campaigns: when today is the cycle's first day use startBasis current without asking; mid-cycle ask the user today vs current vs next in one question showing the three dates — today joins mid-period (the running cycle becomes the first period, starting today, a fixed salary in it paid pro rata), current backdates to the cycle's start and pays it in full, next waits for the boundary; a basis the preflight returns as null would fail (before the campaign starts, or past its end date), so never offer it. Rolling campaigns: startBasis custom with startDate today unless the user names a day. Creators with blockedBy set cannot be assigned — say which and why (archived ones need unarchiving in the app); switching or unassigning is done in the app. blockedBy payout_hold on every creator means hiring is on hold until the organization's overdue creator payouts are settled — point to the Payouts page instead of retrying.
get_brief
ChatGPTRetrieves a brief with its content (as TipTap JSON and as markdown), its audience, read progress, ordered sample videos, and how many creators a notify would reach right now.
get_brief_read_status
ChatGPTLists the creators who read a brief: per creator the routes it reaches them through (campaign, sent directly, everyone), whether they read the current version, an earlier one, or not yet, and when they were last notified. Counts cover the whole audience; creators who have not joined the organization yet are only counted.
get_campaign
ChatGPTReads one campaign in full: its spec (the shape create_campaign and update_campaign take), one sentence per rule-set (summary), the sheet's alerts (specWarnings), the schedule fields locked by usage (lockedFields), and any advanced rules the spec cannot express. Read it before an edit and to answer how a campaign pays. Read it before update_campaign or end_campaign and whenever asked how a campaign pays; quote the summary sentences. rules is the engine's raw form — never show or edit it; advancedRules survive every update untouched and are not editable here. customRates lists the creators paid with their own values on this campaign; their terms differ from the spec.
get_campaign_activity
ChatGPTPer-creator activity rows for creator-hub campaigns: current billing-period progress with a pace status (onSchedule/runningTight/overdue), date-range-normalized targets, and recent 14-day posting. Filter by pace bucket (all/onSchedule/behindSchedule — behindSchedule groups runningTight and overdue) to answer 'which creators are behind?'.
get_campaign_end_context
ChatGPTPreflight for end_campaign: the campaign's validity span, the cycle-aligned end dates behind endBasis prev, current and next (cycleEnds), and every assignment with its validity, the creator's latest settled payout window and whether settled payouts overlap it — what an end date would cut off. cycleEndWarnings lists, per date, the Highest Tier bonus tiers that end would keep from paying. Read it before end_campaign. Offer cycleEnds.current and cycleEnds.next as the end date (never invent one), with the cycleEndWarnings of each, and, when assignments reach past the chosen end, ask the user in ONE question for consent to endAssignments and/or revokeAssignments — naming the creators — before calling end_campaign.
get_campaign_kpis
ChatGPTCreator-hub performance KPIs: campaign views (views gained by videos posted while the creator was assigned, counted for as long as the assignment lasts — no video-age window), posted and eligible videos, paid + projected spend, and effective/paid CPM. Monetary values are converted into the returned display currency (the campaign currency for a single-campaign scope, otherwise the organization default). Filter by campaignIds and/or creatorIds; scope 'dateRange' also returns a previous-period comparison. THE source for 'how is campaign X performing?'.
get_chat_messages
ChatGPTLists a conversation's messages with read receipts for both sides. Deleted messages are included as tombstones (
deletedAt set, empty content). - History (default): the newest limit messages, then older pages through nextPageToken; each page is in ascending order. The object cursor and nextCursor are the legacy form of the same paging. - Incremental sync (after): the messages created at or after 2 minutes before after, oldest first. Pass nextPageToken back with the same after until it is null. Messages commit slightly out of order (a broadcast inserts many at once), so the window deliberately overlaps what you already hold: dedupe on message id. createdAt never changes on edits, so after does not return an edited or deleted message again: follow those through the chat.message.updated and chat.message.deleted webhooks. A page token only continues the direction that issued it, and cursor cannot be combined with pageToken or after (400).get_chat_unread_count
ChatGPTReturns the number of conversations with unread messages. Organization staff must use scope "org".
get_creator
ChatGPTFull detail for one creator (id from list_creators): user/contact info, invitation status, linked social accounts, and profile. Use for follow-ups after payout, campaign, or performance questions.
get_creator_history
ChatGPTGet an aggregated time series (day/week/month buckets) of a creator's metrics summed across all of the creator's assigned accounts: views, likes, comments, shares, bookmarks, posts, paid/organic views, engagement rate, and follower/following levels over time.
get_job
ChatGPTRetrieves a single job posting of the current organization, including drafts and paused jobs.
get_payout_breakdown
ChatGPTReturns the immutable engine breakdown snapshot recorded when the payout was issued, plus the invoiced line items. Cheap read — never re-runs the payout engine.
get_payout_counts
ChatGPTCounts the organization's creator payouts by status (upcoming, due, canceled, paid). Cheap first call to answer 'do I owe anything?'.
get_plan_usage
ChatGPTThe organization's current subscription: plan/product, status, billing period, and included benefits. Admin/owner only — other roles get a permission error; use get_usage_meter for usage counters available to every member.
get_tag_workflow_impact
ChatGPTReturns how many automated tag assignments this workflow currently owns.
get_top_accounts
ChatGPTGet the organization's top performing tracked social accounts for a date range, ranked by metric gains. Metric semantics: plain metrics (viewCount, likeCount, …) rank by LIFETIME totals and surface old evergreen content. When the user asks about a time window ('last 30 days', 'this week'), rank by the matching *InPeriod metric (e.g. viewCountInPeriod) — the dateRange alone does NOT change the ranking. Every result row already contains both lifetime and in-period numbers, so do not re-call with tweaked filters to cross-check. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.get_top_creators
ChatGPTGet the organization's top performing creators (Creator Hub) for a date range, ranked by metric gains across their accounts. Metric semantics: plain metrics (viewCount, likeCount, …) rank by LIFETIME totals and surface old evergreen content. When the user asks about a time window ('last 30 days', 'this week'), rank by the matching *InPeriod metric (e.g. viewCountInPeriod) — the dateRange alone does NOT change the ranking. Every result row already contains both lifetime and in-period numbers, so do not re-call with tweaked filters to cross-check. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.get_top_videos
ChatGPTGet the organization's top performing tracked videos for a date range, ranked by metric gains (e.g. views). Use to answer 'which videos popped'. Metric semantics: plain metrics (viewCount, likeCount, …) rank by LIFETIME totals and surface old evergreen content. When the user asks about a time window ('last 30 days', 'this week'), rank by the matching *InPeriod metric (e.g. viewCountInPeriod) — the dateRange alone does NOT change the ranking. Every result row already contains both lifetime and in-period numbers, so do not re-call with tweaked filters to cross-check. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.get_tracking_status
ChatGPTList recent tracking sync runs (queued/running/completed/failed). Use after add_tracked_accounts or refresh_* tools to check whether syncs finished; filter by eventIds returned from those calls.
get_usage_meter
ChatGPTUsage vs included quota for one plan meter: eventName is one of 'tracked_videos', 'tracked_accounts', 'active_creators', 'creator_invites_daily', 'active_jobs', 'team_seats', 'extra_credits'. Answers 'how much of my plan am I using?', 'how many creators can I still invite today?' and 'how many credits are left?' for any member.
get_video
ChatGPTGet analytics detail for a single tracked video by platform (tiktok | instagram | youtube | facebook | snapchat) and the platform's native video ID.
get_video_history
ChatGPTGet the time-series metrics history (views/likes/comments/shares over time) for a single tracked video. Pass the metrics to return and, optionally, a day/week/month aggregation. Use for trend questions about one video.
get_views_by_country
ChatGPTGet the organization's view gains for a date range grouped by country tag, with each country's top accounts and videos, plus filtered totals. Use to answer 'which markets drove views' or 'which accounts lead a market'.
get_viral_video_insights
ChatGPTDeep research breakdown of ONE viral-library video, beyond what search_viral_video_library already returns per result: the full hook analysis (visual, text overlay, audio, timestamp, psychological trigger, retention pattern, share/save drivers), the commercial read (product/brand shown and when, CTA mechanic, sponsored or organic), creator persona, and a scene-by-scene timeline where available. Use the
id from a search result as videoId; call it for a handful of standout videos, not for every result.invite_creator
ChatGPTSends the platform invitation EMAIL to an existing creator (id from list_creators/create_creator). Set resend: true to re-send a pending invitation. This emails a real person — confirm the recipient with the user first. Sends a REAL email to the creator. Before calling, state the exact recipient address in your message so the approval is informed. Use revoke_creator_invitation to undo a pending invitation.
list_account_tag_rules
ChatGPTLists active account-level tag assignments managed from Accounts.
list_account_video_tags_bulk
ChatGPTRetrieves the distinct video-level tags (tags on at least one of the account's videos that are not account-level tag rules) for up to 100 accounts in one call, keyed by account id. Accounts without such tags map to an empty array.
list_accounts
ChatGPTList tracked social accounts with aggregated analytics metrics. Supports filtering, sorting, and pagination. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.list_applications
ChatGPTRetrieves creator applications to the current organization's job postings, including the applicant, the job, the organization's shared bookmark flag, and unread chat messages. Applicant email addresses are only returned for accepted applications.
list_briefs
ChatGPTRetrieves briefs with a plain-text excerpt (its variables marked as runs), their audience (everyone, or non-ended linked campaigns plus creators sent it directly), read progress at the current version, and sample video counts.
list_campaigns
ChatGPTList creator campaigns (Creator Hub), including status and configuration. Use with list_creators to answer campaign staffing questions.
list_chat_threads
ChatGPTLists brand-creator chat conversations with latest-message previews and unread counts. Organization staff must use scope "org"; scope "creator" is the creator-side inbox. Rows with kind "direct" are 1:1 threads with one creator; rows with kind "group" are brand-created group chats (title = the brand-internal name, publicTitle = the name creators see, groupKind manual/campaign/all, memberCount; creator fields are null). Use filter "groups" to list only groups. Returns up to 200 conversations by recent activity; to read a larger inbox pass limit, then each nextPageToken as pageToken.
list_creators
ChatGPTList creators managed in the Creator Hub, including linked user info and account assignments.
list_due_payouts
ChatGPTLists finished campaign billing periods that have NOT been paid out yet — what the organization currently owes creators. Read-only: it never initiates payments.
payoutAmount is in MINOR currency units with payoutPrecision decimals (e.g. amount 10000 with precision 2 = 100.00), and so are partialsPaid.amount (what partial payments already paid toward the window), partialsPaid.coveredAmount (the earnings they covered — differs from amount only when a partial carried an adjustment) and partialsPaid.calculatedAmount (the window's total before them) — payoutAmount is what is LEFT to pay. ALWAYS divide by 10^payoutPrecision before showing amounts to the user.list_event_subscriptions
ChatGPTLists the MCP event subscriptions (automations) of this organization that you may manage: your own, or every one for owners and admins. Each has the event, its filter arguments, how it is delivered (webhook or poll), the MCP client that created it, when it expires and whether delivery is healthy (active, failing, disabled, expired).
list_jobs
ChatGPTRetrieves discovery job postings including product, requirements, and payment configuration for the current organization.
list_paid_payouts
ChatGPTLists completed payout records (amounts in major currency units) for finished billing windows — the organization's payout history.
list_projects
ChatGPTList the organization's projects (named groupings of tracked accounts used to segment analytics).
list_tag_workflow_runs
ChatGPTLists latest preview/backfill runs for an workflow.
list_tag_workflows
ChatGPTLists all tag workflows for the active organization.
list_tags
ChatGPTRetrieves paginated tags scoped to the active organization.
list_tracked_accounts
ChatGPTList the social accounts the organization currently tracks (tracking configuration view: platform, username, max videos, competitor flag). For performance numbers use list_accounts instead. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.list_tracked_videos
ChatGPTList individually tracked videos (tracking configuration view). For analytics metrics use list_videos instead.
list_upcoming_payouts
ChatGPTLists in-progress campaign billing periods (started, not yet finished) per creator assignment — the payouts that will become due next.
payoutAmount is in MINOR currency units with payoutPrecision decimals (e.g. amount 10000 with precision 2 = 100.00), and so are partialsPaid.amount (what partial payments already paid toward the window), partialsPaid.coveredAmount (the earnings they covered — differs from amount only when a partial carried an adjustment) and partialsPaid.calculatedAmount (the window's total before them) — payoutAmount is what is LEFT to pay. ALWAYS divide by 10^payoutPrecision before showing amounts to the user.list_video_tags
ChatGPTRetrieves tags assigned to a single video.
list_video_tags_bulk
ChatGPTRetrieves tags for up to 100 videos in one call, keyed by
platform:platformVideoId. Videos without tags map to an empty array.list_videos
ChatGPTList tracked videos with their analytics metrics (views, likes, comments, shares, engagement). Supports filtering, sorting, and pagination. Platforms: tiktok, instagram, youtube. The
tags filter accepts tag IDS only (orgtag_/orgproj_/systag_ from list_tags or resolve_tags). Plain tag NAMES are NOT resolved — unrecognized values are silently ignored and the result comes back UNFILTERED, so never pass names, and never present results as tag-filtered unless you passed real ids.live_get_account
ChatGPTFetch a fresh public account profile directly from the platform by username (any account, not just tracked ones). ⚠️ Spends 3 credits per call. Prefer list_accounts for tracked accounts. Call without confirm for a quote; re-call with confirm: true to execute.
live_get_account_videos
ChatGPTFetch an account's recent videos directly from the platform. Requires the platform-native account id (get it via live_get_account) — except Snapchat, which has no id-based lookup: pass the account handle as the id. ⚠️ Spends 3 credits per page. Quote-then-confirm.
live_get_video
ChatGPTFetch a single video's fresh metrics directly from the platform by platform-native video id. ⚠️ Spends 3 credits per call. Prefer get_video for tracked videos. Quote-then-confirm.
live_get_video_comments
ChatGPTFetch the comments on a TikTok, Instagram, YouTube, Facebook or Snapchat video straight from the platform: comment text, like/reply counts, commenter, and timestamp. A page holds 10 to 30 comments in the platform's own order; Snapchat returns only its top comments, as a single page. ⚠️ Spends 3 credits per page. Pass the returned nextPageToken as pageToken for more. Quote-then-confirm. For 'what are people saying' questions, 1-2 pages is normally enough — summarize themes, top-liked comments, questions people ask, and content ideas. Only fetch further pages (each is charged like the first) when the user explicitly asks for more depth. Works for ANY public TikTok, Instagram, YouTube, Facebook or Snapchat video, not just tracked ones; pass the same video id live_get_video takes. Snapchat has one page only. YouTube comment times are approximate.
live_search_hashtags
ChatGPTSearch hashtags directly on TikTok, Instagram or Snapchat by keyword, with how often each is used. On YouTube it looks up the one hashtag the query names. Not available for Facebook. ⚠️ Spends 3 credits per page. Quote-then-confirm.
live_search_users
ChatGPTSearch accounts/creators directly on TikTok, Instagram, YouTube, Facebook or Snapchat by keyword. On Facebook and Snapchat a one-word query is also looked up as an exact handle, and that account comes first. Follower counts come with TikTok, YouTube (rounded) and Snapchat public profiles, not with Instagram or Facebook search results; Instagram and Snapchat return one page. ⚠️ Spends 3 credits per page. Quote-then-confirm.
live_search_videos
ChatGPTSearch videos directly on TikTok, Instagram, YouTube (Shorts), Facebook or Snapchat (fresh upstream results, e.g. for trend or competitor research). TikTok and Instagram results have views, likes, comments, shares and saves; Snapchat all of those but saves; YouTube and Facebook a view count only. Snapchat returns one page. ⚠️ Spends 3 credits per page. Quote-then-confirm.
open_application_chat
ChatGPTReturns the chat conversation with an applicant (chatId for get_chat_messages / send_chat_message), creating it if the organization has not written to them yet.
open_chat_cards
ChatGPTLists the cards the show tool presented in this conversation, newest first. It is ChatGPT's conversation panel for viral.app; a model never needs to call it.
open_viral_app_home
ChatGPTOpens the viral.app home view: KPIs, top videos, top accounts and top creators for the last 7, 30 or 90 days, campaigns, what waits for the team (applications, chats, payouts due), and automations. It is ChatGPT's sidebar app for viral.app and loads its own data; a model never needs to call it.
preview_account_max_videos
ChatGPTDry-runs update_account_max_videos_bulk (same input: accountIds or scope, newMaxVideos) without writing anything. Returns ok, every refusal the write would hit (plan feature missing, tracked-accounts or tracked-videos limit reached), how many accounts match, change, resume or pause, the accounts clamped to their platform's options, and how many units the write adds to the tracked-videos and tracked-accounts plan meters. Use it to state the plan impact from facts before the write; also for a single account.
preview_campaign
ChatGPTDry-runs a campaign spec without writing anything: validates it exactly as create_campaign or update_campaign would and returns the normalized spec, one sentence per rule-set (summary), the sheet's alerts (warnings), the issues with their spec paths, and a previewHash for the write. spec alone = a new campaign; id + spec = an edit, merged into the current configuration, with the sentences that would change (changes); fromJobId = a draft derived from a job listing (missing lists what to ask for); fromCampaignId = a copy. Run it BEFORE every create_campaign / update_campaign and show the user the sentences (summary) and alerts (warnings) it returns, then pass the returned previewHash to the write. ok: false comes with issues at exact spec paths: fix those and preview again, never write around one. With id, changes lists every sentence the edit would alter — show them. fromJobId returns draft + missing when the listing cannot fill everything (schedule.anchor always): ask the user for the missing paths in one round, then preview again with the answers as spec overrides. Amounts are MAJOR units of the campaign currency (perVideo: 10 = 10.00; rate: 1.2 = 1.20 per 1,000 views). Tiers are half-open [from, to): each tier's from equals the previous tier's to, only the last tier leaves to out, aggregated bonus tiers never carry one. schedule.anchor is REQUIRED and never guessed — ask (rolling: each creator's cycle starts the day they join, creators are added and paid on their own dates; fixed: everyone shares the same calendar cycle, creators added mid-cycle snap to a slot, payouts go out in one batch per cycle). Never invent an amount, target or date: ask for what is missing. When a number the user gives falls outside these live ranges (per payout cycle), say so once and confirm before writing — base payout per video 5–35 USD (median 14) or 5–20 EUR (median 10); CPM rate 0.5–3 USD per 1,000 views (median 1) or 0.1–2 EUR (median 1); fixed salary 150–6,000 USD a month (median 500; too rare in other currencies to range); flat bonus 10–1,000 USD per tier (roughly 10 at 10k views, 50 at 50k, 100 at 100k, 200 at 500k, 500 at 1M); video target 4–90 per month (median 30) or 3–28 per week (median 5). Other currencies take the USD ranges as a rough guide. Entries of one family (basePayouts, cpmPayouts, flatBonuses) may share platforms and then STACK — a video on a shared platform earns each of them; the dry-run warns (base_payouts_overlap, cpm_payouts_overlap, flat_bonuses_overlap). Set that up only when the user asked for exactly that; otherwise give each entry its own platforms.
preview_creator_custom_rates
ChatGPTDry-runs custom rates for creators on a campaign without writing: one creator's own values (perVideo, videoCap, amountCap, rate or amount on a payout id from get_campaign's spec, plus videoTarget). Returns per creator every value that changes, warnings, and for a single creator the unpaid periods before and after, plus the previewHash set_creator_custom_rates and assign_creators_to_campaign need. mode replace = the creator's whole set; merge = merged into their existing values (assigning). Use it when the user wants one creator (or a few) paid differently on a campaign: values only — per video, CPM rate, bonus amount, fixed salary, caps, video target. Take payout ids from get_campaign's spec; never invent one. Show the user every change it returns (before → after) and its warnings before the write. When the creator needs other payouts or conditions, not other numbers, suggest a separate campaign instead.
preview_tag_workflow
ChatGPTEvaluates rule conditions and returns impact counts without persisting changes.
reactivate_campaign
ChatGPTClears the end date of a campaign that ended or is scheduled to end, so it runs on without an end. Clears the end date, so the campaign runs on without one. Name the campaign and its current end date in your message before the approval.
read_content
ChatGPTRead one knowledge-base page in full (plain text) by the
slug a search_content result returned. Use after search_content when the snippet is not enough to answer.refresh_tracked_accounts
ChatGPTTrigger an immediate re-sync of tracked accounts instead of waiting for the schedule. Call without confirm to get a credit quote first; re-call with confirm: true to execute. Accounts a refresh was already requested for in the last 10 minutes (by anyone in the organization) come back under skipped: they are already refreshing and were not charged again — report them as such. Track progress via get_tracking_status using the returned eventIds. Refresh is asynchronous and spends credits. It does NOT complete within this conversation; never call it repeatedly to force a sync to finish. Accounts listed under skipped were already refreshing (requested in the last 10 minutes) and were not charged again: tell the user so.
refresh_tracked_videos
ChatGPTTrigger an immediate re-sync of individually tracked videos (not videos that belong to tracked accounts). ⚠️ Spends 3 credits per video. Call without confirm for a quote; re-call with confirm: true to execute. Videos a refresh was already requested for in the last 10 minutes (by anyone in the organization) come back under skipped: they are already refreshing and were not charged again — report them as such. Refresh is asynchronous and spends credits. It does NOT complete within this conversation; never call it repeatedly to force a sync to finish. Videos listed under skipped were already refreshing (requested in the last 10 minutes) and were not charged again: tell the user so.
remove_tracked_account_tag_from_all_videos
ChatGPTRemoves a video-level tag from every video of the account: manual assignments are deleted and automated ones are suppressed so rules do not re-add them.
remove_video_tags
ChatGPTRemoves tags from a single video. Each item in
tags is exactly { scope, tagId } — e.g. { scope: 'org', tagId: 'orgtag_…' }. Use the id field from create_tag / list_tags / resolve_tags results as tagId (scope 'org' for orgtag_ ids, 'project' for orgproj_ ids, 'system' for systag_ ids). Never pass tag names or whole tag objects.reply_to_application
ChatGPTSends a message to the applicant and optionally transitions the application status (open, in_review, accepted, rejected); omit status to reply without deciding. Accepting also onboards the applicant as a creator of the organization, and is refused when the applicant has no date of birth on file. Pass a fresh random clientMessageId (8-64 chars) so retries cannot deliver the reply twice.
resolve_facebook_share_urls
ChatGPTResolve shortened facebook.com/share/... links to trackable Facebook accounts. Returns, per link, the exact
username value to pass to add_tracked_accounts with platform 'facebook' (full profile URLs are normalized without fetching; failed links come back with the reason). Up to 25 links per call — when a sheet contains Facebook share links, resolve them with this BEFORE adding, then include the resolved usernames in your normal add batches. Plain-text names ("Anna's Daily") are NOT resolvable — report those back to the user as manual fixes.resolve_tags
ChatGPTResolves tag metadata for a list of tag IDs.
resolve_tiktok_short_url
ChatGPTResolves a TikTok short/share link (vm.tiktok.com/…) to its canonical video URL so the platform videoId can be extracted for add_tracked_videos or analyze_video. Free helper; only needed when the numeric video id is not visible in the URL.
revoke_creator_invitation
ChatGPTCancels a pending creator invitation so it can no longer be accepted — the undo for invite_creator.
search_chat_messages
ChatGPTSearches messages of a conversation by text, newest first. Deleted messages never match.
search_content
ChatGPTSemantic search over the viral.app knowledge base: product docs, feature guides, platform know-how (virality thresholds, account warmup, posting strategy), and free-tool explainers. Returns page slugs for read_content plus site-relative paths for linking. Only pass
category when you are certain it helps; unfiltered search covers the whole knowledge base.search_viral_video_library
ChatGPTSearches viral.app's curated research library of proven performance-UGC videos (TikToks and Instagram Reels, mostly app/SaaS marketing: creators demoing or reviewing an app; NOT the organization's own tracked content). Use it for 'what is working in niche X', 'find UGC videos/formats/hooks like …', reference and inspiration questions. Every result carries the research taxonomy (vertical, formatPrimary, hookArchetype, hookTextOverlay) plus a whyItWorked verdict and a replicationTip, so one search answers most format/hook questions — group results by formatPrimary/hookArchetype yourself. The formats talking_head and screen_recording filter on how a video is presented, not on formatPrimary: their results still carry a structural formatPrimary (product_demo_review, tutorial_how_to), so never conclude from formatPrimary that a talking-head result is not one. Put the niche and the user's actual question into
search: it is a plain-language hybrid search over what happens in each video (transcript, on-screen text, scene beats, summary, hook, brand and creator names), so 'creator reacts to a notification from a study app', 'meal planning app' or 'before and after screen recording with voiceover' work as written; under the default sort results come back by relevance. Exact handles and brand names match too. It returns close matches only: a topic the library does not cover comes back empty (or with a few videos), never padded with unrelated ones — an empty data means the library has nothing on it. Narrow with the enum filters (formats, hookArchetypes, productTypes, regions; languages for the language spoken or written in the video as ISO 639-1 codes — 'es' for Spanish-language UGC regardless of the account's region; platform for TikTok-only or Instagram-only). verticals are coarse and several are rarely assigned (fashion and food videos sit under health_fitness), so name the niche in search rather than relying on a vertical; when the chosen verticals hold no videos at all the filter is dropped and note says so. dateRange defaults to the whole library ('all'); only narrow it when recency is the question. sort: 'outlier' ranks videos that beat their account's follower count (best for 'what formats punch above their weight'), 'views' for reach, 'recent' (default) for what the library added most recently, 'latest' for the platform post date. Start with limit 12-24; call get_viral_video_insights on single videos only when a deeper breakdown (scenes, CTA mechanic, persona) is needed. Facet values are snake_case ids (curiosity_gap, product_demo_review) — say them in plain words to the user. languages omitted searches every language. The library page shows English by default, so pass ["en"] for that view, or the language(s) the user names or their market implies ('Spanish-language hooks', 'for the German market' → ["de"]); never ask which language.send_chat_message
ChatGPTSends a message in a conversation (chatId from list_chat_threads, open_application_chat, or start_creator_chat), including group chats. Generate a fresh random clientMessageId (8-64 chars) per message — reusing one returns the originally sent message instead of sending again. In a group chat the organization may write @[channel](channel) to notify every member; creators are otherwise only notified when @mentioned.
set_account_competitor
ChatGPTMarks or unmarks one tracked account as a competitor, separating it from the organization's own content in analytics.
set_brief_audience
ChatGPTSets who reads a brief: allCreators=true for everyone at the organization (alone, with campaignIds: [] and creatorIds: [] to clear existing links), or campaignIds (a campaign holds one brief, linking moves it here) plus creatorIds (creators from list_creators who read it directly). Omitted parts stay. Every creator it newly reaches must read it on their next visit. notify=true also notifies them (in the app and by email): only when the user asked for it. Confirm the audience with the user before calling.
set_brief_campaigns
ChatGPTReconciles the brief's non-ended campaign links to the given set: removed links are deleted, added links steal any existing brief on the target campaign (a campaign holds one brief). With notify=true, creators on newly linked campaigns are notified. PUT /briefs/{id}/audience sets campaigns, creators and everyone in one call.
set_creator_custom_rates
ChatGPTSets one creator's custom rates on a campaign: the values given replace theirs (an empty list and no videoTarget reset them to the campaign's). Values only: the campaign's payouts stay, a creator who needs other payouts needs their own campaign. Applies to every unpaid period of that creator at once. Preview first with preview_creator_custom_rates and pass its previewHash. Only after preview_creator_custom_rates (mode replace) returned ok and the user saw its changes; send exactly the values it previewed plus its previewHash — refused without one (PREVIEW_REQUIRED) and on a mismatch. The values replace all of the creator's custom rates on that campaign: start from their current ones (get_campaign's customRates names who has any). Say that the new values apply to every unpaid period at once.
set_job_status
ChatGPTTransitions a job posting through its lifecycle: draft to public (launch), public to paused (pause), paused to public (resume).
set_tracked_account_tags
ChatGPTUpdates account-level tag rules and bulk applies them to existing videos. Tags an ACCOUNT (applies to the account and its videos via a rule) — NOT a single video. To tag one specific video, use add_video_tags instead.
show
ChatGPTPresent data you already fetched as a rich viral.app card. In clients that render MCP Apps (ChatGPT, Claude) the user sees a visual card; every client also gets the card as markdown text. Call it only AFTER a data tool returned what you want to show: get_top_videos, list_videos or search_viral_video_library (card: videos or video); get_account or list_accounts (account); list_creators, get_creator or get_top_creators (creators or creator); get_campaign, get_job or get_brief (campaign, job, brief: pass the id only, the card loads the rest); get_analytics_kpis or get_campaign_kpis (kpis: one tile per metric, with previousValue from the result's
previous block); any time series or breakdown (chart-area, chart-bar, chart-pie). It fetches nothing, changes nothing and costs no credits. Pick card, then fill ONLY the field named for it with values copied from the tool results; never invent or round numbers. One card per call: to show several, call it again. Once a card is shown, do not repeat its numbers in prose; add the insight instead.start_creator_chat
ChatGPTGets or creates the single DIRECT conversation between the active organization and a managed creator (pass creatorUserId or orgCreatorId from list_creators). Idempotent: returns the existing conversation when one already exists. Refused for a creator who has not been invited to the platform yet (invite them first). Group chats are separate conversations (kind "group" in list_chat_threads) and are created by the organization in the chat UI.
suggest_tags
ChatGPTReturns frequently used tags plus system defaults for quick assignment.
update_account_max_videos
ChatGPTChanges how many videos are auto-tracked for one tracked account (its maxVideos limit). Raising it consumes more of the tracked-videos plan meter; campaigns can require a minimum (e.g. requiredMaxVideos warnings from list_campaigns). Tell the user the billing impact before calling.
update_brief
ChatGPTUpdates what is sent and leaves the rest: name, content as markdown (contentMarkdown), the complete sample list (sampleVideos REPLACES the list, so read get_brief first and include the samples to keep), and the audience (campaignIds, creatorIds, allCreators — prefer set_brief_audience for audience-only changes). notify=true bumps the version and re-notifies every creator in the audience (sent alone, it re-publishes the current brief); notify=false saves silently. Show the user the changed text before calling.
update_brief_creators
ChatGPTSends a brief to creators directly (add: creator ids from list_creators) or takes it away (remove, silent). Every creator it newly reaches must read it on their next visit. notify=true also notifies them (in the app and by email): only when the user asked for it.
update_campaign
ChatGPTChanges a campaign from a partial spec: name, description, videoTarget, briefId and each schedule key replace only what is sent; payouts replaces the whole block. Rule changes apply to every unpaid payout at once; currency and the schedule lock once creators are assigned or payouts exist. Returns the campaign with its sentences. Send ONLY what changes: top-level fields and schedule keys are partial; payouts replaces the whole block, so start from get_campaign's spec.payouts and send the complete edited block. Rule changes hit every unpaid payout at once — say so before the approval. Preview with preview_campaign (id + the changes) first and pass its previewHash — the call is refused without one (PREVIEW_REQUIRED); only a briefId-only change (attaching or swapping a brief) needs no preview. lockedFields from get_campaign cannot change (CAMPAIGN_FIELD_LOCKED): offer a copy (preview_campaign with fromCampaignId) instead.
update_creator_accounts
ChatGPTREPLACES a creator's full list of linked tracked accounts with the given accountIds (orgacc_… ids, not handles). Omitting an existing id unlinks it — include everything that should remain. force: true reassigns accounts already linked to another creator. REPLACES the whole list — first call get_creator to fetch currently linked accountIds and include the ones to keep. New handles must be tracked first (add_tracked_accounts, then list_tracked_accounts for their orgacc_ ids). Use force: true only after the user explicitly confirms stealing an account from another creator.
update_job
ChatGPTReplaces a job posting with the fields sent: a FULL update, so read the job with get_job first and send every field back with your changes (a field left out is cleared), writing the body and challenge as markdown (bodyMarkdown, challengeBriefMarkdown). Leave out sampleVideos and exampleVideos to keep the saved lists; sent, each replaces its list. Edits to a public job are live at once and re-rank its Discovery matches, so show the user the change before calling.
update_tag
ChatGPTUpdates an organization tag.
update_tag_workflow
ChatGPTUpdates an existing workflow.
Capabilities
WritesInteractive
Example Prompts
Click any prompt to copy it.
Links
App Stats
124
Tools
3
Prompts
ChatGPT
Platforms
Category
Brand MonitoringWorks with
ChatGPT
Data refreshed daily






