# SOLARI > SOLARI CLI and MCP — creator and brand intelligence from your terminal. ## Overview SOLARI CLI puts SOLARI's creator and content data in your terminal. Look up any brand or creator on Instagram or TikTok, measure their sponsored-content footprint, search what people actually say in captions and video transcripts, and read what is trending right now — as plain commands that compose with jq, shell scripts, and AI coding agents. SOLARI is also available as an MCP server, so apps like Claude Desktop and ChatGPT can reach it without the CLI. Either way you get the same 26 tools and the same read-only access. ```console $ solari instagram account search query=oliveyoung brands_only=true $ solari tiktok content search query=sunscreen region=KR $ solari instagram content trending region=KR limit=10 --json ``` ## Install The CLI is one file, with nothing else to install alongside it. Pick whichever method matches how you usually install tools — they all give you the same thing. **macOS** Shell: ```bash curl -fsSL https://solari.sh/install | sh ``` Homebrew: ```bash brew install brandazine/solari/solari ``` npm: ```bash npm install -g @brandazine/solari ``` uv: ```bash uv tool install solari-cli ``` uv tool puts the CLI in its own environment and on your PATH, so it never collides with a project's dependencies. **Windows** PowerShell: ```powershell irm https://solari.sh/install.ps1 | iex ``` npm: ```bash npm install -g @brandazine/solari ``` uv: ```bash uv tool install solari-cli ``` uv tool puts the CLI in its own environment and on your PATH, so it never collides with a project's dependencies. **Linux** Shell: ```bash curl -fsSL https://solari.sh/install | sh ``` npm: ```bash npm install -g @brandazine/solari ``` uv: ```bash uv tool install solari-cli ``` uv tool puts the CLI in its own environment and on your PATH, so it never collides with a project's dependencies. Then confirm the install: ```console $ solari --version 1.0.0-alpha.9 ``` ## Quickstart Sign in once, then look through the tools and run one. Looking around is answered from a copy kept on your own machine, so it comes back instantly. ```console $ solari auth login # opens a browser; sign in with your SOLARI account $ solari # platforms and groups available to you $ solari instagram account # a group path lists its tools $ solari instagram account search --help # parameters, without calling $ solari instagram account search query=oliveyoung brands_only=true limit=3 ``` Most work starts by turning a name into an account_id, then passing that id to the other tools: ```console $ solari instagram account search query=innisfree brands_only=true --json \ | jq -r '.content[0].text | fromjson | .items[0].account_id' 018cabce-14cc-7544-8890-7811ec33ef74 $ solari instagram brand ad stats username=innisfreeofficial $ solari instagram brand top collaborators username=innisfreeofficial limit=20 ``` A name is not the only way in. query_type=bio searches what accounts write about themselves, so you can start from a category rather than from a brand you already know: ```console $ solari instagram account search query="협찬 문의" query_type=bio region=KR limit=10 $ solari instagram account search query=skincare query_type=bio brands_only=true limit=20 ``` ## The command model The path is the command. Stop partway and you get a list of what sits under it; type a full tool path and it runs; leave out something the tool needs and it shows you what it takes instead of running. Spaces and underscores work the same, and you can drop the solari_ prefix. ```console $ solari instagram brand # lists the group $ solari brand overview --help # unambiguous trailing paths resolve while browsing $ solari instagram brand overview username=innisfreeofficial # calls ``` Arguments are key=value pairs. Arrays accept JSON or a comma-separated list. ```bash solari instagram content batch post_ids='["019f505f-…","019f5060-…"]' solari instagram content batch post_ids=019f505f-…,019f5060-… ``` - `solari help all` — Every command, tool, and parameter on one page. Answered from your own machine; add --json for a machine-readable version. Handy for handing an AI agent everything at once. - `solari get ` — Runs a tool and nothing else — it refuses a half-finished path. Use it in scripts, where a typo should fail rather than quietly print a list. - `solari cache refresh` — Update the tool list on your machine right away, instead of waiting for it to refresh on its own. ## Authentication Signing in opens your browser, the same way signing in to any website does. - `solari auth login` — Opens your browser. Where it cannot — over SSH, or when an agent is running the command — it prints the sign-in link instead. - `solari auth list` — List the SOLARI accounts you are signed in to. - `solari auth switch ` — Switch to another account you are already signed in to, without opening a browser. - `solari auth status` — Show which server and account you are on, what you can reach, and when the sign-in runs out. Exit code 3 means someone has to sign in again. - `solari auth logout` — Sign out. Add --all to sign out of every account at once. If the browser cannot hand you back to the machine you ran the command on — over SSH, or inside a container — finish signing in, then copy the address out of the browser's address bar and paste it into the prompt that is waiting for it. ### What you can reach Access is read-only and it covers every tool. Once you have signed in you can call all 26 — there are no tiers and nothing to unlock one tool at a time. Instead of plan limits, there is a cap on how often a single account can call. ## Output and piping Results go to standard output; prompts and hints go to standard error, so a pipe only ever carries data. Colour is added only when you are looking at a terminal — never into a pipe, and never into JSON. - `--json` — Raw JSON. A tool's answer arrives wrapped one layer deep — the data itself is the JSON string at content[0].text. - `--ndjson` — One JSON object per line: the items of a response, one at a time. What surrounds them (total, has_more, and so on) goes to standard error. Made for jq and for writing large pulls straight into a file. - `--refresh` — Skip the copy on your machine and get the tool list fresh from the server. - `--color[=always|never|auto]` — Colour the help and the tool listings. auto (the default) adds colour only when you are looking at a terminal; NO_COLOR=1 turns it off, FORCE_COLOR=1 turns it on even in a pipe. --no-color is the same as never. - `--verbose, -v` — Print a running log to standard error while the command works. Secrets are hidden. ```console $ solari instagram brand ad posts username=innisfreeofficial months=24 limit=200 --ndjson >> ads.ndjson $ jq -s 'group_by(.username) | map({creator: .[0].username, posts: length})' ads.ndjson ``` ## Configuration Settings live in ~/.solari/config.json. Every setting also has an environment variable, which takes over for that one command. solari config list shows the value in effect and where it came from. ```console $ solari config list $ solari config set server https://solari.sh $ solari config unset server ``` - `server · SOLARI_SERVER` — Which SOLARI server to talk to. Defaults to https://solari.sh, and a successful sign-in remembers the server it used. - `cacheTtl · SOLARI_CACHE_TTL` — How long, in seconds, the tool list on your machine counts as current. Default 900; 0 always asks the server. - `cacheShadow · SOLARI_CACHE_SHADOW` — After answering from your machine, quietly update the tool list in the background. Default true. - `callTimeout · SOLARI_CALL_TIMEOUT` — Seconds to wait for a tool call. Default 150. - `catalogTimeout · SOLARI_CATALOG_TIMEOUT` — Seconds to wait for the tool list. Default 8, so an unreachable server fails quickly instead of hanging. - `SOLARI_HOME` — Keep SOLARI's files somewhere other than ~/.solari. - `SOLARI_NO_UPDATE_CHECK=1` — Turn the daily update check off entirely. NO_UPDATE_NOTIFIER=1 does the same. The tool list is answered from your machine first, so browsing and checking parameters are instant; once the copy is older than the timeout above, it is refreshed in the background. A path the copy does not know is looked up on the spot, so a tool added on the server works right away. ## Agents If you already work with an agent that runs commands, hand it this one line and stop reading. It fetches a short setup page written for agents rather than people, then does the rest itself — connects or installs, walks you through sign-in, and registers SOLARI with the tools on your machine. ```text set up solari.sh/get-started.md ``` The rest of this section is what that page does, in case you would rather do it by hand. solari init tells the AI agents on your machine that the CLI exists, so they reach for it on their own when a question is about Instagram or TikTok data. It sets up a skill for Claude Code, a section it manages in Codex's AGENTS.md, and tab completion in zsh. solari init --remove undoes all of it. ```bash solari init # claude + codex + zsh, with a confirmation for each solari init claude # just one target solari init --remove ``` Use the CLI in a terminal, in scripts, and with agents that run commands. Use MCP for apps that connect to servers themselves, like Claude Desktop and ChatGPT. ### Machine-readable docs Every page on this site has a Markdown twin at the same address with .md on the end, and the whole reference is available as one file to hand to a model. - `/get-started.md` — The setup page the line at the top of this section points to. Written for an agent to act on. - `/llms.txt` — An index of the documentation, in the llms.txt format. - `/llms-full.txt` — The entire documentation — guide and all 26 tools — concatenated into one Markdown file. - `/docs/tools.md` — Any page, as Markdown. Add ?lang=ko or ?lang=ja for the other languages. ## Connect over MCP SOLARI also runs as a remote MCP server. A host with MCP support connects to it directly and gets the same read-only tools as the CLI, with nothing to install. One address is all it needs: ```text https://solari.sh/mcp ``` The first connection opens a browser to sign in with your SOLARI account. The host then asks which tools it may call, and nothing runs until you approve. Access is read-only from every host. ### Claude Desktop Open Settings and choose Customize at the bottom of the sidebar. ![The Claude Desktop settings sidebar, with Customize at the bottom.](https://solari.sh/docs/claude-desktop-settings.webp) _Settings → Customize_ Go to Connectors, press Add, and fill in the dialog: a name for the connectors list, and the address above. ![The Add custom connector dialog in Claude Desktop, with a name and the SOLARI MCP address filled in.](https://solari.sh/docs/claude-desktop-add-connector.webp) _Connectors → Add → Add custom connector_ Continue walks you through sign-in once. After that SOLARI sits in your connectors list and its tools are available in any chat. claude.ai works the same way. ### Claude Code One command registers the server. ```bash claude mcp add --transport http solari https://solari.sh/mcp ``` Claude Code asks you to sign in the first time it reaches the server. /mcp shows the connection and lets you start that yourself. ### ChatGPT ChatGPT connects the same way as Claude Desktop: add the address as a custom connector under Settings → Connectors, then sign in. Custom connectors are a paid-plan feature in ChatGPT. ### Other hosts Other apps that support remote MCP servers can connect too. Most of them take an entry like this in their settings file: ```json { "mcpServers": { "solari": { "url": "https://solari.sh/mcp" } } } ``` > Some apps can only run MCP servers installed on your own machine. Those cannot reach SOLARI directly — use the CLI instead. ## Errors and exit codes Every error says what to do next, and the exit codes are stable enough to branch on in a script. - `0` — Success. - `1` — The tool or the server failed. - `2` — You typed something the CLI could not use — an unknown path, a missing argument, or a bad value. - `3` — You need to sign in. Only a person can finish the browser sign-in, so an agent should say so rather than keep trying. ### Common tool errors - `auth expired, reconnect the connector` — Your sign-in ran out. Run solari auth login again, or reconnect the connector in your app. - `SOLARI access denied (403)` — SOLARI refused the call. Every tool is open to any signed-in account, so this points at the account itself — sign in again, and tell us if it keeps happening. - `rate limited, retry shortly` — Too many calls in a short window. Wait a moment and try again. - `SOLARI upstream timed out` — The call took too long — 90 seconds for most tools, 120 for the aggregate and trend-cluster ones. Narrow the range or lower the limit and try again. ## Data coverage What SOLARI can answer depends on which tool you use. Two limits matter most: which regions are covered, and how far back the data goes. - Keyword search and grouped counts (content search and content aggregate, on both platforms) cover KR, JP, US, and TW, and hold roughly the last 6 months. Ask for an earlier date and it is moved up to the oldest one available; the response tells you which date was actually used. - Looking up an account, a brand, or a post uses the full history, and is not limited to those four regions or to six months. - KR has the deepest coverage of every region. - Result counts are exact up to 10,000 and stop climbing there. TikTok search stops paging at 9,800 — to go further, narrow the date range. ### Identifiers - account_id is a SOLARI account UUID, issued per platform. An Instagram account_id and a TikTok account_id are different values and never interchangeable, even for the same brand. - Every account slot accepts either an account_id UUID or a username, and account_id wins when both are set. - post_id is a SOLARI post UUID, also per platform. Its public counterpart is slug (the Instagram shortcode) or video_id (the numeric TikTok id). ## FAQ ### Can the CLI modify my SOLARI data? No. Every tool is read-only — there is nothing in the CLI or the MCP server that can write. ### Can I use it with agents like Claude? Yes. Run solari init to introduce the CLI to the agents on your machine, or connect to the MCP server directly. Both are read-only. ### Why did my search return nothing? Account search reads handles from the start of the name, and display names anywhere in them. What you type has to actually appear in one of the two, so a nickname or an abbreviation will not find it — try the spelling the account uses itself. For content search, check that the region is KR, JP, US, or TW and that the dates fall inside the last six months. ### Is there a fee? SOLARI CLI is free to use for now. We will announce pricing before anything changes. ## Tool reference Every tool the SOLARI CLI and MCP server expose, with parameters, response fields, and a recorded example call. Tool names are namespaced solari___; in the CLI the same path is written with spaces. ### solari instagram account search > Turn a brand or creator name — or a phrase from a profile bio — into an Instagram account_id. - **CLI**: `solari instagram account search` - **MCP tool**: `solari_instagram_account_search` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Resolves a brand/creator name or Instagram handle to candidate tracked accounts via fast deterministic index search — like a typeahead, all candidates are returned — and also searches profile bio text. query_type picks what the query is matched against: auto (default) matches handles by prefix and profile display names (Korean or English) by text match; username or full_name narrows to just one of those; bio runs a full-text search over profile bio text, which is how you discover accounts by what they say about themselves ("skincare", "협찬 문의", "コスメ") rather than by name. Ranked by match quality and follower count. Returns found plus items ordered best-first (items[0] is the top match), each with account_id (the SOLARI account UUID every other tool takes), username, full_name, biography, follower_count, region, is_verified, and profile_pic_url; found=false with empty items means nothing matched. In the name modes the query must actually appear in the handle or display name — phonetic aliases and abbreviations do not resolve, so retry with the native spelling (for example the English brand name). Set brands_only=true when resolving a brand name to filter out fan and meme accounts; pair it with query_type=bio to sweep a category of brands. Leave region unset unless the user asked for one country — it drops every account outside that region. Works with any signed-in SOLARI account. Use this first to resolve any entity mentioned by name. **When to use it** — Call this first whenever the user names an entity. Every other Instagram tool takes the account_id it returns. **What comes back** — Candidate accounts ordered best-first; items[0] is the top match. #### Parameters - `query` (string, required) — Brand or creator name (Korean/English) or Instagram handle to resolve, or — with query_type=bio — the words to look for in profile bios. - `query_type` (enum, optional, default "auto") — Which text to match. auto = handle and display name together; username = handle only; full_name = display name only; bio = profile bio text. Values: `auto`, `username`, `full_name`, `bio`. - `brands_only` (boolean, optional, default false) — Restrict matches to known brand accounts. Recommended when resolving a brand name. - `limit` (integer, optional, ≥ 1) — Maximum candidates to return, default 8. Values above 50 are clamped to 50. - `region` (string, optional, ≤ 8 chars) — Optional region code such as KR, JP, or US. Leave unset unless the user asked for one country: it filters results to that region and drops the rest. #### Response ##### `Response` - `found` (boolean) — true when at least one candidate matched. - `items` (object[]) — Candidates, ranked by match quality then follower count. ##### `items[]` - `account_id` (uuid) — SOLARI account id — the value every other Instagram tool accepts. - `username` (string) — Instagram handle. - `full_name` (string) — Profile display name. - `biography` (string) — Profile bio text. - `follower_count` (integer) — Follower count at snapshot time. - `region` (string) — Region code. - `is_verified` (boolean) — Instagram verification badge. - `profile_pic_url` (string) — Profile picture URL. #### Example ```console $ solari instagram account search query=oliveyoung brands_only=true limit=5 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "found": true, "items": [ { "account_id": "018cab6d-1648-7071-9734-c47a2be2fd19", "username": "oliveyoung_official", "full_name": "올리브영 OLIVE YOUNG", "biography": "ALL LIVE YOUNG 🫒\nALL LIVE BETTER @olivebetter.official", "follower_count": 1199628, "region": "KR", "is_verified": true, "profile_pic_url": "https://dcr.bzine.co/instagram/users/oliveyoung_official/profile-picture" }, { "account_id": "018dc63c-31b5-740f-bde0-2c00931385e1", "username": "oliveyoung_global", "full_name": "OLIVE YOUNG Global", "biography": "Korea's No.1 Health & Beauty Store\n✈️ FREE SHIPPING on orders over $60", "follower_count": 535949, "region": "KR", "is_verified": true, "profile_pic_url": "https://dcr.bzine.co/instagram/users/oliveyoung_global/profile-picture" }, { "account_id": "018cabcf-e60e-70af-95eb-eff777ce5195", "username": "oliveyoung_magazine", "full_name": "올리브영 매거진", "biography": "내 일상과 가까운 뷰티 매거진", "follower_count": 142316, "region": "KR", "is_verified": false, "profile_pic_url": "https://dcr.bzine.co/instagram/users/oliveyoung_magazine/profile-picture" }, "… 2 more" ] } ``` #### As an MCP call ```json { "name": "solari_instagram_account_search", "arguments": { "query": "oliveyoung", "brands_only": true, "limit": 5 } } ``` #### Notes - In the name modes the query has to actually appear in the handle or the display name. Phonetic aliases and abbreviations do not resolve — retry with the native spelling. - Set brands_only=true when resolving a brand name; it filters out fan and meme accounts. - query_type=bio searches profile bio text instead of names, so you can find accounts by what they say about themselves — "skincare", "협찬 문의", "コスメ". Korean, Japanese and Chinese bios match on substrings, so a query word does not have to be a separate word in the bio. - Bios are searchable for accounts SOLARI already tracks, and roughly one account in ten has no bio at all — treat bio search as discovery, not as an exhaustive census. - region filters results down to that region and drops every other account, so leave it unset unless the user asked for one country. #### Related tools - [`solari_instagram_account_profile`](https://solari.sh/docs/tools/instagram-account-profile.md) - [`solari_instagram_account_posts`](https://solari.sh/docs/tools/instagram-account-posts.md) - [`solari_tiktok_account_search`](https://solari.sh/docs/tools/tiktok-account-search.md) ### solari instagram account similar > Find Instagram accounts whose relationship graph overlaps a given handle. - **CLI**: `solari instagram account similar` - **MCP tool**: `solari_instagram_account_similar` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Finds Instagram accounts similar to the given username based on relationship-graph overlap. Takes an Instagram handle (no @), not a UUID. Works with any signed-in SOLARI account. **When to use it** — "Who else is like this creator?" — graph adjacency, not collaboration history. **What comes back** — The seed account, the similar accounts, and diagnostics describing the traversal. #### Parameters - `username` (string, required) — Instagram handle to find similar accounts for, without the leading @. - `limit` (integer, optional, ≥ 1) — Number of similar accounts to return, default 50. Values above 100 are clamped to 100. #### Response ##### `Response` - `user_id` (uuid) — Seed account id. - `user` (object) — Seed account profile summary. - `params` (object) — Traversal parameters actually applied (k, hops, max_rank_to_use). - `results` (object[]) — Similar accounts, score descending. - `diagnostics` (object) — Neighbours used, algorithm, and build time — useful when a result looks off. ##### `results[]` - `user_id` (uuid) — account_id of the similar account. - `username` (string) — Handle. - `full_name / bio` (string) — Display name and bio text. - `score` (number) — Graph-overlap score. Comparable only within this response. - `follower_count` (integer) — Follower count. - `region` (string) — Region code. - `has_collaborated` (boolean) — Whether this account has an ad collaboration with the seed. - `last_collaboration_date` (date | null) — Most recent collaboration date. - `recent_media` (object[]) — Recent post previews. #### Example ```console $ solari instagram account similar username=oliveyoung_official limit=8 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "user_id": "018cab6d-1648-7071-9734-c47a2be2fd19", "user": { "user_id": "018cab6d-1648-7071-9734-c47a2be2fd19", "username": "oliveyoung_official", "full_name": "올리브영 OLIVE YOUNG", "profile_pic_url": "https://dcr.bzine.co/instagram/users/oliveyoung_official/profile-picture", "follower_count": 1199628, "region": "KR", "is_verified": null }, "params": { "k": 8, "hops": 3, "max_rank_to_use": 25 }, "results": [ { "user_id": "018cabd4-926b-7a58-b0cb-11dfc7c37006", "username": "gs25_official", "score": 0.1515, "profile_pic_url": "https://dcr.bzine.co/instagram/users/gs25_official/profile-picture", "follower_count": 1017802, "median_views": null, "full_name": "대한민국 대표 편의점 GS25", "bio": "더 재미있게 더 실속있게\n오늘 가장 최신의 트렌드를 만나는\n#25매거진 #재미있는GS25 #라이프스타일플랫폼", "region": "KR", "has_collaborated": false, "last_collaboration_date": null, "recent_media": [ { "post_id": "01a062a3-a504-7fe5-b53f-7cd291ffceff", "media_type": "image", "source_url": "https://bzine.co/cdn-cgi/image/fit=scale-down,width=480/https://smr-images.bzine.co/users/018cabd4-926b-7a58-b0cb-11dfc7c37006/posts/01a062a3-a504-7fe5-b53f-7cd291ffceff/medias/01a062a3-a7f8-702c-994f-bd426afe5d74.jpg", "thumbnail_url": "https://bzine.co/cdn-cgi/image/fit=scale-down,width=480/https://smr-images.bzine.co/users/018cabd4-926b-7a58-b0cb-11dfc7c37006/posts/01a062a3-a504-7fe5-b53f-7cd291ffceff/medias/01a062a3-a7f8-702c-994f-bd426afe5d74.jpg", "slug": "Dcx-Nrij7IV", "media_url": "https://bzine.co/cdn-cgi/image/fit=scale-down,width=480/https://smr-images.bzine.co/users/018cabd4-926b-7a58-b0cb-11dfc7c37006/posts/01a062a3-a504-7fe5-b53f-7cd291ffceff/medias/01a062a3-a7f8-702c-994f-bd426afe5d74.jpg", "play_count": null, "posted_at": "2026-09-02T10:00:09+00:00" }, "… 3 more" ], "collaborated_with": [] }, "… 7 more" ], "diagnostics": { "neighbors_used": 4930, "unique_terms": 25, "build_ms": 7664, "algorithm": "distance_weighted_jaccard", "max_rank_used": 25, "target_related_count": 25 } } ``` #### As an MCP call ```json { "name": "solari_instagram_account_similar", "arguments": { "username": "oliveyoung_official", "limit": 8 } } ``` #### Notes - Takes a handle only — an account_id UUID is not accepted here. - For similarity by brand collaboration instead of graph overlap, use brand top collaborators. #### Related tools - [`solari_instagram_account_search`](https://solari.sh/docs/tools/instagram-account-search.md) - [`solari_instagram_brand_top_collaborators`](https://solari.sh/docs/tools/instagram-brand-top-collaborators.md) ### solari instagram brand overview > A brand's profile plus the id lists describing its ad footprint. - **CLI**: `solari instagram brand overview` - **MCP tool**: `solari_instagram_brand_overview` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Returns a brand's profile plus its ad-collaboration footprint: creator IDs who produced ad posts targeting the brand and the ad post IDs themselves (previewed to the first 20 with total counts; set full=true to receive the complete lists, up to 100 each). Feed the post IDs into solari_instagram_content_batch to hydrate them. Takes the brand's Instagram handle (no @), not a UUID. Works with any signed-in SOLARI account. Returns 404 if the handle is not tracked. **When to use it** — The starting point for brand analysis. Feed the post ids into content batch to hydrate them. **What comes back** — Brand profile, plus ids of the creators and posts that tagged the brand. #### Parameters - `username` (string, required) — Brand Instagram handle without the leading @. - `full` (boolean, optional, default false) — Return the complete ID lists instead of the first-20 preview. #### Response ##### `Response` - `information` (object) — Brand profile: user_id, username, full_name, bio, follower_count. - `all_influencers_id` (uuid[]) — account_ids of creators who produced ads for the brand. First 20 by default. - `all_influencers_count` (integer) — Total creators before truncation. - `all_influencers_truncated` (boolean) — true when the list is a preview. - `all_campaign_posts_id` (uuid[]) — Ad post ids. First 20 by default. - `all_campaign_posts_count` (integer) — Total posts before truncation. - `all_campaign_posts_truncated` (boolean) — true when the list is a preview. #### Example ```console $ solari instagram brand overview username=innisfreeofficial ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "information": { "user_id": "018cabce-14cc-7544-8890-7811ec33ef74", "username": "innisfreeofficial", "full_name": "INNISFREE | 이니스프리", "bio": "NATURE MEETS KOREAN SKIN SCIENCE", "follower_count": 847619, "brand_id": null }, "all_influencers_id": [ "01935f3d-8188-727e-a0bb-09e54aadfdac", "018caf6e-abfd-73da-88ad-11a56c39358b", "019a0061-b1d4-7adb-8ea4-1c5572dca38c", "… 17 more" ], "all_campaign_ids": [], "all_campaign_posts_id": [ "019f505f-f8be-7e88-ae08-6fba999950b1", "019f5060-3449-779e-a08b-d6d49add90cd", "019f4342-3357-7418-916c-da1c44468308", "… 17 more" ], "post_id_to_campaign_id": {}, "all_influencers_count": 93, "all_influencers_truncated": true, "all_campaign_posts_count": 100, "all_campaign_posts_truncated": true } ``` #### As an MCP call ```json { "name": "solari_instagram_brand_overview", "arguments": { "username": "innisfreeofficial" } } ``` #### Notes - full=true returns the complete lists, but they cap at 100 each. For accurate totals use brand ad stats instead of counting ids. - Takes a handle only — an account_id UUID is not accepted here. - An untracked handle returns 404. #### Related tools - [`solari_instagram_brand_ad_stats`](https://solari.sh/docs/tools/instagram-brand-ad-stats.md) - [`solari_instagram_content_batch`](https://solari.sh/docs/tools/instagram-content-batch.md) - [`solari_instagram_brand_ad_posts`](https://solari.sh/docs/tools/instagram-brand-ad-posts.md) ### solari instagram brand ad stats > Exact ad volume for a brand's recent window. - **CLI**: `solari instagram brand ad stats` - **MCP tool**: `solari_instagram_brand_ad_stats` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Exact sponsored-post and collaborating-creator counts for a brand's recent window, plus a bounded play-count sum. Use this for accurate ad-volume figures since solari_instagram_brand_overview ID lists are capped; for the underlying row-level posts use solari_instagram_brand_ad_posts. Takes the brand's Instagram handle (no @). Works with any signed-in SOLARI account. **When to use it** — Questions answered by a number — "how many ads did this brand run?". The brand overview id lists are capped and must not be counted. **What comes back** — Sponsored-post count, collaborating-creator count, and a bounded play-count sum. #### Parameters - `username` (string, required) — Brand Instagram handle without the leading @. #### Response ##### `Response` - `total_ad_posts` (integer) — Sponsored posts in the window. Exact. - `unique_creator_count` (integer) — Distinct collaborating creators. - `total_play_count` (integer) — Sum of plays. - `play_count_covered_posts` (integer) — Posts the play sum actually covers. Lower than total_ad_posts means the sum is a lower bound. - `window_months` (integer) — Length of the window in months. #### Example ```console $ solari instagram brand ad stats username=innisfreeofficial ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "total_ad_posts": 405, "unique_creator_count": 360, "total_play_count": 27357941, "play_count_covered_posts": 405, "window_months": 3 } ``` #### As an MCP call ```json { "name": "solari_instagram_brand_ad_stats", "arguments": { "username": "innisfreeofficial" } } ``` #### Notes - Takes a handle only. - For the underlying rows, use brand ad posts. #### Related tools - [`solari_instagram_brand_ad_posts`](https://solari.sh/docs/tools/instagram-brand-ad-posts.md) - [`solari_instagram_brand_overview`](https://solari.sh/docs/tools/instagram-brand-overview.md) ### solari instagram brand ad posts > Row-level sponsored posts targeting a brand, with the authoring creator on each row. - **CLI**: `solari instagram brand ad posts` - **MCP tool**: `solari_instagram_brand_ad_posts` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Paginated row-level list of the identified sponsored posts targeting a brand, each hydrated with slug, caption, posted_at, like/comment counts, play_count for videos, and the authoring creator's username and account_id. sort=recent pages the full window newest-first with an exact total; sort=engagement ranks within a bounded recent window whose size is reported as ranking_window (non-null means the ordering covers a slice, not everything). Widen the lookback with months (default 3, up to 24). Row-level companion to solari_instagram_brand_ad_stats. Takes the brand's Instagram handle (no @). Works with any signed-in SOLARI account. Returns 404 if the handle is not tracked. **When to use it** — Analysing a brand's ad history as raw rows rather than rollups. **What comes back** — Sponsored posts. What total means depends on the sort. #### Parameters - `username` (string, required) — Brand Instagram handle without the leading @. - `sort` (enum, optional, default "recent") — recent pages the full window with an exact total; engagement ranks within ranking_window. Values: `recent`, `engagement`. - `months` (integer, optional, ≥ 1) — Lookback window in months, default 3. Values above 24 are clamped to 24. - `limit` (integer, optional, ≥ 1) — Posts per page, default 50. Values above 200 are clamped to 200. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. #### Response ##### `Response` - `items` (object[]) — Sponsored posts. - `total` (integer) — Exact count across the window when sort=recent. - `has_more` (boolean) — Whether another page exists. - `ranking_window` (integer | null) — How far the engagement ranking actually looked. Non-null means the ordering covers a slice, not the whole window. ##### `items[]` - `id` (uuid) — Post id. - `slug` (string) — Instagram shortcode. - `text` (string) — Caption text. - `posted_at` (timestamp) — Publication time (UTC). - `username / user_id / account_id` (string) — The authoring creator. account_id is the current name; user_id carries the same value. - `like_count / comment_count / play_count` (integer) — Engagement snapshot. - `media_type` (string) — Post format. - `media / media_url / thumbnail_url` (string) — Media links. - `virtual_campaign` (object | null) — Campaign grouping, when one is resolved. #### Example ```console $ solari instagram brand ad posts username=innisfreeofficial limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "id": "01a062a0-2747-72eb-b20d-670cf30f2c96", "slug": "DcygG05GrA-", "text": "#광고 요즘 부쩍 신경 쓰이기 시작한 모공 고민을 직접 경험해보고 싶어 방문한 이니스프리 레티놀 시카 강의실 무빙 팝업💙\n\n업그레이드된 레티놀 시카 모공 흔적 앰플을 직접 테스트해볼 수 있을 뿐 아니라, 제품을 알아보고 체험할 수 있는 다양한 프로그램과 이벤트가 마련되어 있어 더욱 재미있게 둘러볼 수 있었어요.\n\n특히 오늘 방문했을 때는 정말 많은 분들이 찾아와서 놀랐는데요. 대기 줄이 길게 …", "posted_at": "2026-09-02T14:56:19Z", "virtual_campaign": null, "username": "_mini_mming", "user_id": "018caf92-e08a-78a2-b9c3-59f6f5740182", "profile_picture_url": null, "like_count": 384, "comment_count": 4, "thumbnail_url": null, "media_url": null, "media": [], "media_type": "post", "account_id": "018caf92-e08a-78a2-b9c3-59f6f5740182" }, "… 1 more" ], "total": 405, "has_more": true, "ranking_window": null } ``` #### As an MCP call ```json { "name": "solari_instagram_brand_ad_posts", "arguments": { "username": "innisfreeofficial", "limit": 2 } } ``` #### Notes - sort=recent pages the full window newest-first with an exact total. sort=engagement ranks within a bounded recent slice and reports its size as ranking_window. - months defaults to 3 and is clamped at 24. - Takes a handle only. An untracked handle returns 404. #### Related tools - [`solari_instagram_brand_ad_stats`](https://solari.sh/docs/tools/instagram-brand-ad-stats.md) - [`solari_instagram_account_ad_posts`](https://solari.sh/docs/tools/instagram-account-ad-posts.md) ### solari instagram brand top collaborators > Creators ranked by how often they have run ads for a brand. - **CLI**: `solari instagram brand top collaborators` - **MCP tool**: `solari_instagram_brand_top_collaborators` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Ranked list of creators who authored resolved ad posts targeting the brand, ordered by collaboration count. Identify the brand by account_id (SOLARI account UUID from solari_instagram_account_search) or by username (Instagram handle); an unknown reference returns a not-found error. Retrospective collaboration history, not a forward-looking fit score. Works with any signed-in SOLARI account. **When to use it** — "Who does this brand work with?" Retrospective history, not a forward-looking fit score. **What comes back** — Creators ordered by collaboration count. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Brand account_id (SOLARI account UUID) from solari_instagram_account_search. Provide this or username. - `username` (string, optional, ≤ 64 chars) — Brand Instagram handle, with or without a leading @. Ignored when account_id is set. - `promotion` (enum, optional, default "all") — Ad-post promotion filter: all rows, promotion=true rows, or promotion=false rows. Values: `all`, `true_only`, `false_only`. - `limit` (integer, optional, ≥ 1) — Maximum creators returned, default 20. Values above 1000 are clamped to 1000. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. #### Response ##### `Response` - `brand_id` (uuid) — The resolved brand account_id. - `promotion_filter` (string) — The promotion filter applied. - `items` (object[]) — Creators, collaboration count descending. - `total_count` (integer) — Creators matching the filter. ##### `items[]` - `creator_id` (uuid) — Creator account_id — the value the other tools accept. - `username / full_name` (string) — Handle and display name. - `profile_pic_url` (string) — Profile picture. - `follower_count` (integer) — Follower count. - `collaboration_count` (integer) — Collaboration posts with this brand. #### Example ```console $ solari instagram brand top collaborators username=innisfreeofficial limit=5 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "brand_id": "018cabce-14cc-7544-8890-7811ec33ef74", "promotion_filter": "all", "items": [ { "creator_id": "0195474c-8ee3-7690-a385-71b2913e31b5", "username": "donge_cos", "full_name": "💞동이💞", "profile_pic_url": "https://dcr.bzine.co/instagram/users/donge_cos/profile-picture", "follower_count": 83354, "collaboration_count": 31 }, { "creator_id": "018ecc75-55d8-70a7-a348-d370aa504ed9", "username": "beinny_motd", "full_name": "베이니 BEINNY", "profile_pic_url": "https://dcr.bzine.co/instagram/users/beinny_motd/profile-picture", "follower_count": 205754, "collaboration_count": 29 }, "… 3 more" ], "total_count": 2331 } ``` #### As an MCP call ```json { "name": "solari_instagram_brand_top_collaborators", "arguments": { "username": "innisfreeofficial", "limit": 5 } } ``` #### Notes - limit reaches 1000. Feed the creator_ids into brand collaborator posts, 100 at a time, to hydrate their posts. - The mirror view starting from a creator is account collabs. #### Related tools - [`solari_instagram_brand_collaborator_posts`](https://solari.sh/docs/tools/instagram-brand-collaborator-posts.md) - [`solari_instagram_account_collabs`](https://solari.sh/docs/tools/instagram-account-collabs.md) ### solari instagram brand collaborator posts > One brand plus up to 100 creators, hydrated in a single call. - **CLI**: `solari instagram brand collaborator posts` - **MCP tool**: `solari_instagram_brand_collaborator_posts` - **Access**: `solari:read` — Works with any signed-in SOLARI account. For one brand and up to 100 creator account_ids, returns each creator's sponsored posts targeting that brand — per creator: post_count, reels_count, images_count, follower_count, and the posts themselves (slug, caption, posted_at, like/comment counts) — sorted by total engagement. All-time history, one call instead of one per creator. Get creator account_ids from solari_instagram_brand_top_collaborators or solari_instagram_brand_overview. Identify the brand by account_id (SOLARI account UUID) or by username (Instagram handle); an unknown reference returns a not-found error. Works with any signed-in SOLARI account. **When to use it** — Replacing one call per creator. Covers all-time history rather than a recent window. **What comes back** — Per-creator rollups and the posts themselves, sorted by total engagement. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Brand account_id (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — Brand Instagram handle, with or without a leading @. Ignored when account_id is set. - `account_ids` (uuid[], required, 1–100 items, uuid) — Creator account_ids (SOLARI account UUIDs) to hydrate, at most 100 per call. #### Response ##### `Response` - `(top level)` (object[]) — An array of creators — this response has no envelope object. ##### `[]` - `user_id` (uuid) — Creator account_id. - `username / full_name` (string) — Handle and display name. - `follower_count` (integer) — Follower count. - `post_count` (integer) — Posts targeting this brand. - `reels_count / images_count` (integer) — Breakdown by format. - `posts` (object[]) — The posts: id, slug, text, posted_at, like_count, comment_count, play_count. - `like_count_avg / comment_count_avg` (number | null) — Mean engagement, when computed. #### Example ```console $ solari instagram brand collaborator posts username=innisfreeofficial account_ids='["0195474c-8ee3-7690-a385-71b2913e31b5","018ecc75-55d8-70a7-a348-d370aa504ed9"]' ``` _Long strings and repeated array entries are trimmed for readability._ ```json [ { "user_id": "018ecc75-55d8-70a7-a348-d370aa504ed9", "username": "beinny_motd", "full_name": "베이니 BEINNY", "post_count": 29, "follower_count": 205754, "reels_count": 1, "images_count": 28, "posts": [ { "id": "019c98bc-a666-717d-a5fe-ea96f1345042", "slug": "ByVKkIbnQ8S", "text": "#이니스프리 에서 새롭게 출시된 #구름블러틴트 ☁️💓\n비비드 코튼 잉크 블러버젼이에용\n.\n요즘 이런 블러틴트류 많이 출시돼서 넘 행복해요🥺💛\n이니스프리 블러틴트는 보송보송한 마무리지만 꽤 촉촉하고 가볍게 발리더라구요! 발림성 넘 좋았어요✨\n총 8가지 컬러인데 그중 제 맘에 드는 4가지 컬러는 입술에 발색해서 보여드려용 :) 특히 로즈+핑크 섞인듯한 2호 #로제핑크 완전 추천👍🏻✨\n가격은 9, …", "posted_at": "2019-06-05T14:02:19Z", "virtual_campaign": null, "like_count": 2399, "comment_count": 20, "play_count": null, "username": "beinny_motd", "user_id": "018ecc75-55d8-70a7-a348-d370aa504ed9" }, "… 10 more" ], "like_count_avg": null, "comment_count_avg": null, "synced_at": null }, "… 1 more" ] ``` #### As an MCP call ```json { "name": "solari_instagram_brand_collaborator_posts", "arguments": { "username": "innisfreeofficial", "account_ids": [ "0195474c-8ee3-7690-a385-71b2913e31b5", "018ecc75-55d8-70a7-a348-d370aa504ed9" ] } } ``` #### Notes - account_ids accepts a JSON array or a comma-separated list. Up to 100 per call. - Covers full history, with no month window. #### Related tools - [`solari_instagram_brand_top_collaborators`](https://solari.sh/docs/tools/instagram-brand-top-collaborators.md) - [`solari_instagram_brand_overview`](https://solari.sh/docs/tools/instagram-brand-overview.md) ### solari instagram brand lookalike content > Posts that look and read like a brand's best-performing ads. - **CLI**: `solari instagram brand lookalike content` - **MCP tool**: `solari_instagram_brand_lookalike_content` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Instagram posts visually and semantically similar to the brand's top-performing sponsored ads, found via vector-neighbour search seeded from the brand's own ad posts. Identify the brand by account_id (SOLARI account UUID from solari_instagram_account_search) or by username (Instagram handle); an unknown reference returns a not-found error. Works with any signed-in SOLARI account. **When to use it** — Reference hunting. Vector-neighbour search seeded from the brand's own top ads. **What comes back** — The lookalike posts, plus the brand's own ads that seeded the search. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Brand account_id (SOLARI account UUID) whose sponsored ads seed the lookalike search. Provide this or username. - `username` (string, optional, ≤ 64 chars) — Brand Instagram handle, with or without a leading @. Ignored when account_id is set. - `limit` (integer, optional, ≥ 1) — Maximum lookalike posts returned, default 30. Values above 50 are clamped to 50. - `region` (string, optional, default "KR") — Region code such as KR, JP, or US scoping the search. #### Response ##### `Response` - `items` (object[]) — Lookalike posts. - `basis` (object[]) — The brand's own ad posts used as seeds. - `region` (string) — Region the search was scoped to. ##### `items[] · basis[]` - `post_id` (uuid) — SOLARI post id. Feed it straight into the other content tools. - `slug` (string) — Instagram shortcode — the segment after /p/ or /reel/ in a public URL. - `author_id` (uuid) — account_id of the authoring account. - `username` (string) — Author handle. - `full_name` (string | null) — Profile display name. - `profile_pic_url` (string | null) — Profile picture URL. - `follower_count` (integer | null) — Author follower count at snapshot time. - `region` (string | null) — Region code assigned to the author. - `posted_at` (timestamp) — Publication time (UTC). - `media_type` (string) — image, video, or carousel. - `play_count` (integer | null) — Video plays. null for image posts. - `like_count` (integer | null) — Likes at snapshot time. - `text` (string | null) — Caption text. - `media_url` (string) — Original media URL. - `thumbnail_url` (string) — Thumbnail URL. - `score` (number | null) — Feed ranking score. Comparable only within one response. - `efficiency_score` (number | null) — Performance relative to the author's follower count. - `est_percentile` (number | null) — Estimated percentile within the region, 0–1. - `total_views_3m` (integer | null) — Author's cumulative views over the last 3 months. - `median_views_3m` (integer | null) — Author's median views over the last 3 months. - `recent_collab_brands` (string[]) — Brands the author has collaborated with recently. - `item_type` (string) — Item kind tag; post in the content feeds. - `content_source` (string | null) — Which pipeline surfaced this item. - `is_saved` (boolean | null) — Whether the item is saved in the SOLARI app. - `updated_at` (timestamp | null) — When the metric snapshot was last refreshed. #### Example ```console $ solari instagram brand lookalike content username=innisfreeofficial limit=3 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "item_type": "content", "post_id": "019ecb92-a677-7421-8ed6-752efe3d99d0", "author_id": "0196cb39-870a-7a76-9773-0b95789c877d", "username": "boo_rookie", "full_name": null, "profile_pic_url": null, "follower_count": null, "region": null, "posted_at": "2026-06-11T08:14:37Z", "media_type": "video", "play_count": 427258, "like_count": null, "score": null, "efficiency_score": null, "est_percentile": null, "updated_at": null, "media_url": "https://smr-images-b.bzine.co/users/0196cb39-870a-7a76-9773-0b95789c877d/posts/019ecb92-a677-7421-8ed6-752efe3d99d0/medias/019ecb92-a92e-7fc8-b644-69b930f2e197.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=100ms/https://smr-images-a.bzine.co/users/0196cb39-870a-7a76-9773-0b95789c877d/posts/019ecb92-a677-7421-8ed6-752efe3d99d0/medias/019ecb92-a92e-7fc8-b644-69b930f2e1 …", "slug": "DZcD8KXxKwd", "text": null, "brand_match_score": null, "recent_collab_brands": [], "total_views_3m": null, "median_views_3m": null, "is_saved": null, "content_source": "lookalikes_by_top_ad" }, "… 2 more" ], "basis": [ { "item_type": "content", "post_id": "01a04c73-3ec3-7873-9e84-334c644abfe4", "author_id": "0196c474-c96e-71ad-aceb-61af051c81d3", "username": "hwitto_", "full_name": null, "profile_pic_url": null, "follower_count": null, "region": null, "posted_at": null, "media_type": "video", "play_count": 155729, "like_count": null, "score": null, "efficiency_score": null, "est_percentile": null, "updated_at": null, "media_url": "https://smr-images-a.bzine.co/users/0196c474-c96e-71ad-aceb-61af051c81d3/posts/01a04c73-3ec3-7873-9e84-334c644abfe4/medias/01a04c73-4036-7a83-a52a-97b0058e6732.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=100ms/https://smr-images.bzine.co/users/0196c474-c96e-71ad-aceb-61af051c81d3/posts/01a04c73-3ec3-7873-9e84-334c644abfe4/medias/01a04c73-4036-7a83-a52a-97b0058e6732 …", "slug": "DckGrZ6vZiU", "text": null, "brand_match_score": null, "recent_collab_brands": [], "total_views_3m": null, "median_views_3m": null, "is_saved": null, "content_source": "lookalikes_by_top_ad" }, "… 5 more" ], "region": "KR" } ``` #### As an MCP call ```json { "name": "solari_instagram_brand_lookalike_content", "arguments": { "username": "innisfreeofficial", "limit": 3 } } ``` #### Notes - limit is clamped at 50. - An empty basis means the brand has no ad posts to seed from yet. #### Related tools - [`solari_instagram_brand_ad_posts`](https://solari.sh/docs/tools/instagram-brand-ad-posts.md) - [`solari_instagram_content_search`](https://solari.sh/docs/tools/instagram-content-search.md) ### solari instagram account profile > Everything SOLARI knows about one Instagram account, with performance metrics. - **CLI**: `solari instagram account profile` - **MCP tool**: `solari_instagram_account_profile` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Full SOLARI profile for one tracked Instagram account: username, full name, bio, follower/following/post counts, verified flag, inferred account_type, view metrics (median and total views, ad count, month-over-month growth, region percentiles), plus embedded previews of recent posts and recent ad collaborations. Identify the account by account_id (UUID from solari_instagram_account_search) or by username (Instagram handle). A username not tracked yet is fetched live on first request (allow several seconds; fetched_on_demand=true in the response, with no view metrics or collaboration history built yet); a not-found error then means the handle does not exist on Instagram. Works with any signed-in SOLARI account. **When to use it** — The first call of any account deep-dive. Recent posts and recent collaborations come embedded, which saves follow-up calls. **What comes back** — Profile fields, view-based performance metrics, and embedded previews. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the account (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — Instagram handle, with or without a leading @. Ignored when account_id is set. #### Response ##### `Response` - `user_id` (uuid) — The account_id. - `username / full_name / bio` (string) — Handle, display name, bio text. - `follower_count / following_count` (integer) — Follower and following counts. - `total_post_count` (integer) — Lifetime post count. - `post_count_3m` (integer) — Posts in the last 3 months. - `is_verified` (boolean) — Verification badge. - `account_type` (string) — Account character inferred by SOLARI (brand, creator, …). - `median_views_cur` (integer) — Median views in the current window. - `total_views_cur` (integer) — Total views in the current window. - `ad_count_cur` (integer) — Sponsored posts in the current window. - `median_views_growth_m1` (number) — Median-view change vs. the previous month, as a ratio. - `total_views_growth_m1` (number) — Total-view change vs. the previous month, as a ratio. - `median_views_region_pct` (number) — Median-view percentile within the region, 0–1. - `total_views_region_pct` (number) — Total-view percentile within the region, 0–1. - `recent_posts` (object[]) — Recent post previews. - `recent_collabs` (object[]) — Recent ad-collaboration previews. - `fetched_on_demand` (boolean) — true when this request is what first pulled the account in. #### Example ```console $ solari instagram account profile username=innisfreeofficial ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "user_id": "018cabce-14cc-7544-8890-7811ec33ef74", "username": "innisfreeofficial", "full_name": "INNISFREE | 이니스프리", "bio": "NATURE MEETS KOREAN SKIN SCIENCE", "profile_pic_url": "https://dcr.bzine.co/instagram/users/innisfreeofficial/profile-picture", "follower_count": 847619, "total_post_count": 4131, "post_count_3m": 100, "following_count": 17, "is_verified": true, "median_views_cur": 12409, "ad_count_cur": 0, "total_views_cur": 685771, "median_views_growth_m1": 0.04956440835659308, "total_views_growth_m1": 0.39407867587418205, "median_views_region_pct": 0.1736183168163037, "total_views_region_pct": 0.1457900950723917, "recent_posts": [ { "post_id": "01a06275-d974-7fda-98ee-dd3ee15b4dcf", "slug": "DcyMAmUh6FZ", "media_type": "video", "media_url": "https://smr-images-b.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.m …", "text": "Deeply hydrated skin—NO OFF HOURS. 💚\nwherever the day takes MINGYU (@min9yu_k)—his hydration stays SUPERCHARGED ⚡️\n\nGreen Tea Ceramide Milk: Lightweight milky toner that won‘t clog your pores\nGreen Tea Ceramide Mist: Tou …", "play_count": 22467, "like_count": 3224, "video_media_count": 0, "media_count": 1 }, "… 5 more" ], "recent_collabs": [], "account_type": "brand", "fetched_on_demand": false } ``` #### As an MCP call ```json { "name": "solari_instagram_account_profile", "arguments": { "username": "innisfreeofficial" } } ``` #### Notes - An untracked handle is fetched live on first request. Allow several seconds; fetched_on_demand=true marks it, and view metrics and collaboration history are not built yet in that state. - A not-found error after that means the handle does not exist on Instagram. - Metrics are snapshots and can lag live counts. #### Related tools - [`solari_instagram_account_posts`](https://solari.sh/docs/tools/instagram-account-posts.md) - [`solari_instagram_account_collabs`](https://solari.sh/docs/tools/instagram-account-collabs.md) - [`solari_tiktok_account_profile`](https://solari.sh/docs/tools/tiktok-account-profile.md) ### solari instagram account posts > Page through one account's posts, newest first. - **CLI**: `solari instagram account posts` - **MCP tool**: `solari_instagram_account_posts` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Posts by one tracked Instagram account, newest first, with pagination and filters. Identify the account by account_id (UUID from solari_instagram_account_search) or by username (Instagram handle). Each item has post_id (SOLARI post UUID), slug and url (public Instagram permalink), post_type (reel, video, photo, or carousel), posted_at, caption text, like/comment/play counts, media_count, is_paid_partnership, a medias array (every media of the post in carousel order, each with media_type, media/thumbnail URLs, video_duration, and tags — accounts and hashtags tagged on that media, with account_id when the tagged account is tracked), and a representative thumbnail_url. The response carries found, account_id, username, total, has_more, and items; page with limit and offset, narrow with since/until (UTC dates, inclusive) and post_type. A username not tracked yet is fetched live on first request (allow several seconds), and fetched_on_demand=true marks that only its most recent posts are available so far; found=false means the handle does not exist on Instagram. Works with any signed-in SOLARI account. **When to use it** — Going deeper than the profile preview, or pulling raw rows narrowed by date range and format. **What comes back** — Posts with every media of each post, including the accounts and hashtags tagged on them. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the account (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — Instagram handle, with or without a leading @. Ignored when account_id is set. - `limit` (integer, optional, ≥ 1) — Posts per page, default 12. Values above 200 are clamped to 200. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. - `post_type` (enum, optional) — Only posts of this format. reel is short-form single-video; video is non-reel video. Values: `reel`, `video`, `photo`, `carousel`. #### Response ##### `Response` - `found` (boolean) — false means the handle does not exist on Instagram. - `account_id / username` (string) — The resolved account. - `total` (integer) — Posts matching the filters. - `has_more` (boolean) — Whether another page exists. - `items` (object[]) — Posts, newest first. - `fetched_on_demand` (boolean) — true when only the most recent posts are available so far. ##### `items[]` - `post_id` (uuid) — SOLARI post id. - `slug` (string) — Instagram shortcode. - `url` (string) — Public permalink. - `post_type` (string) — reel, video, photo, or carousel. - `posted_at` (timestamp) — Publication time (UTC). - `text` (string) — Caption text. - `like_count / comment_count / play_count` (integer) — Engagement snapshot. - `media_count` (integer) — Number of medias in the post. - `is_paid_partnership` (boolean | null) — Instagram's own paid-partnership label. - `medias` (object[]) — Every media in carousel order — each with media_type, media/thumbnail URLs, and video_duration. - `medias[].tags` (object[]) — Accounts and hashtags tagged on that media. A tagged account carries account_id when SOLARI tracks it. - `thumbnail_url` (string) — Representative thumbnail. #### Example ```console $ solari instagram account posts username=innisfreeofficial limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "found": true, "account_id": "018cabce-14cc-7544-8890-7811ec33ef74", "username": "innisfreeofficial", "fetched_on_demand": false, "total": 4196, "has_more": true, "items": [ { "post_id": "01a06275-d974-7fda-98ee-dd3ee15b4dcf", "slug": "DcyMAmUh6FZ", "url": "https://www.instagram.com/p/DcyMAmUh6FZ/", "post_type": "reel", "posted_at": "2026-09-02T12:00:06+00:00", "text": "Deeply hydrated skin—NO OFF HOURS. 💚\nwherever the day takes MINGYU (@min9yu_k)—his hydration stays SUPERCHARGED ⚡️\n\nGreen Tea Ceramide Milk: Lightweight milky toner that won‘t clog your pores\nGreen Tea Ceramide Mist: Tou …", "like_count": 3224, "comment_count": 57, "play_count": 22467, "media_count": 1, "is_paid_partnership": false, "medias": [ { "media_type": "video", "media_url": "https://smr-images-b.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.m …", "video_duration": 23.868000030517578, "tags": [] } ], "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.m …" }, "… 1 more" ] } ``` #### As an MCP call ```json { "name": "solari_instagram_account_posts", "arguments": { "username": "innisfreeofficial", "limit": 2 } } ``` #### Notes - Up to 200 per page. For bulk pulls prefer --ndjson appended to a file over large in-memory pages. - since and until are UTC dates and inclusive on both ends. - post_type=reel is short-form single video; video is non-reel video. #### Related tools - [`solari_instagram_account_profile`](https://solari.sh/docs/tools/instagram-account-profile.md) - [`solari_instagram_content_detail`](https://solari.sh/docs/tools/instagram-content-detail.md) - [`solari_tiktok_account_posts`](https://solari.sh/docs/tools/tiktok-account-posts.md) ### solari instagram account collabs > Which brands a creator has run ads for, grouped by brand. - **CLI**: `solari instagram account collabs` - **MCP tool**: `solari_instagram_account_collabs` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Recent ad collaborations produced by one creator within a month window. Each item is a target brand (target_account_id, target_username) with collab_count, last_posted_at, and a sample collaboration post. Returns items, has_more, and total; page with limit/offset. Identify the creator by account_id (SOLARI account UUID) or by username (Instagram handle); an unknown reference returns a not-found error. Mirror view of solari_instagram_brand_top_collaborators, which starts from the brand instead. Works with any signed-in SOLARI account. **When to use it** — "Who does this creator work with?" The mirror view, starting from the brand, is brand top collaborators. **What comes back** — One row per target brand, each carrying a sample collaboration post. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the creator (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — Instagram handle, with or without a leading @. Ignored when account_id is set. - `months` (integer, optional, ≥ 1) — Lookback window in months, default 3. Values above 12 are clamped to 12. - `limit` (integer, optional, ≥ 1) — Maximum items per page, default 5. Values above 200 are clamped to 200. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. #### Response ##### `Response` - `total` (integer) — Total rows matching the filters. - `has_more` (boolean) — Whether rows exist beyond offset + limit. - `items` (object[]) — Collaboration summaries, one per target brand. ##### `items[]` - `target_account_id` (uuid) — account_id of the target brand. - `target_username` (string) — Target brand handle. - `collab_count` (integer) — Collaboration posts with this brand. - `last_posted_at` (timestamp) — Most recent collaboration. - `post_id / slug` (string) — Identifiers of the sample post. - `text` (string) — Sample post caption. - `like_count / play_count` (integer) — Sample post engagement. - `media_type` (string) — Sample post format. - `thumbnail_url / media_url` (string) — Sample post media. - `bio` (string) — Target brand bio. #### Example ```console $ solari instagram account collabs username=beinny_motd months=6 limit=3 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "post_id": "01a05575-7c9b-7232-8519-4a38fa061389", "target_user_id": "018cab85-8ef8-7dc9-ab0a-7044d463f65e", "target_username": "dasique_official", "collab_count": 2, "last_posted_at": "2026-08-30T05:08:56+00:00", "slug": "DcpugJ2kzv8", "text": "#광고 무겁지 않은 가을 데일리 팔레트 로즈밀크티 . .🫖🤎\n차분하고 미지근한 로즈핑크 팔레트인데\n부드러운 밀크티 무드라서 분위기가 넘 예뻐요..🥺\n\n데이지크에서 올리브영 X 산리오 콜라보\n시티팝 에디션으로 미니섀도우팔레트 4종이 출시되는데\n그 중 자주 추천드렸던 로즈밀크티, 밀크라떼가 있더라구요 !\n\nNEW 컬러 피치레코드, 모브카세트도 출시되어요🤍\n도시의 아침과 저녁 무드를 담은 데일리한 …", "play_count": 0, "media_type": "8", "like_count": 878, "video_media_count": 0, "media_count": 15, "bio": "🫒올영세일 08.30 – 09.05\nUP TO 37% SALE\n올리브영X산리오,\n🌠데이지크 🆕 미니 섀도우", "thumbnail_url": "https://bzine.co/cdn-cgi/image/fit=scale-down,width=480/https://smr-images-c.bzine.co/users/018ecc75-55d8-70a7-a348-d370aa504ed9/posts/01a05575-7c9b-7232-8519-4a38fa061389/medias/01a05575-7dd3-779e-9050-a6cb59578cb9.jpg", "media_url": "https://bzine.co/cdn-cgi/image/fit=scale-down,width=480/https://smr-images-c.bzine.co/users/018ecc75-55d8-70a7-a348-d370aa504ed9/posts/01a05575-7c9b-7232-8519-4a38fa061389/medias/01a05575-7dd3-779e-9050-a6cb59578cb9.jpg", "target_account_id": "018cab85-8ef8-7dc9-ab0a-7044d463f65e" }, "… 2 more" ], "has_more": true, "total": 7 } ``` #### As an MCP call ```json { "name": "solari_instagram_account_collabs", "arguments": { "username": "beinny_motd", "months": 6, "limit": 3 } } ``` #### Notes - target_user_id is the legacy name for the same value as target_account_id. New code should read target_account_id. - months defaults to 3 and is clamped at 12. - For row-level history instead of per-brand rollups, use account ad posts. #### Related tools - [`solari_instagram_account_ad_posts`](https://solari.sh/docs/tools/instagram-account-ad-posts.md) - [`solari_instagram_brand_top_collaborators`](https://solari.sh/docs/tools/instagram-brand-top-collaborators.md) ### solari instagram account ad posts > Row-level sponsored posts a creator authored, with the target brand on each row. - **CLI**: `solari instagram account ad posts` - **MCP tool**: `solari_instagram_account_ad_posts` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Paginated row-level list of the identified sponsored posts one creator authored, newest first, with the target brand attached to each row — one row per post-brand pair, so a multi-brand post appears once per target. Each item carries post_id, slug and url, post_type, posted_at, caption text, like/comment/play counts, media_count, is_paid_partnership, and target_account_id/target_username. Filter to one brand with target (its account_id or Instagram handle). Widen the lookback with months (default 3, up to 24). Row-level companion to solari_instagram_account_collabs, which groups the same history by brand. Identify the creator by account_id (SOLARI account UUID) or by username (Instagram handle); an unknown reference returns a not-found error. Works with any signed-in SOLARI account. **When to use it** — Analysing collaboration history as raw rows. A post tagging several brands appears once per target, so rows are post–brand pairs. **What comes back** — Sponsored posts, newest first. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the creator (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — Instagram handle, with or without a leading @. Ignored when account_id is set. - `months` (integer, optional, ≥ 1) — Lookback window in months, default 3. Values above 24 are clamped to 24. - `limit` (integer, optional, ≥ 1) — Items per page, default 50. Values above 200 are clamped to 200. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. - `target` (string, optional, ≤ 64 chars) — Optional target-brand filter: its account_id (SOLARI account UUID) or Instagram handle. #### Response ##### `Response` - `account_id / username` (string) — The resolved creator. - `months` (integer) — Lookback window applied. - `total` (integer) — Total rows. - `has_more` (boolean) — Whether another page exists. - `items` (object[]) — Post–brand pairs. ##### `items[]` - `post_id / slug / url` (string) — Post identifiers and public link. - `post_type` (string) — reel, video, photo, or carousel. - `posted_at` (timestamp) — Publication time (UTC). - `text` (string) — Caption text. - `like_count / comment_count / play_count` (integer) — Engagement snapshot. - `media_count` (integer) — Number of medias. - `is_paid_partnership` (boolean | null) — Instagram's paid-partnership label. - `target_account_id / target_username` (string) — The brand this row is attributed to. #### Example ```console $ solari instagram account ad posts username=beinny_motd months=6 limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "account_id": "018ecc75-55d8-70a7-a348-d370aa504ed9", "username": "beinny_motd", "months": 6, "total": 12, "has_more": true, "items": [ { "post_id": "01a05575-7c9b-7232-8519-4a38fa061389", "slug": "DcpugJ2kzv8", "url": "https://www.instagram.com/p/DcpugJ2kzv8/", "post_type": "carousel", "posted_at": "2026-08-30T05:08:56Z", "text": "#광고 무겁지 않은 가을 데일리 팔레트 로즈밀크티 . .🫖🤎\n차분하고 미지근한 로즈핑크 팔레트인데\n부드러운 밀크티 무드라서 분위기가 넘 예뻐요..🥺\n\n데이지크에서 올리브영 X 산리오 콜라보\n시티팝 에디션으로 미니섀도우팔레트 4종이 출시되는데\n그 중 자주 추천드렸던 로즈밀크티, 밀크라떼가 있더라구요 !\n\nNEW 컬러 피치레코드, 모브카세트도 출시되어요🤍\n도시의 아침과 저녁 무드를 담은 데일리한 …", "like_count": 878, "comment_count": 19, "play_count": 0, "media_count": 15, "is_paid_partnership": null, "target_account_id": "018cab85-8ef8-7dc9-ab0a-7044d463f65e", "target_username": "dasique_official" }, "… 1 more" ] } ``` #### As an MCP call ```json { "name": "solari_instagram_account_ad_posts", "arguments": { "username": "beinny_motd", "months": 6, "limit": 2 } } ``` #### Notes - target filters to a single brand and accepts either its account_id or its handle. - months defaults to 3 and reaches back up to 24 — further than account collabs. - To see the same history grouped by brand, use account collabs. #### Related tools - [`solari_instagram_account_collabs`](https://solari.sh/docs/tools/instagram-account-collabs.md) - [`solari_instagram_brand_ad_posts`](https://solari.sh/docs/tools/instagram-brand-ad-posts.md) ### solari instagram content detail > One Instagram post in full. - **CLI**: `solari instagram content detail` - **MCP tool**: `solari_instagram_content_detail` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Detail for one Instagram post, in the same item shape as solari_instagram_content_trending entries. Identify the post by post_id (SOLARI post UUID from solari_instagram_account_posts, solari_instagram_content_search, solari_instagram_content_trending, or solari_instagram_content_rising), by slug (the public Instagram shortcode), or by url (the public post URL). A shortcode or URL not tracked yet is fetched live on first request (allow several seconds) and fetched_on_demand=true marks that case; item is null when the post does not exist or is not public, or when a post_id is unknown. Works with any signed-in SOLARI account. **When to use it** — Opening a single post by post_id, shortcode, or public URL. **What comes back** — One item, in the same shape as the content feeds. #### Parameters - `post_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — The SOLARI post_id UUID. Provide this, slug, or url. - `slug` (string, optional, pattern ^[A-Za-z0-9_-]{3,20}$) — Public Instagram shortcode, the segment after /p/, /reel/, or /tv/ in a post URL. Ignored when post_id is set. - `url` (string, optional, ≤ 512 chars) — Public Instagram post URL such as https://www.instagram.com/p// or .../reel//. Ignored when post_id or slug is set. #### Response ##### `Response` - `item` (object | null) — The post. null when it does not exist or is not public. - `fetched_on_demand` (boolean) — true when this request is what first pulled the post in. ##### `item` - `post_id` (uuid) — SOLARI post id. Feed it straight into the other content tools. - `slug` (string) — Instagram shortcode — the segment after /p/ or /reel/ in a public URL. - `author_id` (uuid) — account_id of the authoring account. - `username` (string) — Author handle. - `full_name` (string | null) — Profile display name. - `profile_pic_url` (string | null) — Profile picture URL. - `follower_count` (integer | null) — Author follower count at snapshot time. - `region` (string | null) — Region code assigned to the author. - `posted_at` (timestamp) — Publication time (UTC). - `media_type` (string) — image, video, or carousel. - `play_count` (integer | null) — Video plays. null for image posts. - `like_count` (integer | null) — Likes at snapshot time. - `text` (string | null) — Caption text. - `media_url` (string) — Original media URL. - `thumbnail_url` (string) — Thumbnail URL. - `score` (number | null) — Feed ranking score. Comparable only within one response. - `efficiency_score` (number | null) — Performance relative to the author's follower count. - `est_percentile` (number | null) — Estimated percentile within the region, 0–1. - `total_views_3m` (integer | null) — Author's cumulative views over the last 3 months. - `median_views_3m` (integer | null) — Author's median views over the last 3 months. - `recent_collab_brands` (string[]) — Brands the author has collaborated with recently. - `item_type` (string) — Item kind tag; post in the content feeds. - `content_source` (string | null) — Which pipeline surfaced this item. - `is_saved` (boolean | null) — Whether the item is saved in the SOLARI app. - `updated_at` (timestamp | null) — When the metric snapshot was last refreshed. #### Example ```console $ solari instagram content detail slug=DcyMAmUh6FZ ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "item": { "item_type": "content", "post_id": "01a06275-d974-7fda-98ee-dd3ee15b4dcf", "author_id": "018cabce-14cc-7544-8890-7811ec33ef74", "username": "innisfreeofficial", "full_name": "INNISFREE | 이니스프리", "profile_pic_url": "https://dcr.bzine.co/instagram/users/innisfreeofficial/profile-picture", "follower_count": 847619, "region": null, "posted_at": "2026-09-02T12:00:06Z", "media_type": "video", "play_count": 22467, "like_count": 3224, "score": null, "efficiency_score": null, "est_percentile": null, "updated_at": null, "media_url": "https://smr-images-b.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images.bzine.co/users/018cabce-14cc-7544-8890-7811ec33ef74/posts/01a06275-d974-7fda-98ee-dd3ee15b4dcf/medias/01a06275-db2b-77f7-a020-b4beb744771f.m …", "slug": "DcyMAmUh6FZ", "text": "Deeply hydrated skin—NO OFF HOURS. 💚\nwherever the day takes MINGYU (@min9yu_k)—his hydration stays SUPERCHARGED ⚡️\n\nGreen Tea Ceramide Milk: Lightweight milky toner that won‘t clog your pores\nGreen Tea Ceramide Mist: Tou …", "brand_match_score": null, "recent_collab_brands": [], "total_views_3m": null, "median_views_3m": null, "is_saved": null, "content_source": null }, "fetched_on_demand": false } ``` #### As an MCP call ```json { "name": "solari_instagram_content_detail", "arguments": { "slug": "DcyMAmUh6FZ" } } ``` #### Notes - Passing url extracts the shortcode after /p/, /reel/, or /tv/ automatically. - An untracked shortcode or URL is fetched live on first request. - To open several at once, use content batch. #### Related tools - [`solari_instagram_content_batch`](https://solari.sh/docs/tools/instagram-content-batch.md) - [`solari_instagram_account_posts`](https://solari.sh/docs/tools/instagram-account-posts.md) ### solari instagram content batch > Hydrate up to 100 post ids in one call. - **CLI**: `solari instagram content batch` - **MCP tool**: `solari_instagram_content_batch` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Batch companion to solari_instagram_content_detail: hydrates up to 100 posts by their SOLARI post UUIDs in a single call. Each row carries slug, caption, posted_at, like/comment counts, play_count for videos, and the author's username and account_id. Untracked ids are omitted, so found can be lower than requested. Feed it post_id lists from solari_instagram_brand_overview (full=true), solari_instagram_account_posts, solari_instagram_content_search, or the trend feeds. Works with any signed-in SOLARI account. **When to use it** — Turning an id list from brand overview or a trend feed into real captions and metrics. **What comes back** — The posts that were found among the requested ids. #### Parameters - `post_ids` (uuid[], required, 1–100 items, uuid) — SOLARI post UUIDs to hydrate, at most 100 per call. Not Instagram shortcodes/slugs. - `sort` (enum, optional, default "recent") — Item order: posted_at descending (recent) or like+comment engagement descending. Values: `recent`, `engagement`. #### Response ##### `Response` - `items` (object[]) — The posts found. - `requested` (integer) — How many ids were sent. - `found` (integer) — How many resolved. Untracked ids are dropped, so this can be lower. ##### `items[]` - `id` (uuid) — Post id. - `slug` (string) — Instagram shortcode. - `text` (string) — Caption text. - `posted_at` (timestamp) — Publication time (UTC). - `username / user_id / account_id` (string) — Authoring account. account_id is the current name. - `like_count / comment_count` (integer) — Engagement snapshot. - `play_count` (integer | null) — Video plays. - `media_type` (string) — Post format. #### Example ```console $ solari instagram content batch post_ids='["019f505f-f8be-7e88-ae08-6fba999950b1","019f5060-3449-779e-a08b-d6d49add90cd"]' ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "id": "019f505f-f8be-7e88-ae08-6fba999950b1", "slug": "Dam_BYyJxtR", "text": "#광고 ₊✩‧₊˚ @innisfreeofficial ˚₊✩‧₊ \n공들인 나의 화장.. 찜통 더위에 무너져 내릴때\n이니스프리 노세범 선 파우더 하나면 고민 끝!\n\n유분 가득한 피부.. 꺼진 부위, 모공, 요철 부각되어\n10년은 늙어보이는 몰골에서 노세범 선 파우더 바르는\n즉시 핑크빛 필터를 씌운 듯~ 뽀용 피부 완성 ⭒˚.⋆\n\n노세범 맛집 답게 과다 피지와 유분을 즉각 흡착시키고\n무엇보다 가벼 …", "posted_at": "2026-07-10T10:34:01Z", "virtual_campaign": null, "username": "the_ketchap", "user_id": "018d3b53-c0c1-71cc-a44f-204f7d850267", "profile_picture_url": null, "like_count": 38579, "comment_count": 31, "thumbnail_url": null, "media_url": null, "media": [], "media_type": "reel", "play_count": 676825, "account_id": "018d3b53-c0c1-71cc-a44f-204f7d850267" }, "… 1 more" ], "requested": 2, "found": 2 } ``` #### As an MCP call ```json { "name": "solari_instagram_content_batch", "arguments": { "post_ids": [ "019f505f-f8be-7e88-ae08-6fba999950b1", "019f5060-3449-779e-a08b-d6d49add90cd" ] } } ``` #### Notes - Takes SOLARI post UUIDs only. Instagram shortcodes do not belong here — those go to content detail as slug. - sort=engagement orders by like + comment instead of recency. #### Related tools - [`solari_instagram_content_detail`](https://solari.sh/docs/tools/instagram-content-detail.md) - [`solari_instagram_brand_overview`](https://solari.sh/docs/tools/instagram-brand-overview.md) ### solari instagram content search > Keyword search across captions, creator bios, and video transcriptions. - **CLI**: `solari instagram content search` - **MCP tool**: `solari_instagram_content_search` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Lexical keyword search over tracked posts: matches captions, creator bios, and video transcription text (Korean-aware analysis plus n-gram partial matching), ranked by relevance with match highlights. Each item carries post_id, author account_id/username, caption, transcription text, engagement counts, and score — feed post_id into solari_instagram_content_detail or solari_instagram_content_batch and the account reference into the account tools. Coverage: only regions KR, JP, US, and TW are searchable, holding roughly the most recent 6 months of posts; total is exact up to 10,000 and saturates there. Narrow with since/until (UTC dates). Works with any signed-in SOLARI account. **When to use it** — Finding posts by topic or phrasing. When the answer is a count, use content aggregate instead. **What comes back** — Relevance-ranked hits with match highlights. #### Parameters - `query` (string, required) — Free-text keyword query matched against captions, creator bios, and video transcriptions. - `region` (enum, optional, default "KR") — Region to search. Only these four regions are indexed. Values: `KR`, `JP`, `US`, `TW`. - `limit` (integer, optional, ≥ 1) — Maximum hits, default 20. Values above 100 are clamped to 100. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. Data older than ~6 months is not indexed. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. #### Response ##### `Response` - `query / region` (string) — The query and region applied. - `total` (integer) — Total matches. Exact up to 10,000, then saturates. - `took_ms` (integer) — Search time. - `items` (object[]) — Hits, score descending. ##### `items[]` - `post_id` (uuid) — SOLARI post id. - `slug` (string) — Instagram shortcode. - `account_id / author_id / username` (string) — Authoring account. account_id is the current name. - `caption` (string) — Caption text. - `user_bio` (string) — Author bio — part of the searched text. - `transcription_text` (string | null) — Video speech transcription. - `posted_at` (timestamp) — Publication time (UTC). - `like_count / comment_count` (integer) — Engagement snapshot. - `follower_count` (integer) — Author follower count. - `score` (number) — Relevance score. Comparable only within this response. - `highlight` (object) — Matched fragments per field: caption, user_bio, transcription_text. - `is_video` (boolean) — Whether the post is a video. #### Example ```console $ solari instagram content search query="이니스프리 그린티" limit=3 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "query": "이니스프리 그린티", "region": "KR", "total": 10000, "took_ms": 1586, "items": [ { "post_id": "019f12d8-3e72-78e9-b7e5-39293bc56f23", "author_id": "019f12d8-3e0f-7c74-afc6-e14405bd1523", "username": "hanydiary", "caption": "[이니스프리에디터 4기 1-2 : 그린티 PDRN 아이&립 세럼] #이니스프리 #그린티PDRN 💚 자세한 포스팅은 프로필 링크 참고해주세요 :)", "user_bio": "대외활동 | 휴학생 | 취준일기 🪽과 학생회 2년 연임 🪽이니스프리 대학생 에디터 3기 / 4기", "transcription_text": null, "posted_at": "2026-02-16T05:44:45Z", "like_count": 3, "comment_count": 3, "follower_count": 972, "score": 140.43787, "slug": "DUzrl1UkoJb", "highlight": { "caption": [ "[이니스프리에디터 4기 1-2 : 그린티 PDRN 아이&립 세럼] #이니스프리 #그린티PDRN 💚 자세한 포스팅은 프로필 링크 참고해주세요 :)" ], "user_bio": [ "대외활동 | 휴학생 | 취준일기 🪽과 학생회 2년 연임 🪽이니스프리 대학생 에디터 3기 / 4기" ], "transcription_text": [] }, "is_video": false, "media_url": null, "thumbnail_url": null, "account_id": "019f12d8-3e0f-7c74-afc6-e14405bd1523" }, "… 2 more" ] } ``` #### As an MCP call ```json { "name": "solari_instagram_content_search", "arguments": { "query": "이니스프리 그린티", "limit": 3 } } ``` #### Notes - The index covers KR, JP, US, and TW only, holding roughly the most recent 6 months. A since older than that returns nothing. - total is exact up to 10,000 and stops there. - Korean-aware analysis is combined with n-gram partial matching. #### Related tools - [`solari_instagram_content_aggregate`](https://solari.sh/docs/tools/instagram-content-aggregate.md) - [`solari_instagram_content_batch`](https://solari.sh/docs/tools/instagram-content-batch.md) - [`solari_tiktok_content_search`](https://solari.sh/docs/tools/tiktok-content-search.md) ### solari instagram content trending > Instagram posts trending right now in a region. - **CLI**: `solari instagram content trending` - **MCP tool**: `solari_instagram_content_trending` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Instagram posts currently trending in the region, enriched with creator profile fields. Supports cursor pagination via next_cursor from the previous response. Optionally personalizes ranking with a brand account_id or username. Works with any signed-in SOLARI account. Use solari_instagram_content_rising for velocity-led accelerating posts instead. **When to use it** — "What's working at the moment?" For velocity rather than volume, use content rising. **What comes back** — Trending posts enriched with author profile fields, paged by cursor. #### Parameters - `region` (string, optional, default "KR") — Region code such as KR, JP, or US. - `limit` (integer, optional, ≥ 1) — Maximum posts per page, default 20. Values above 50 are clamped to 50. - `cursor` (string, optional) — Opaque pagination cursor from the previous response's next_cursor. - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Optional brand account_id (SOLARI account UUID) for brand-affinity personalization. - `username` (string, optional, ≤ 64 chars) — Optional brand Instagram handle for brand-affinity personalization. Ignored when account_id is set. #### Response ##### `Response` - `items` (object[]) — Trending posts. - `total_count` (integer) — Size of the feed. - `region` (string) — Region applied. - `content_type` (string) — Feed kind tag. - `next_cursor` (string | null) — Pass this back as cursor for the next page. ##### `items[]` - `post_id` (uuid) — SOLARI post id. Feed it straight into the other content tools. - `slug` (string) — Instagram shortcode — the segment after /p/ or /reel/ in a public URL. - `author_id` (uuid) — account_id of the authoring account. - `username` (string) — Author handle. - `full_name` (string | null) — Profile display name. - `profile_pic_url` (string | null) — Profile picture URL. - `follower_count` (integer | null) — Author follower count at snapshot time. - `region` (string | null) — Region code assigned to the author. - `posted_at` (timestamp) — Publication time (UTC). - `media_type` (string) — image, video, or carousel. - `play_count` (integer | null) — Video plays. null for image posts. - `like_count` (integer | null) — Likes at snapshot time. - `text` (string | null) — Caption text. - `media_url` (string) — Original media URL. - `thumbnail_url` (string) — Thumbnail URL. - `score` (number | null) — Feed ranking score. Comparable only within one response. - `efficiency_score` (number | null) — Performance relative to the author's follower count. - `est_percentile` (number | null) — Estimated percentile within the region, 0–1. - `total_views_3m` (integer | null) — Author's cumulative views over the last 3 months. - `median_views_3m` (integer | null) — Author's median views over the last 3 months. - `recent_collab_brands` (string[]) — Brands the author has collaborated with recently. - `item_type` (string) — Item kind tag; post in the content feeds. - `content_source` (string | null) — Which pipeline surfaced this item. - `is_saved` (boolean | null) — Whether the item is saved in the SOLARI app. - `updated_at` (timestamp | null) — When the metric snapshot was last refreshed. #### Example ```console $ solari instagram content trending region=KR limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "item_type": "content", "post_id": "01a055fe-d72c-7005-8709-eef67b4be6f0", "author_id": "018ecc27-f8e7-7100-9339-bb050ea44a7f", "username": "sixpackpiggy", "full_name": "Jinmin Park", "profile_pic_url": "https://dcr.bzine.co/instagram/users/sixpackpiggy/profile-picture", "follower_count": 93442, "region": "KR", "posted_at": "2026-08-29T02:02:20Z", "media_type": "video", "play_count": 286749, "like_count": null, "score": 96.69330916066565, "efficiency_score": null, "est_percentile": 96.69330916066565, "updated_at": "2026-09-03T04:51:42.797111Z", "media_url": "https://smr-images-b.bzine.co/users/018ecc27-f8e7-7100-9339-bb050ea44a7f/posts/01a055fe-d72c-7005-8709-eef67b4be6f0/medias/01a055fe-d964-7d73-9a77-d06823a2abc2.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images.bzine.co/users/018ecc27-f8e7-7100-9339-bb050ea44a7f/posts/01a055fe-d72c-7005-8709-eef67b4be6f0/medias/01a055fe-d964-7d73-9a77-d06823a2abc2.m …", "slug": "Dcmzs05SAae", "text": "How dedicated are you to your Korean skincare? 💅@patinaosaka \n#koreanskincare #osaka #japan #kbeauty #traveling", "brand_match_score": null, "recent_collab_brands": [], "total_views_3m": 1875678, "median_views_3m": 57780, "is_saved": false, "content_source": null }, "… 1 more" ], "total_count": 213635, "region": "KR", "content_type": "trending", "next_cursor": "eyJhcyI6ICIyMDI2LTA5LTAzVDA1OjIwOjIzLjM4Mzk3NCswMDowMCIsICJzYyI6ICIyMDI2LTA5LTAzVDA0OjQ0OjQ3LjkzNTI1OCswMDowMCIsICJzcCI6ICIwMWEwNTVmZS1mOWIyLTdiNmYtYjY1OS05ZGE1OTM3NjgzMWMifQ==" } ``` #### As an MCP call ```json { "name": "solari_instagram_content_trending", "arguments": { "region": "KR", "limit": 2 } } ``` #### Notes - Supplying a brand account_id or handle personalises the ranking by brand affinity. - Pagination is by cursor, not offset — feed next_cursor into the next call. #### Related tools - [`solari_instagram_content_rising`](https://solari.sh/docs/tools/instagram-content-rising.md) - [`solari_instagram_content_trend_clusters`](https://solari.sh/docs/tools/instagram-content-trend-clusters.md) ### solari instagram content rising > Instagram posts accelerating faster than their baseline. - **CLI**: `solari instagram content rising` - **MCP tool**: `solari_instagram_content_rising` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Instagram posts whose recent performance is accelerating faster than baseline in the region. Same shape as solari_instagram_content_trending including cursor pagination and optional brand personalization via a brand account_id or username. Works with any signed-in SOLARI account. **When to use it** — When momentum matters more than absolute numbers — catching posts before they peak. **What comes back** — Same shape as content trending; only the ranking differs. #### Parameters - `region` (string, optional, default "KR") — Region code such as KR, JP, or US. - `limit` (integer, optional, ≥ 1) — Maximum posts per page, default 20. Values above 50 are clamped to 50. - `cursor` (string, optional) — Opaque pagination cursor from the previous response's next_cursor. - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Optional brand account_id (SOLARI account UUID) for brand-affinity personalization. - `username` (string, optional, ≤ 64 chars) — Optional brand Instagram handle for brand-affinity personalization. Ignored when account_id is set. #### Response ##### `Response` - `items` (object[]) — Rising posts. - `total_count` (integer) — Size of the feed. - `region` (string) — Region applied. - `content_type` (string) — Feed kind tag. - `next_cursor` (string | null) — Pass this back as cursor for the next page. ##### `items[]` - `post_id` (uuid) — SOLARI post id. Feed it straight into the other content tools. - `slug` (string) — Instagram shortcode — the segment after /p/ or /reel/ in a public URL. - `author_id` (uuid) — account_id of the authoring account. - `username` (string) — Author handle. - `full_name` (string | null) — Profile display name. - `profile_pic_url` (string | null) — Profile picture URL. - `follower_count` (integer | null) — Author follower count at snapshot time. - `region` (string | null) — Region code assigned to the author. - `posted_at` (timestamp) — Publication time (UTC). - `media_type` (string) — image, video, or carousel. - `play_count` (integer | null) — Video plays. null for image posts. - `like_count` (integer | null) — Likes at snapshot time. - `text` (string | null) — Caption text. - `media_url` (string) — Original media URL. - `thumbnail_url` (string) — Thumbnail URL. - `score` (number | null) — Feed ranking score. Comparable only within one response. - `efficiency_score` (number | null) — Performance relative to the author's follower count. - `est_percentile` (number | null) — Estimated percentile within the region, 0–1. - `total_views_3m` (integer | null) — Author's cumulative views over the last 3 months. - `median_views_3m` (integer | null) — Author's median views over the last 3 months. - `recent_collab_brands` (string[]) — Brands the author has collaborated with recently. - `item_type` (string) — Item kind tag; post in the content feeds. - `content_source` (string | null) — Which pipeline surfaced this item. - `is_saved` (boolean | null) — Whether the item is saved in the SOLARI app. - `updated_at` (timestamp | null) — When the metric snapshot was last refreshed. #### Example ```console $ solari instagram content rising region=KR limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "items": [ { "item_type": "content", "post_id": "01a0495a-4e46-73d5-a111-a818248b665b", "author_id": "019e4a24-ee85-78e9-8763-602930999853", "username": "iiiwantkitty", "full_name": "주 령", "profile_pic_url": "https://dcr.bzine.co/instagram/users/iiiwantkitty/profile-picture", "follower_count": 706, "region": "KR", "posted_at": "2026-08-28T07:38:46Z", "media_type": "video", "play_count": 48092, "like_count": null, "score": 0.1292899036795201, "efficiency_score": 0.1292899036795201, "est_percentile": 84.68488691008565, "updated_at": "2026-09-03T05:20:45.496271Z", "media_url": "https://smr-images-b.bzine.co/users/019e4a24-ee85-78e9-8763-602930999853/posts/01a0495a-4e46-73d5-a111-a818248b665b/medias/01a0495a-4fc0-7352-92dd-a04afe898589.mp4", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=0ms/https://smr-images-a.bzine.co/users/019e4a24-ee85-78e9-8763-602930999853/posts/01a0495a-4e46-73d5-a111-a818248b665b/medias/01a0495a-4fc0-7352-92dd-a04afe898589 …", "slug": "Dck0Wj8xeq3", "text": "이정도가 아니면 뮤트라고 하지말자..⭐️ 뮤트톤 친구 입술에 빡빡 발라주고싶음\n\n컬러 보자마자 아 내꺼하자ㅡㅡ 하고 바로 겟한 것\n\n그레이애쉬,, 핑크 ,, 브라운 다 들어간 밑힌 컬러 이거 뮤트톤들이 바르면 진짜 분위기 미처버리는 립이걸랑 영상보다 실물이 더 뮤트!\n\n입술에 올리면 좀더 투명하게 올라가면서 회끼도는데 뉴트럴하면서도 팥앙금 같은 고런 깔 느낌\n안쪽에만 톡톡 발라서 쌩얼립으로도 …", "brand_match_score": null, "recent_collab_brands": [ "apieu_cosmetics", "… 8 more" ], "total_views_3m": 2389749, "median_views_3m": 5215, "is_saved": false, "content_source": null }, "… 1 more" ], "total_count": 291665, "region": "KR", "content_type": "rising", "next_cursor": "eyJhcyI6ICIyMDI2LTA5LTAzVDA1OjIwOjQ5LjA3Mjg3MiswMDowMCIsICJzYyI6ICIyMDI2LTA5LTAzVDA1OjE5OjQwLjc1NzUwOCswMDowMCIsICJzcCI6ICIwMWEwNDNmOC1hODdlLTdiMWItYjFiNi1iODliMTU2YjU0ODgifQ==" } ``` #### As an MCP call ```json { "name": "solari_instagram_content_rising", "arguments": { "region": "KR", "limit": 2 } } ``` #### Notes - Parameters and response match content trending, brand personalisation included. #### Related tools - [`solari_instagram_content_trending`](https://solari.sh/docs/tools/instagram-content-trending.md) - [`solari_instagram_content_trend_clusters`](https://solari.sh/docs/tools/instagram-content-trend-clusters.md) ### solari instagram content trend clusters > The SOLARI trend digest — recent content grouped into named themes. - **CLI**: `solari instagram content trend clusters` - **MCP tool**: `solari_instagram_content_trend_clusters` - **Access**: `solari:read` — Works with any signed-in SOLARI account. The SOLARI trend digest: recent content trend clusters for a region with cluster metadata and member posts, optionally reranked by brand affinity when a brand account_id or username is supplied. Works with any signed-in SOLARI account. **When to use it** — Reading the shape of the moment rather than individual posts. **What comes back** — Named clusters with size, movement, and member post previews. #### Parameters - `region` (string, optional, default "KR") — Region code such as KR, JP, or US. - `since_days` (integer, optional, default 7, 1–90) — Lookback window in days for trending clusters, between 1 and 90. - `limit` (integer, optional, ≥ 1) — Maximum trend clusters returned, default 20. Values above 24 are clamped to 24. - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — Optional brand account_id (SOLARI account UUID) for brand-affinity reranking. - `username` (string, optional, ≤ 64 chars) — Optional brand Instagram handle for brand-affinity reranking. Ignored when account_id is set. - `brand_aware` (boolean, optional, default true) — Rerank clusters by brand affinity when account_id is provided. #### Response ##### `Response` - `success` (boolean) — Whether the digest was generated. - `trend_count` (integer) — Clusters returned. - `header_text` (string) — Digest headline. - `region / since_days` (string · integer) — Region and lookback applied. - `brand_aware` (boolean) — Whether brand-affinity reranking was requested. - `als_applied` (boolean) — Whether the affinity model actually ran. - `trends` (object[]) — The clusters. ##### `trends[]` - `cluster_id` (string) — Cluster id. - `name` (string) — Cluster name. - `bullets` (string[]) — Sentences describing the cluster. - `count` (integer) — Member posts. - `count_delta` (integer) — Change in member posts vs. the previous period. - `growth_pct` (number) — Growth rate, percent. - `avg_play_delta` (number) — Change in average plays. - `distinct_creators` (integer) — Creators contributing to the cluster. - `creator_delta` (integer) — Change in creator count. - `is_new` (boolean) — Whether the cluster first appeared this period. - `member_thumbnails` (object[]) — Thumbnail previews of member posts. #### Example ```console $ solari instagram content trend clusters region=KR since_days=7 limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "success": true, "trend_count": 2, "header_text": "최근 7일 인기 트렌드 2개 (브랜드 컨텍스트 없음)", "brand_aware": true, "als_applied": false, "region": "KR", "since_days": 7, "directive": null, "trends": [ { "cluster_id": "01a05857-7727-74d8-8da5-4e95981aca8d", "name": "GV90의 미래형 하이테크 기능", "bullets": [ "화면이 회전하거나 시트가 뒤로 돌아가는 등 물리적으로 변형되는 자동차 내부 장치들을 직접 시연함", "… 1 more" ], "count": 7, "count_delta": 0, "growth_pct": 0, "avg_play_delta": 0, "creator_delta": 0, "distinct_creators": 3, "is_new": false, "early_zone_creator_count": null, "early_zone_creator_ratio": null, "als_member_count": null, "mean_als_score": null, "annotation": null, "group": null, "member_thumbnails": [ { "post_id": "01a030df-c4b3-739c-9214-44b3b9463c7b", "thumbnail_url": "https://bzine.co/cdn-cgi/media/width=480,mode=frame,time=100ms/https://smr-images-c.bzine.co/users/018cb4c9-da89-7b02-8efd-53ccb65c26c9/posts/01a030df-c4b3-739c-9214-44b3b9463c7b/medias/01a030df-c7c3-788e-8775-1096728e07 …", "slug": "DcP6jgRMTRv", "username": "sol.bpd", "media_url": "https://smr-images-c.bzine.co/users/018cb4c9-da89-7b02-8efd-53ccb65c26c9/posts/01a030df-c4b3-739c-9214-44b3b9463c7b/medias/01a030df-c7c3-788e-8775-1096728e07f2.mp4", "media_type": "video", "play_count": 1947419, "posted_at": "2026-08-20T04:37:17+00:00" }, "… 3 more" ] }, "… 1 more" ], "insights": null, "insight_query": null } ``` #### As an MCP call ```json { "name": "solari_instagram_content_trend_clusters", "arguments": { "region": "KR", "since_days": 7, "limit": 2 } } ``` #### Notes - A heavy call — the gateway allows it 120 seconds. - since_days runs 1–90; limit is clamped at 24. - Supplying a brand turns on brand_aware reranking. Set brand_aware=false to keep the raw ordering. #### Related tools - [`solari_instagram_content_trending`](https://solari.sh/docs/tools/instagram-content-trending.md) - [`solari_instagram_content_rising`](https://solari.sh/docs/tools/instagram-content-rising.md) ### solari instagram content aggregate > Count posts instead of listing them — by account, format, hashtag, mention, or keyword. - **CLI**: `solari instagram content aggregate` - **MCP tool**: `solari_instagram_content_aggregate` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Counts and engagement rollups over tracked posts, for questions answered by numbers rather than by individual posts: posts per account per month, which hashtags dominate a topic, average likes by format. Group by account, post_type, hashtag, mention, caption_keyword, or transcription_keyword, and optionally split each group by day, week, or month. post_count always comes back; request metrics for like/comment/view sums and averages, mean follower count, and distinct account counts. Narrow the set with a free-text query, usernames, hashtags, mentions, or post_types. Filtering by mentions and grouping by account answers which accounts tagged a given handle. Coverage: regions KR, JP, US, and TW, holding roughly the most recent 6 months — a since older than that is clamped and the applied value is echoed back. Buckets are largest-first; truncated=true means more groups existed than limit returned. Use solari_instagram_content_search when the posts themselves are needed instead of counts. Works with any signed-in SOLARI account. **When to use it** — Numeric questions: posts per account per month, which hashtags dominate a topic, average likes by format. **What comes back** — Per-group counts and engagement rollups, largest group first. #### Parameters - `region` (enum, optional, default "KR") — Region to aggregate. Only these four regions are indexed. Values: `KR`, `JP`, `US`, `TW`. - `group_by` (enum, optional) — Dimension to group by. Omit to aggregate the whole filtered set into a single total bucket. Values: `account`, `post_type`, `hashtag`, `mention`, `caption_keyword`, `transcription_keyword`. - `interval` (enum, optional) — Calendar interval to split by. Alone it returns one bucket per period; combined with group_by each group carries a series. Values: `day`, `week`, `month`. - `metrics` (string[], optional) — Extra metrics beyond post_count, which is always returned. Metric values are snapshots and can lag live counts. Values: `like_sum`, `like_avg`, `comment_sum`, `comment_avg`, `view_sum`, `view_avg`, `follower_avg`, `account_count`. - `query` (string, optional) — Free-text filter matched against captions, creator bios, and video transcriptions. - `usernames` (string[], optional) — Restrict to these Instagram handles. - `hashtags` (string[], optional) — Restrict to posts carrying every one of these hashtags. - `mentions` (string[], optional) — Restrict to posts that tag every one of these handles. Pair with group_by=account to rank the accounts tagging a given handle. - `post_types` (string[], optional) — Restrict to these post formats. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. Defaults to 183 days ago, which is also the earliest accepted bound. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. - `limit` (integer, optional, ≥ 1) — Maximum groups returned when group_by is set, default 20. Values above 50 are clamped to 50. #### Response ##### `Response` - `region` (string) — Region the aggregation ran over. - `since` (date) — Start date actually applied. A request older than the retention window is clamped and echoed back here. - `until` (date | null) — End date actually applied. - `group_by` (string | null) — Grouping dimension applied. - `interval` (string | null) — Calendar interval applied. - `total_posts` (integer) — Posts matching the filters. Can differ from the sum of bucket counts when groups overlap. - `truncated` (boolean) — true when more groups existed than limit returned. - `buckets` (object[]) — One entry per group, largest first. ##### `buckets[]` - `key` (string) — The group value — handle, hashtag, format, and so on. A single total bucket when group_by is omitted. - `metrics.post_count` (integer) — Post count. Always returned. - `metrics.like_sum / like_avg` (number | null) — Like total and mean. Only when requested via metrics. - `metrics.comment_sum / comment_avg` (number | null) — Comment total and mean. - `metrics.view_sum / view_avg` (number | null) — View total and mean. - `metrics.share_sum / collect_sum` (number | null) — TikTok-only metrics; always null on Instagram. - `metrics.follower_avg` (number | null) — Mean follower count of the authoring accounts. - `metrics.account_count` (integer | null) — Distinct accounts in the group. - `series` (object[] | null) — Per-period breakdown, present when interval is set. #### Example ```console $ solari instagram content aggregate group_by=hashtag query="이니스프리" metrics='["like_avg","view_sum","account_count"]' limit=5 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "region": "KR", "since": "2026-03-04", "until": null, "group_by": "hashtag", "interval": null, "total_posts": 1647, "truncated": true, "buckets": [ { "key": "이니스프리", "metrics": { "post_count": 772, "like_sum": null, "like_avg": 320.7240932642487, "comment_sum": null, "comment_avg": null, "view_sum": 9400953, "view_avg": null, "share_sum": null, "share_avg": null, "collect_sum": null, "collect_avg": null, "follower_avg": null, "account_count": 587 }, "series": null }, { "key": "광고", "metrics": { "post_count": 548, "like_sum": null, "like_avg": 373.04021937842776, "comment_sum": null, "comment_avg": null, "view_sum": 5463711, "view_avg": null, "share_sum": null, "share_avg": null, "collect_sum": null, "collect_avg": null, "follower_avg": null, "account_count": 381 }, "series": null }, "… 3 more" ] } ``` #### As an MCP call ```json { "name": "solari_instagram_content_aggregate", "arguments": { "group_by": "hashtag", "query": "이니스프리", "metrics": [ "like_avg", "view_sum", "account_count" ], "limit": 5 } } ``` #### Notes - post_count always comes back. Everything else is null unless named in metrics. - Filtering by mentions and grouping by account answers "which accounts tagged this handle?". - The index covers KR, JP, US, and TW over roughly the most recent 6 months. since defaults to — and bottoms out at — 183 days ago; an older value is clamped and the applied value is echoed back. - interval alone returns one bucket per period; combined with group_by, each group carries a series. - When the posts themselves are the answer, use content search. #### Related tools - [`solari_instagram_content_search`](https://solari.sh/docs/tools/instagram-content-search.md) - [`solari_tiktok_content_aggregate`](https://solari.sh/docs/tools/tiktok-content-aggregate.md) ### solari instagram tag search > Every post carrying one exact hashtag or @mention. - **CLI**: `solari instagram tag search` - **MCP tool**: `solari_instagram_tag_search` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Every tracked post carrying one exact tag — '#ootd' for a hashtag, '@handle' for mentions of an account — hydrated into full rows, newest-collected first with cursor pagination. Exact whole-tag matching over the entire tracked history and every region, where solari_instagram_content_search does free-text over four regions and about six months. Works with any signed-in SOLARI account. **When to use it** — Measuring a campaign hashtag's real reach, or finding every post that mentioned an account. Exact whole-tag matching over the full tracked history — content search is the tool for keywords found anywhere in text, but it only reaches four regions and about six months. **What comes back** — Hydrated posts carrying the tag, newest collected first, with a cursor for the next page. #### Parameters - `query` (string, required, ≤ 200 chars) — One exact tag. '#ootd' or 'ootd' searches a hashtag; '@oliveyoung_official' searches mentions of that account. No spaces, no wildcards. - `limit` (integer, optional, ≥ 1) — Posts per page, default 20. Values above 1000 are clamped to 1000. Larger pages cost no more than smaller ones. - `cursor` (string, optional) — next_cursor from the previous response. Omit for the first page. #### Response ##### `Response` - `query` (string) — The tag the lookup actually ran on, without its leading # or @. - `tag_kind` (string) — hashtag or mention — how the query was read. - `matched_tags` (integer) — How many stored tag spellings the query matched. Above 1 is normal: a mention matches both the handle and the account's numeric id, and a Hangul hashtag matches both of its Unicode spellings. 0 means the tag has never been seen. - `items` (object[]) — The posts found. - `found` (integer) — Posts that hydrated. Lower than the page size when a post was deleted after the tag index was last refreshed. - `next_cursor` (string | null) — Pass back as cursor for the next page. null on the last page. - `mirror_synced_at` (timestamp | null) — When the tag index was last refreshed (UTC). Posts published after this may not carry their tags yet. ##### `items[]` - `id` (uuid) — Post id. - `slug` (string) — Instagram shortcode. - `text` (string) — Caption text. - `posted_at` (timestamp) — Publication time (UTC). - `username / user_id / account_id` (string) — Authoring account. account_id is the current name. - `like_count / comment_count` (integer) — Engagement snapshot. - `play_count` (integer | null) — Video plays. - `media_type` (string) — Post format. #### Example ```console $ solari instagram tag search query=#ootd limit=3 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "query": "ootd", "tag_kind": "hashtag", "matched_tags": 1, "items": [ { "id": "01a06a16-781f-7578-822b-1c326e72f28d", "slug": "DW1jniHiVSU", "text": "御殿場是一個一天逛不完的地方 希望下次有時間可以慢慢逛 —— OOTD —— Pants:LAKOLE / Shirt:HARE #LYNN__OOTD #日常穿搭 #ootd …", "posted_at": "2026-04-07T16:16:21Z", "virtual_campaign": null, "username": "llling_yinnnnn", "user_id": "019dbc46-1a67-7ef5-b95a-2fb466790d04", "account_id": "019dbc46-1a67-7ef5-b95a-2fb466790d04", "profile_picture_url": null, "like_count": 3, "comment_count": 4, "media_type": "post", "play_count": null, "media": [] }, { "id": "01a06a16-552d-7099-ae0a-77e6b68de960", "slug": "DaS66VzJBPW", "text": "SEOUL OOTD — 這次搭配了四種完全不同風格 #ootd #lynn__ootd #穿搭販賣機 #韓國穿搭", "posted_at": "2026-07-02T15:33:13Z", "virtual_campaign": null, "username": "llling_yinnnnn", "user_id": "019dbc46-1a67-7ef5-b95a-2fb466790d04", "account_id": "019dbc46-1a67-7ef5-b95a-2fb466790d04", "profile_picture_url": null, "like_count": 32, "comment_count": 1, "media_type": "reel", "play_count": 888, "media": [] }, "… 1 more" ], "found": 3, "next_cursor": "01a06a16-552d-7099-ae0a-77e6b68de960", "mirror_synced_at": "2026-09-03T21:47:19Z" } ``` #### As an MCP call ```json { "name": "solari_instagram_tag_search", "arguments": { "query": "#ootd", "limit": 3 } } ``` #### Notes - Order is collection recency, not publication date — a single account's posts are collected in one burst, so consecutive items often share an author and their posted_at values jump around. Sort by posted_at yourself when publication order matters. - The tag index is rebuilt once a day, so posts from the last several hours may not carry their tags yet. mirror_synced_at gives the exact cutoff. Captions and engagement counts are always live. - Every page costs the same to compute no matter how large, so ask for one page of 1000 rather than twenty pages of 50. - Matching is exact and whole-tag. '#ootd' will not match '#ootdkorea', and there are no wildcards. - Prefix with @ to search mentions of an account: 'query=@oliveyoung_official'. #### Related tools - [`solari_instagram_content_search`](https://solari.sh/docs/tools/instagram-content-search.md) - [`solari_instagram_content_aggregate`](https://solari.sh/docs/tools/instagram-content-aggregate.md) ### solari tiktok account search > Turn a brand or creator name into a TikTok account_id. - **CLI**: `solari tiktok account search` - **MCP tool**: `solari_tiktok_account_search` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Resolves a brand/creator name or TikTok handle to candidate tracked TikTok accounts via fast deterministic index search, typeahead-style: matches handles by prefix and display nicknames by text match, ranked by match quality and follower count. Returns found plus items ordered best-first (items[0] is the top match), each with account_id (the SOLARI account UUID the other solari_tiktok_* tools take; a TikTok account_id is a different value from any Instagram account_id and the two are never interchangeable), username (the TikTok handle), nickname, follower_count, video_count, region, is_verified, is_private, is_commerce_user, commerce_user_category, and profile_url; found=false with empty items means nothing matched. The query must actually appear in the handle or nickname, so retry with the native spelling when a phonetic alias does not resolve. Leave region unset unless the user asked for one country: many tracked TikTok accounts carry no region, and a region filter drops them. A handle that is not tracked yet does not appear here; pass it straight to solari_tiktok_account_profile or solari_tiktok_account_posts, which fetch it live. Works with any signed-in SOLARI account. **When to use it** — The first call for any TikTok question. An Instagram account_id will not work here. **What comes back** — Candidate accounts ordered best-first; items[0] is the top match. #### Parameters - `query` (string, required) — Brand or creator name or TikTok handle to resolve. - `limit` (integer, optional, ≥ 1) — Maximum candidates to return, default 8. Values above 50 are clamped to 50. - `region` (string, optional, ≤ 8 chars) — Optional region code such as KR, JP, or US. Leave unset unless the user asked for one country: accounts with no known region are dropped when a region is set. #### Response ##### `Response` - `found` (boolean) — true when at least one candidate matched. - `items` (object[]) — Candidates. ##### `items[]` - `account_id` (uuid) — TikTok account_id. Never interchangeable with an Instagram account_id, even for the same brand. - `username` (string) — TikTok handle. - `nickname` (string) — Display name. - `follower_count / video_count` (integer) — Followers and videos. - `region` (string | null) — Region code. Many tracked accounts carry none. - `is_verified / is_private` (boolean) — Verification and privacy flags. - `is_commerce_user` (boolean) — Whether this is a commerce account. - `commerce_user_category` (string | null) — Commerce category, e.g. Beauty. - `profile_url` (string) — Public profile URL. #### Example ```console $ solari tiktok account search query=innisfree limit=5 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "found": true, "items": [ { "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "nickname": "Innisfreeofficial", "follower_count": 143800, "video_count": 767, "region": "KR", "is_verified": true, "is_private": false, "is_commerce_user": true, "commerce_user_category": "Beauty", "profile_url": "https://www.tiktok.com/@innisfree_official" } ] } ``` #### As an MCP call ```json { "name": "solari_tiktok_account_search", "arguments": { "query": "innisfree", "limit": 5 } } ``` #### Notes - Leave region unset unless the user asked for one country. Many tracked accounts have no region, and setting one drops them entirely. - An untracked handle does not appear here. Pass it straight to tiktok account profile or tiktok account posts, which fetch it live. #### Related tools - [`solari_tiktok_account_profile`](https://solari.sh/docs/tools/tiktok-account-profile.md) - [`solari_tiktok_account_posts`](https://solari.sh/docs/tools/tiktok-account-posts.md) - [`solari_instagram_account_search`](https://solari.sh/docs/tools/instagram-account-search.md) ### solari tiktok account profile > Everything SOLARI knows about one TikTok account. - **CLI**: `solari tiktok account profile` - **MCP tool**: `solari_tiktok_account_profile` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Full SOLARI profile for one TikTok account: username (the handle), nickname, bio, follower/following/like/video counts, region, verified/private/commerce flags, profile_url, plus embedded previews of recent posts (recent_posts). Identify the account by account_id (TikTok account UUID from solari_tiktok_account_search) or by username (TikTok handle). A handle not tracked yet is fetched live on first request (allow 10 to 40 seconds; fetched_on_demand=true in the response, and only its most recent posts are available until the background crawl lands); a not-found error then means the handle does not exist on TikTok. Works with any signed-in SOLARI account. **When to use it** — The first call of a TikTok account deep-dive. Recent posts come embedded. **What comes back** — Profile fields, recent post previews, and the tracking state. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the TikTok account (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — TikTok handle, with or without a leading @. Ignored when account_id is set. #### Response ##### `Response` - `account_id` (uuid) — TikTok account_id. - `username / nickname / bio` (string) — Handle, display name, bio text. - `bio_links` (string[]) — Links in the bio. - `follower_count / following_count` (integer) — Followers and following. - `heart_count` (integer) — Lifetime likes across the account. - `video_count` (integer) — Videos published. - `is_verified / is_private` (boolean) — Verification and privacy flags. - `is_commerce_user / commerce_user_category` (boolean · string) — Commerce status and category. - `region / language` (string | null) — Region and language codes. - `avatar_url / profile_url` (string) — Avatar and public profile link. - `tracked` (boolean) — Whether the account is on the regular crawl. - `sync_status` (string) — Crawl state. - `synced_at` (timestamp) — Last crawl time. - `recent_posts` (object[]) — Recent post previews. - `fetched_on_demand` (boolean) — true when this request is what first pulled the account in. ##### `recent_posts[]` - `post_id` (uuid) — SOLARI post id. A different namespace from Instagram post ids. - `video_id` (string) — Public numeric TikTok id — the digits after /video/ or /photo/. - `url` (string) — Public TikTok permalink. - `account_id` (uuid) — TikTok account_id of the author. - `username` (string) — Author handle. - `post_type` (string) — video (single clip) or carousel (image slideshow). - `posted_at` (timestamp) — Publication time (UTC). - `caption` (string) — Caption text. - `duration_seconds` (integer) — Video length. - `width / height` (integer) — Video resolution. - `play_count` (integer) — Plays. - `like_count` (integer) — Likes. - `comment_count` (integer) — Comments. - `share_count` (integer) — Shares. - `collect_count` (integer) — Saves. - `is_ad` (boolean) — Whether TikTok flags the post as an ad. - `is_pinned` (boolean) — Pinned to the top of the profile. - `aigc_label_type` (string | null) — AI-generated-content label, when TikTok applies one. - `original_language_code` (string | null) — Source language code. - `cover_url` (string) — Cover image URL. - `video_url` (string) — Video file URL. - `images` (string[]) — Carousel slides. Empty for a video post. - `hashtags` (string[]) — Hashtags parsed from the caption. - `mentions` (string[]) — Handles mentioned in the caption. - `transcript` (string | null) — Spoken-word transcript. Only filled when include_transcript=true. #### Example ```console $ solari tiktok account profile username=innisfree_official ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "nickname": "Innisfreeofficial", "bio": "NATURE MEETS KOREAN SKIN SCIENCE", "bio_links": [ "https://linktr.ee/innisfree_official" ], "follower_count": 143900, "following_count": 14, "heart_count": 2200000, "video_count": 767, "is_verified": true, "is_private": false, "is_commerce_user": true, "commerce_user_category": "Beauty", "region": "KR", "language": null, "avatar_url": "https://p16-common-sign.tiktokcdn-eu.com/tos-alisg-avt-0068/3f8e48dc4a284a8ead37e93175ebdb86~tplv-tiktokx-cropcenter:720:720.jpeg?dr=10399&refresh_token=04b90255&x-expires=1788541200&x-signature=Gd3gJu4HyBZPCr%2FqEevyDs6 …", "profile_url": "https://www.tiktok.com/@innisfree_official", "sync_status": "OK", "tracked": true, "synced_at": "2026-09-02T17:16:05.835000Z", "recent_posts": [ { "post_id": "01a0631e-f0df-7e9d-a09b-d84bc31d3834", "video_id": "7680375687139642645", "url": "https://www.tiktok.com/@innisfree_official/video/7680375687139642645", "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "post_type": "video", "posted_at": "2026-09-02T12:00:00Z", "caption": "Deeply hydrated skin—NO OFF HOURS. 💚 wherever the day takes MINGYU—his hydration stays SUPERCHARGED ⚡️ Green Tea Ceramide Milk: Lightweight milky toner that won't clog your pores Green Tea Ceramide Mist: Touch-free, fa …", "duration_seconds": 23, "width": 1080, "height": 1920, "play_count": 493, "like_count": 37, "comment_count": 2, "share_count": 0, "collect_count": 3, "is_ad": false, "is_pinned": false, "aigc_label_type": null, "original_language_code": null, "cover_url": "https://smr-images-a.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/cover.jpg", "video_url": "https://smr-images-a.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/origin.mp4", "images": [], "hashtags": [], "mentions": [], "transcript": null }, "… 5 more" ], "fetched_on_demand": false } ``` #### As an MCP call ```json { "name": "solari_tiktok_account_profile", "arguments": { "username": "innisfree_official" } } ``` #### Notes - An untracked handle is fetched live on first request. Allow 10 to 40 seconds; fetched_on_demand=true marks it, and only the most recent posts exist until the background crawl lands. - A not-found error after that means the handle does not exist on TikTok. #### Related tools - [`solari_tiktok_account_posts`](https://solari.sh/docs/tools/tiktok-account-posts.md) - [`solari_tiktok_account_search`](https://solari.sh/docs/tools/tiktok-account-search.md) - [`solari_instagram_account_profile`](https://solari.sh/docs/tools/instagram-account-profile.md) ### solari tiktok account posts > Page through one TikTok account's posts, newest first. - **CLI**: `solari tiktok account posts` - **MCP tool**: `solari_tiktok_account_posts` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Posts by one TikTok account, newest first, with pagination and filters. Identify the account by account_id (TikTok account UUID from solari_tiktok_account_search) or by username (TikTok handle). Each item has post_id (SOLARI post UUID), video_id (the public numeric TikTok id) and url, post_type (video or carousel), posted_at, caption, duration_seconds, play/like/comment/share/collect counts, is_ad, cover_url, images (carousel slides), hashtags, mentions, and transcript when include_transcript=true. Transcripts are long, so include_transcript is off by default; turn it on only when the spoken content matters. The response carries found, account_id, username, total, has_more, and items; page with limit and offset, narrow with since/until (UTC dates, inclusive) and post_type. A handle not tracked yet is fetched live on first request (allow 10 to 40 seconds), and fetched_on_demand=true marks that only its most recent posts are available until the background crawl lands; found=false means the handle does not exist on TikTok. Works with any signed-in SOLARI account. **When to use it** — Going deeper than the profile preview, or narrowing by date range and format. **What comes back** — Posts, optionally with spoken-word transcripts. #### Parameters - `account_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — account_id of the TikTok account (SOLARI account UUID). Provide this or username. - `username` (string, optional, ≤ 64 chars) — TikTok handle, with or without a leading @. Ignored when account_id is set. - `limit` (integer, optional, ≥ 1) — Posts per page, default 12. Values above 200 are clamped to 200. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. - `post_type` (enum, optional) — Only posts of this format. video is a single clip; carousel is an image slideshow. Values: `video`, `carousel`. - `include_transcript` (boolean, optional, default false) — Attach the spoken-word transcript to each item. Off by default because transcripts are long. #### Response ##### `Response` - `found` (boolean) — false means the handle does not exist on TikTok. - `account_id / username` (string) — The resolved account. - `total` (integer) — Posts matching the filters. - `has_more` (boolean) — Whether another page exists. - `items` (object[]) — Posts, newest first. - `fetched_on_demand` (boolean) — true when only the most recent posts are available so far. ##### `items[]` - `post_id` (uuid) — SOLARI post id. A different namespace from Instagram post ids. - `video_id` (string) — Public numeric TikTok id — the digits after /video/ or /photo/. - `url` (string) — Public TikTok permalink. - `account_id` (uuid) — TikTok account_id of the author. - `username` (string) — Author handle. - `post_type` (string) — video (single clip) or carousel (image slideshow). - `posted_at` (timestamp) — Publication time (UTC). - `caption` (string) — Caption text. - `duration_seconds` (integer) — Video length. - `width / height` (integer) — Video resolution. - `play_count` (integer) — Plays. - `like_count` (integer) — Likes. - `comment_count` (integer) — Comments. - `share_count` (integer) — Shares. - `collect_count` (integer) — Saves. - `is_ad` (boolean) — Whether TikTok flags the post as an ad. - `is_pinned` (boolean) — Pinned to the top of the profile. - `aigc_label_type` (string | null) — AI-generated-content label, when TikTok applies one. - `original_language_code` (string | null) — Source language code. - `cover_url` (string) — Cover image URL. - `video_url` (string) — Video file URL. - `images` (string[]) — Carousel slides. Empty for a video post. - `hashtags` (string[]) — Hashtags parsed from the caption. - `mentions` (string[]) — Handles mentioned in the caption. - `transcript` (string | null) — Spoken-word transcript. Only filled when include_transcript=true. #### Example ```console $ solari tiktok account posts username=innisfree_official limit=2 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "found": true, "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "total": 87, "has_more": true, "items": [ { "post_id": "01a0631e-f0df-7e9d-a09b-d84bc31d3834", "video_id": "7680375687139642645", "url": "https://www.tiktok.com/@innisfree_official/video/7680375687139642645", "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "post_type": "video", "posted_at": "2026-09-02T12:00:00Z", "caption": "Deeply hydrated skin—NO OFF HOURS. 💚 wherever the day takes MINGYU—his hydration stays SUPERCHARGED ⚡️ Green Tea Ceramide Milk: Lightweight milky toner that won't clog your pores Green Tea Ceramide Mist: Touch-free, fa …", "duration_seconds": 23, "width": 1080, "height": 1920, "play_count": 493, "like_count": 37, "comment_count": 2, "share_count": 0, "collect_count": 3, "is_ad": false, "is_pinned": false, "aigc_label_type": null, "original_language_code": null, "cover_url": "https://smr-images-b.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/cover.jpg", "video_url": "https://smr-images-a.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/origin.mp4", "images": [], "hashtags": [], "mentions": [], "transcript": null }, "… 1 more" ], "fetched_on_demand": false } ``` #### As an MCP call ```json { "name": "solari_tiktok_account_posts", "arguments": { "username": "innisfree_official", "limit": 2 } } ``` #### Notes - Transcripts are long, so include_transcript is off by default. Turn it on only when the spoken content matters. - Up to 200 per page. #### Related tools - [`solari_tiktok_account_profile`](https://solari.sh/docs/tools/tiktok-account-profile.md) - [`solari_tiktok_content_detail`](https://solari.sh/docs/tools/tiktok-content-detail.md) - [`solari_instagram_account_posts`](https://solari.sh/docs/tools/instagram-account-posts.md) ### solari tiktok content detail > One TikTok post in full. - **CLI**: `solari tiktok content detail` - **MCP tool**: `solari_tiktok_content_detail` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Detail for one TikTok post, in the same item shape as solari_tiktok_account_posts entries (transcript included when one exists). Identify the post by post_id (SOLARI post UUID from solari_tiktok_account_posts, solari_tiktok_content_search, or solari_tiktok_account_profile), by video_id (the public numeric TikTok video id), or by url (any public TikTok post URL, including vm.tiktok.com and vt.tiktok.com short links, which are resolved upstream). A video_id or url not tracked yet is fetched live on first request (allow 10 to 40 seconds) and fetched_on_demand=true marks that case; item is null when the post does not exist or is not public, or when a post_id is unknown. Works with any signed-in SOLARI account. **When to use it** — Opening a single post by post_id, video_id, or public URL. **What comes back** — One item in the account-posts shape, transcript included when one exists. #### Parameters - `post_id` (string, optional, uuid, pattern ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$) — The SOLARI post_id UUID. Provide this, video_id, or url. - `video_id` (string, optional, pattern ^\d{15,20}$) — Public numeric TikTok video id, the digits after /video/ or /photo/ in a post URL. Ignored when post_id is set. - `url` (string, optional, ≤ 512 chars) — Public TikTok post URL such as https://www.tiktok.com/@/video/ or a vm.tiktok.com / vt.tiktok.com short link. Ignored when post_id or video_id is set. #### Response ##### `Response` - `item` (object | null) — The post. null when it does not exist or is not public. - `fetched_on_demand` (boolean) — true when this request is what first pulled the post in. ##### `item` - `post_id` (uuid) — SOLARI post id. A different namespace from Instagram post ids. - `video_id` (string) — Public numeric TikTok id — the digits after /video/ or /photo/. - `url` (string) — Public TikTok permalink. - `account_id` (uuid) — TikTok account_id of the author. - `username` (string) — Author handle. - `post_type` (string) — video (single clip) or carousel (image slideshow). - `posted_at` (timestamp) — Publication time (UTC). - `caption` (string) — Caption text. - `duration_seconds` (integer) — Video length. - `width / height` (integer) — Video resolution. - `play_count` (integer) — Plays. - `like_count` (integer) — Likes. - `comment_count` (integer) — Comments. - `share_count` (integer) — Shares. - `collect_count` (integer) — Saves. - `is_ad` (boolean) — Whether TikTok flags the post as an ad. - `is_pinned` (boolean) — Pinned to the top of the profile. - `aigc_label_type` (string | null) — AI-generated-content label, when TikTok applies one. - `original_language_code` (string | null) — Source language code. - `cover_url` (string) — Cover image URL. - `video_url` (string) — Video file URL. - `images` (string[]) — Carousel slides. Empty for a video post. - `hashtags` (string[]) — Hashtags parsed from the caption. - `mentions` (string[]) — Handles mentioned in the caption. - `transcript` (string | null) — Spoken-word transcript. Only filled when include_transcript=true. #### Example ```console $ solari tiktok content detail video_id=7680375687139642645 include_transcript=true ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "item": { "post_id": "01a0631e-f0df-7e9d-a09b-d84bc31d3834", "video_id": "7680375687139642645", "url": "https://www.tiktok.com/@innisfree_official/video/7680375687139642645", "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "post_type": "video", "posted_at": "2026-09-02T12:00:00Z", "caption": "Deeply hydrated skin—NO OFF HOURS. 💚 wherever the day takes MINGYU—his hydration stays SUPERCHARGED ⚡️ Green Tea Ceramide Milk: Lightweight milky toner that won't clog your pores Green Tea Ceramide Mist: Touch-free, fa …", "duration_seconds": 23, "width": 1080, "height": 1920, "play_count": 493, "like_count": 37, "comment_count": 2, "share_count": 0, "collect_count": 3, "is_ad": false, "is_pinned": false, "aigc_label_type": null, "original_language_code": null, "cover_url": "https://smr-images-b.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/cover.jpg", "video_url": "https://smr-images-c.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/origin.mp4", "images": [], "hashtags": [], "mentions": [], "transcript": null }, "fetched_on_demand": false } ``` #### As an MCP call ```json { "name": "solari_tiktok_content_detail", "arguments": { "video_id": "7680375687139642645" } } ``` #### Notes - vm.tiktok.com and vt.tiktok.com short links are accepted and resolved upstream. - An untracked video_id or URL is fetched live on first request — allow 10 to 40 seconds. #### Related tools - [`solari_tiktok_content_batch`](https://solari.sh/docs/tools/tiktok-content-batch.md) - [`solari_tiktok_account_posts`](https://solari.sh/docs/tools/tiktok-account-posts.md) ### solari tiktok content batch > Hydrate up to 100 TikTok post ids in one call. - **CLI**: `solari tiktok content batch` - **MCP tool**: `solari_tiktok_content_batch` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Batch companion to solari_tiktok_content_detail: hydrates up to 100 TikTok posts by their SOLARI post UUIDs in a single call, in the same item shape as solari_tiktok_account_posts entries. Untracked ids are omitted, so found can be lower than requested. Transcripts are long, so include_transcript is off by default. Feed it post_id lists from solari_tiktok_account_posts, solari_tiktok_content_search, or solari_tiktok_account_profile; TikTok post_ids are separate from Instagram post_ids. Works with any signed-in SOLARI account. **When to use it** — Opening an id list from search or account posts all at once. **What comes back** — The posts that were found among the requested ids. #### Parameters - `post_ids` (uuid[], required, 1–100 items, uuid) — SOLARI post UUIDs to hydrate, at most 100 per call. Not TikTok video ids. - `sort` (enum, optional, default "recent") — Item order: posted_at descending (recent) or engagement descending. Values: `recent`, `engagement`. - `include_transcript` (boolean, optional, default false) — Attach the spoken-word transcript to each item. Off by default because transcripts are long. #### Response ##### `Response` - `requested` (integer) — How many ids were sent. - `found` (integer) — How many resolved. - `items` (object[]) — The posts found. ##### `items[]` - `post_id` (uuid) — SOLARI post id. A different namespace from Instagram post ids. - `video_id` (string) — Public numeric TikTok id — the digits after /video/ or /photo/. - `url` (string) — Public TikTok permalink. - `account_id` (uuid) — TikTok account_id of the author. - `username` (string) — Author handle. - `post_type` (string) — video (single clip) or carousel (image slideshow). - `posted_at` (timestamp) — Publication time (UTC). - `caption` (string) — Caption text. - `duration_seconds` (integer) — Video length. - `width / height` (integer) — Video resolution. - `play_count` (integer) — Plays. - `like_count` (integer) — Likes. - `comment_count` (integer) — Comments. - `share_count` (integer) — Shares. - `collect_count` (integer) — Saves. - `is_ad` (boolean) — Whether TikTok flags the post as an ad. - `is_pinned` (boolean) — Pinned to the top of the profile. - `aigc_label_type` (string | null) — AI-generated-content label, when TikTok applies one. - `original_language_code` (string | null) — Source language code. - `cover_url` (string) — Cover image URL. - `video_url` (string) — Video file URL. - `images` (string[]) — Carousel slides. Empty for a video post. - `hashtags` (string[]) — Hashtags parsed from the caption. - `mentions` (string[]) — Handles mentioned in the caption. - `transcript` (string | null) — Spoken-word transcript. Only filled when include_transcript=true. #### Example ```console $ solari tiktok content batch post_ids='["01a0631e-f0df-7e9d-a09b-d84bc31d3834"]' ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "requested": 1, "found": 1, "items": [ { "post_id": "01a0631e-f0df-7e9d-a09b-d84bc31d3834", "video_id": "7680375687139642645", "url": "https://www.tiktok.com/@innisfree_official/video/7680375687139642645", "account_id": "019b2137-f76e-7b33-9437-26044fa7b1ed", "username": "innisfree_official", "post_type": "video", "posted_at": "2026-09-02T12:00:00Z", "caption": "Deeply hydrated skin—NO OFF HOURS. 💚 wherever the day takes MINGYU—his hydration stays SUPERCHARGED ⚡️ Green Tea Ceramide Milk: Lightweight milky toner that won't clog your pores Green Tea Ceramide Mist: Touch-free, fa …", "duration_seconds": 23, "width": 1080, "height": 1920, "play_count": 493, "like_count": 37, "comment_count": 2, "share_count": 0, "collect_count": 3, "is_ad": false, "is_pinned": false, "aigc_label_type": null, "original_language_code": null, "cover_url": "https://smr-images-b.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/cover.jpg", "video_url": "https://smr-images-b.bzine.co/tiktok/users/019b2137-f76e-7b33-9437-26044fa7b1ed/posts/01a0631e-f0df-7e9d-a09b-d84bc31d3834/medias/origin.mp4", "images": [], "hashtags": [], "mentions": [], "transcript": null } ] } ``` #### As an MCP call ```json { "name": "solari_tiktok_content_batch", "arguments": { "post_ids": [ "01a0631e-f0df-7e9d-a09b-d84bc31d3834" ] } } ``` #### Notes - Takes SOLARI post UUIDs only. A numeric TikTok video id does not belong here — that goes to content detail as video_id. - TikTok post ids and Instagram post ids are separate namespaces. #### Related tools - [`solari_tiktok_content_detail`](https://solari.sh/docs/tools/tiktok-content-detail.md) - [`solari_tiktok_content_search`](https://solari.sh/docs/tools/tiktok-content-search.md) ### solari tiktok content search > Keyword search across TikTok captions and video transcripts. - **CLI**: `solari tiktok content search` - **MCP tool**: `solari_tiktok_content_search` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Lexical keyword search over tracked TikTok posts: matches captions and video transcripts (Korean-aware analysis plus n-gram partial matching), ranked by relevance with match highlights. Each item carries post_id, video_id, url, author account_id/username, caption, transcription_text, post_type, posted_at, play/like/comment/share/collect counts, follower_count, duration_seconds, is_ad, cover_url, score, and highlight; feed post_id into solari_tiktok_content_detail or solari_tiktok_content_batch and the account reference into the solari_tiktok_account_* tools. Coverage: only regions KR, JP, US, and TW are searchable, holding roughly the most recent 6 months of posts; total is exact up to 10,000 and saturates there. Narrow with since/until (UTC dates). Works with any signed-in SOLARI account. **When to use it** — Finding TikTok posts by topic or by what is actually said on screen. **What comes back** — Relevance-ranked hits with highlights and transcript text. #### Parameters - `query` (string, required) — Free-text keyword query matched against captions and video transcripts. - `region` (enum, optional, default "KR") — Region to search. Only these four regions are indexed. Values: `KR`, `JP`, `US`, `TW`. - `limit` (integer, optional, ≥ 1) — Maximum hits, default 20. Values above 100 are clamped to 100. - `offset` (integer, optional, default 0, ≥ 0) — Pagination offset, default 0. Values above 9800 are clamped to 9800. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. Data older than ~6 months is not indexed. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. #### Response ##### `Response` - `query / region` (string) — The query and region applied. - `total` (integer) — Total matches. Exact up to 10,000, then saturates. - `took_ms` (integer) — Search time. - `items` (object[]) — Hits, score descending. ##### `items[]` - `post_id / video_id / url` (string) — Post identifiers and public link. - `account_id / username` (string) — Authoring account. - `caption` (string) — Caption text. - `user_bio` (string) — Author bio. - `transcription_text` (string | null) — Speech transcript — part of the searched text. - `transcription_language` (string | null) — Transcript language code. - `post_type` (string) — video or carousel. - `posted_at` (timestamp) — Publication time (UTC). - `duration_seconds` (integer) — Video length. - `play_count / like_count / comment_count / share_count / collect_count` (integer) — Engagement snapshot. - `follower_count` (integer) — Author follower count. - `is_ad` (boolean) — TikTok's own ad flag. - `cover_url` (string) — Cover image. - `score` (number) — Relevance score. - `highlight` (object) — Matched fragments per field. #### Example ```console $ solari tiktok content search query="올리브영 세일" limit=3 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "query": "올리브영 세일", "region": "KR", "total": 4041, "took_ms": 29, "items": [ { "post_id": "01a05c46-9a08-7e92-a40e-b1a039103118", "video_id": "7679484556189207815", "url": "https://www.tiktok.com/@flos_bonita/video/7679484556189207815", "account_id": "0196cb39-87a7-7be3-ac4a-4a80b7818a90", "username": "flos_bonita", "caption": "태닝한 산리오 키링이라니…☀️🥹💗 푸드올로지 X 산리오 콜라보 실물 너무 귀엽잖아!! 헬로키티·쿠로미·한교동·마이멜로디까지🎀 제품마다 다른 키링이라 산리오 덕후들 취향 제대로 저격💘 올영 세일 시작했으니 얼른 구경해봐요👀🛒 #푸드올로지 #태닝키티 #올리브영추천템 #올영세일", "user_bio": "화미 프로필 링크", "transcription_text": "살리오 덕후라면 절대 그냥 넘길 수 없는 영상 오늘부터 시작인 올리브영 세일과 함께 푸드올로지와 살리오 콜라보 나왔어요 이번 콜라보는 젤리 폼 앰플 젤리 3 종으로 피디아렌 앰플 젤리 글루타치원 씨 앰플 젤리 히알루론산 앰플 젤리까지 제품마다 귀여운 살리오 굿즈도 함께 만나 볼 수 있는데 헬로키티 크로미 한교동부터 마이 멜로디까지 저는 역시 헬로키티 더 쿠답게 키티 키링으로 폼구 최애 캐릭터 …", "transcription_language": "ko", "post_type": "video", "posted_at": "2026-08-29T16:02:22Z", "duration_seconds": 37, "play_count": 955, "like_count": 26, "comment_count": 0, "share_count": 0, "collect_count": 5, "follower_count": 1345, "is_ad": true, "cover_url": "https://p16-common-sign.tiktokcdn-eu.com/tos-alisg-p-0037/oEu4VAolaEBAAYjMAjBtiyCIAABiPp9TOCAME~tplv-tiktokx-origin.image?dr=10395&x-expires=1788426000&x-signature=FAP0C10M1M1gEwD4YMB03pYd0YA%3D&t=4d5b0474&ps=13740610&sh …", "score": 53.787056, "highlight": { "caption": [ "헬로키티·쿠로미·한교동·마이멜로디까지🎀 제품마다 다른 키링이라 산리오 덕후들 취향 제대로 저격💘 올 세일 시작했으니 얼른 구경해봐요👀🛒 #푸드올로지 #태닝키티 #올리브영추천템 #올영세일" ], "user_bio": [], "transcription_text": [ "살리오 덕후라면 절대 그냥 넘길 수 없는 영상 오늘부터 시작인 올리브 세일과 함께 푸드올로지와 살리오 콜라보 나왔어요 이번 콜라보는 젤리 폼 앰플 젤리 3 종으로 피디아렌 앰플 젤리 글루타치원 씨 앰플 젤리 히알루론산 앰플 젤리까지 제품마다 귀여운 살리오 굿즈도 함께", "… 1 more" ] } }, "… 2 more" ] } ``` #### As an MCP call ```json { "name": "solari_tiktok_content_search", "arguments": { "query": "올리브영 세일", "limit": 3 } } ``` #### Notes - The index covers KR, JP, US, and TW over roughly the most recent 6 months. - offset is clamped at 9,800. To go deeper, narrow the date range and search again. - total is exact up to 10,000 and stops there. #### Related tools - [`solari_tiktok_content_aggregate`](https://solari.sh/docs/tools/tiktok-content-aggregate.md) - [`solari_tiktok_content_batch`](https://solari.sh/docs/tools/tiktok-content-batch.md) - [`solari_instagram_content_search`](https://solari.sh/docs/tools/instagram-content-search.md) ### solari tiktok content aggregate > Count TikTok posts instead of listing them. - **CLI**: `solari tiktok content aggregate` - **MCP tool**: `solari_tiktok_content_aggregate` - **Access**: `solari:read` — Works with any signed-in SOLARI account. Counts and engagement rollups over tracked TikTok posts, for questions answered by numbers rather than by individual posts: posts per account per month, which hashtags dominate a topic, average plays by format. Group by account, post_type, hashtag, mention, or caption_keyword, and optionally split each group by day, week, or month. post_count always comes back; request metrics for like/comment/view/share/collect sums and averages (the view_* metrics count plays), mean follower count, and distinct account counts. Narrow the set with a free-text query (captions and video transcripts), usernames, hashtags, mentions, or post_types (video, carousel). Filtering by mentions and grouping by account answers which accounts tagged a given handle. Coverage: regions KR, JP, US, and TW, holding roughly the most recent 6 months; a since older than that is clamped and the applied value is echoed back. Buckets are largest-first; truncated=true means more groups existed than limit returned. Use solari_tiktok_content_search when the posts themselves are needed instead of counts. Works with any signed-in SOLARI account. **When to use it** — Numeric questions: upload cadence per account, hashtag distribution in a topic, average plays by format. **What comes back** — Per-group counts and engagement rollups, largest group first. #### Parameters - `region` (enum, optional, default "KR") — Region to aggregate. Only these four regions are indexed. Values: `KR`, `JP`, `US`, `TW`. - `group_by` (enum, optional) — Dimension to group by. Omit to aggregate the whole filtered set into a single total bucket. Values: `account`, `post_type`, `hashtag`, `mention`, `caption_keyword`. - `interval` (enum, optional) — Calendar interval to split by. Alone it returns one bucket per period; combined with group_by each group carries a series. Values: `day`, `week`, `month`. - `metrics` (string[], optional) — Extra metrics beyond post_count, which is always returned. view_* metrics count plays. Metric values are snapshots and can lag live counts. Values: `like_sum`, `like_avg`, `comment_sum`, `comment_avg`, `view_sum`, `view_avg`, `share_sum`, `share_avg`, `collect_sum`, `collect_avg`, `follower_avg`, `account_count`. - `query` (string, optional) — Free-text filter matched against captions and video transcripts. - `usernames` (string[], optional) — Restrict to these TikTok handles. - `hashtags` (string[], optional) — Restrict to posts carrying every one of these hashtags. - `mentions` (string[], optional) — Restrict to posts that tag every one of these handles. Pair with group_by=account to rank the accounts tagging a given handle. - `post_types` (string[], optional) — Restrict to these post formats. Values: `video`, `carousel`. - `since` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or after this UTC date, YYYY-MM-DD inclusive. Defaults to 183 days ago, which is also the earliest accepted bound. - `until` (string, optional, pattern ^\d{4}-\d{2}-\d{2}$) — Only posts on or before this UTC date, YYYY-MM-DD inclusive. - `limit` (integer, optional, ≥ 1) — Maximum groups returned when group_by is set, default 20. Values above 50 are clamped to 50. #### Response ##### `Response` - `region` (string) — Region the aggregation ran over. - `since` (date) — Start date actually applied. A request older than the retention window is clamped and echoed back here. - `until` (date | null) — End date actually applied. - `group_by` (string | null) — Grouping dimension applied. - `interval` (string | null) — Calendar interval applied. - `total_posts` (integer) — Posts matching the filters. Can differ from the sum of bucket counts when groups overlap. - `truncated` (boolean) — true when more groups existed than limit returned. - `buckets` (object[]) — One entry per group, largest first. ##### `buckets[]` - `key` (string) — The group value — handle, hashtag, format, and so on. A single total bucket when group_by is omitted. - `metrics.post_count` (integer) — Post count. Always returned. - `metrics.like_sum / like_avg` (number | null) — Like total and mean. Only when requested via metrics. - `metrics.comment_sum / comment_avg` (number | null) — Comment total and mean. - `metrics.view_sum / view_avg` (number | null) — Play total and mean. - `metrics.share_sum / collect_sum` (number | null) — Share and save totals, with matching _avg variants. - `metrics.follower_avg` (number | null) — Mean follower count of the authoring accounts. - `metrics.account_count` (integer | null) — Distinct accounts in the group. - `series` (object[] | null) — Per-period breakdown, present when interval is set. #### Example ```console $ solari tiktok content aggregate group_by=account query="이니스프리" metrics='["view_sum","like_avg","account_count"]' limit=5 ``` _Long strings and repeated array entries are trimmed for readability._ ```json { "region": "KR", "since": "2026-03-04", "until": null, "group_by": "account", "interval": null, "total_posts": 20, "truncated": true, "buckets": [ { "key": "merryview_", "metrics": { "post_count": 2, "like_sum": null, "like_avg": 2378.5, "comment_sum": null, "comment_avg": null, "view_sum": 179504, "view_avg": null, "share_sum": null, "share_avg": null, "collect_sum": null, "collect_avg": null, "follower_avg": null, "account_count": 1 }, "series": null }, { "key": "_kimdayun_", "metrics": { "post_count": 1, "like_sum": null, "like_avg": 1829, "comment_sum": null, "comment_avg": null, "view_sum": 102000, "view_avg": null, "share_sum": null, "share_avg": null, "collect_sum": null, "collect_avg": null, "follower_avg": null, "account_count": 1 }, "series": null }, "… 3 more" ] } ``` #### As an MCP call ```json { "name": "solari_tiktok_content_aggregate", "arguments": { "group_by": "account", "query": "이니스프리", "metrics": [ "view_sum", "like_avg", "account_count" ], "limit": 5 } } ``` #### Notes - The view_* metrics count plays. - Unlike the Instagram version, share_* and collect_* are actually populated, and there is no transcription_keyword grouping. - The index covers KR, JP, US, and TW over roughly the most recent 6 months. since bottoms out at 183 days ago; an older value is clamped and echoed back. #### Related tools - [`solari_tiktok_content_search`](https://solari.sh/docs/tools/tiktok-content-search.md) - [`solari_instagram_content_aggregate`](https://solari.sh/docs/tools/instagram-content-aggregate.md)