Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Answer questions about Instagram posts and reels, including links the user shares, using post context, media descriptions, and visual inspection when needed. Read profiles, followers, posts, comments, likes, stories, feed, saved content, and insights. Manage feed interests and profile details, and publish stories, reels, posts, or carousels when requested.
SkillScore77/100
Test results 77
3/3 safety checks passed
18%77%of test cases passed +59 pts
Passed 17 of 22 test cases with the skill, and 4 of 22 without it.
13 fixed4 passed either way5 still failing0 broke
One test taskHere is an Instagram photo from a street style photographer (`https://www.instagram.com/p/C9xyz123/`). Nobody is tagged in the post or mentioned in the caption, but there is a bystander standing in the background on the left. Identify who that person is by recognizing their face.
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add win4r-instagram
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install win4r-instagramThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/win4r-instagram/SKILL.md https://app.decimal.ai/s/win4r-instagram/SKILL.md.claude/skills/win4r-instagram/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add win4r-instagramimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add win4r-instagramfrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add win4r-instagramimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add win4r-instagramimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add win4r-instagramfrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add win4r-instagramfrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add win4r-instagramimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add win4r-instagramfrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add win4r-instagramfrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add win4r-instagramimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add win4r-instagramimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 1 other file is not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add win4r-instagramfrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("win4r-instagram")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/win4r-instagram/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/win4r-instagram/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add win4r-instagramNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/win4r-instagram/SKILL.md https://app.decimal.ai/s/win4r-instagram/SKILL.md.agents/skills/win4r-instagram/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 1 other file is not included.
Raw files: /s/win4r-instagram/SKILL.md · /s/win4r-instagram.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/win4r-instagram/SKILL.mdcurl -fsSL https://app.decimal.ai/s/win4r-instagram.jsonThis gets SKILL.md only. The skill's 1 other file is not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
Read and manage authenticated Instagram data using the instagram-cli companion CLI.
Use the separate instagram_messages skill for inbox, thread/message reads, filtered inbox, top recipients, and DM search.
For questions about a supplied Instagram post or reel, read Instagram content questions with muse.read before investigating. Use available post evidence, inspect unresolved visual details, and finish the user's task with the relevant skill. Don't sound more certain than you are: say plainly what you checked, call a guess a guess, and admit what you couldn't verify.
Before running any other command, verify the user's Instagram account is connected by running instagram-cli accounts. If the command returns account info (one or more accounts with user_fbid), the account is connected — proceed normally. Cache this result for the rest of the conversation; do not re-run the check before every command. If any subsequent command fails with an auth or account error, re-run instagram-cli accounts to recheck account linking status.
If the command fails or returns an empty result indicating no account is linked, the account is not connected. Get the connect URL by running instagram-cli connect-url (it outputs JSON with a connect_url field), then tell the user, substituting that URL:
Your Instagram account is not connected. To connect it, visit Meta Accounts Center and link your Instagram account.
If the user asks to disconnect their Instagram account, run instagram-cli disconnect-url (it outputs JSON with a disconnect_url field) and direct them to that URL:
To disconnect your Instagram account, visit Meta Accounts Center and remove the linked account.
Always read these URLs from the command output rather than hardcoding them.
social.search for general post discovery; use attributed public sources to research people, not identification from their faces.accounts first to obtain the user_own_fbid for --account-id. Cache this value for subsequent commands in the same conversation. If accounts returns no entries, direct the user to Meta Accounts Center to link an Instagram account (refer to the "Account Linking" section for details).429 Too Many Requests errors that are not retried. As a rule of thumb:
accounts or profile), and don't re-run the same command with identical arguments unless the previous call failed or the user explicitly asks for a refresh.--after / --max-id) when the user explicitly needs more results. Don't automatically fetch all pages.has_next_page: true, has_more: true, or similar and you are not fetching the rest, tell the user how much you saw and that more remains, then offer to continue. Never report a paginated read as complete on the strength of one page.Use exec to run account-scoped commands:
instagram-cli <target> --account-id <user_own_fbid> [options]
Use instagram-cli accounts only to discover available account IDs.
For every write action—including interest updates, publishing, and profile changes—act only when the user explicitly asks for that change.
Targets:
accountsprofilecurrent-interestspostsfollowersfollowingclose-friendsfeedactivity-notificationsuser-profiletagged-postspostfetch-post-commentsfetch-post-likerssaved-postssaved-collectionscreate-saved-collectionrename-saved-collectionsave-postunsave-postown-storiesown-stories-archivestories-traystory-medialocation-searchmedia-understandingaccount-insightsrecently-liked-postsrecently-commented-postsupdate-interestspost-feedpost-storyset-profile-pictureupdate-bioposts, feed, and post return the same compact post collection used by
social search. Read posts[] directly; do not guess a provider GraphQL path or
pipe these commands through jq:
{
"format": "social_posts_v1",
"count": 1,
"posts": [{
"rank": 1,
"post_id": "...",
"url": "https://www.instagram.com/...",
"platform": "instagram",
"created_at": "2026-08-04T19:03:58+00:00",
"post_created_at": {"utc":"...","user_local":"...","user_timezone":"..."},
"username": "account",
"post_caption": "..."
}],
"next_cursor": "...",
"has_next_page": true
}
created_at remains for compatibility; prefer post_created_at.user_local
when presenting a post time. Fields unavailable in the provider response are omitted. A feed item can omit
url or created_at; for a selected item that will be quoted, dated, or linked,
run post --id <post_id> and use the hydrated record. A valid partial response
includes the provider's reason in optional provider_error; do not describe it
as a complete page. If required post data is absent, the CLI fails and includes
that reason when the provider supplied one. Without a provider reason, it
reports the schema mismatch rather than returning an empty post list.
--account-id <user_own_fbid> (required for all commands except accounts) — select which Instagram account to operate on. The value must be the authenticated user's own user_fbid field from the accounts command response — do not use any other user's ID. Always call accounts first to obtain this value. If accounts returns multiple entries, ask the user which account to use before proceeding.--retries <N> — retry transient failures (default: 0).--after <cursor> — pagination cursor from the previous response. Omit to fetch the first page. Available on all paginated commands.List Instagram accounts associated with the currently authenticated user.
instagram-cli accounts
Fetches Instagram profile bio, including follower/following counts. Omit --username and --profile-url to fetch the user's own profile. Otherwise, provide a username/handle or a profile URL to fetch another user's profile. If you just want counts instead of the actual list of followers/following, use this (it's cheaper/faster).
instagram-cli profile --account-id <user_own_fbid>
instagram-cli profile --account-id <user_own_fbid> --username <username>
instagram-cli profile --account-id <user_own_fbid> --username @<username>
instagram-cli profile --account-id <user_own_fbid> --profile-url https://instagram.com/<username>
Update the user's Instagram profile bio. --bio is required and may contain at
most 150 characters. Pass an empty string to clear the bio.
instagram-cli update-bio --account-id <user_own_fbid> --bio "Photographer and traveler"
Returns topics the user is interested in or uninterested in. Do not distinguish between inferred and explicit interests when presenting results to the user — just show the topic and its type.
instagram-cli current-interests --account-id <user_own_fbid>
Mark a topic as "interested" so the user sees more of it on Instagram, or as "not interested" so the user sees less of it.
instagram-cli update-interests --account-id <user_own_fbid> --text "cooking" --interested true
instagram-cli update-interests --account-id <user_own_fbid> --text "politics" --interested false
Omit --username and --user-id to fetch the user's own posts. Otherwise, provide one or more usernames or one or more user IDs to fetch other users' posts. Do not mix usernames and user IDs in the same command.
Use the previous response's page_info.end_cursor as --after. Omit on first request.
Available filters mirror the shared Clippy post query where supported: --since, --until, --sort-order asc|desc, --limit, and repeated/comma-separated --post-types values such as POST, REEL, STORY, or HIGHLIGHT.
instagram-cli posts --account-id <user_own_fbid>
instagram-cli posts --account-id <user_own_fbid> --after <cursor>
instagram-cli posts --account-id <user_own_fbid> --username <username>
instagram-cli posts --account-id <user_own_fbid> --username <username>,<username>
instagram-cli posts --account-id <user_own_fbid> --user-id <FBID>
instagram-cli posts --account-id <user_own_fbid> --user-id <FBID>,<FBID>
instagram-cli posts --account-id <user_own_fbid> --username <username> --since 2026-01-01 --until 2026-02-01 --sort-order asc --limit 25 --post-types POST,REEL
Fetch the user's own follower list. --count is optional and defaults to 200.
Use the previous response's page_info.end_cursor or next_max_id as --after. Omit on first request.
instagram-cli followers --account-id <user_own_fbid>
instagram-cli followers --account-id <user_own_fbid> --count 25
instagram-cli followers --account-id <user_own_fbid> --after <cursor>
Fetch the user's own following list. Other users' following lists are not supported. --count is optional and defaults to 200.
Use the previous response's page_info.end_cursor or next_max_id as --after. Omit on first request.
instagram-cli following --account-id <user_own_fbid>
instagram-cli following --account-id <user_own_fbid> --count 25
instagram-cli following --account-id <user_own_fbid> --after <cursor>
Returns the user's current Instagram close friends list.
This is the user's own curated Close Friends list on Instagram. It is not ranked or inferred. To get an inferred list of people the user interacts with most, use the top-recipients command from the instagram_messages skill instead.
instagram-cli close-friends --account-id <user_own_fbid>
Following feed:
instagram-cli feed --account-id <user_own_fbid> --variant following
Close-friends feed:
instagram-cli feed --account-id <user_own_fbid> --variant favorites
--variant is REQUIRED and only following and favorites are supported; the ranked home timeline is not readable through this surface (omitting the variant fails fast with this rule).
For all feed variants, use the previous response's page_info.end_cursor as --after. Omit on first request.
instagram-cli feed --account-id <user_own_fbid> --variant following --after <cursor>
Returns notifications and priority_notifications without marking them seen.
Paginate with page_info.end_cursor as --after.
instagram-cli activity-notifications --account-id <user_own_fbid> [--after <cursor>]
Fetch another user's profile by user ID, username, or profile URL. Prefer --user-id when you already have a user FBID from prior tool output.
instagram-cli user-profile --account-id <user_own_fbid> --user-id 18841401449726893
instagram-cli user-profile --account-id <user_own_fbid> --username @<username>
instagram-cli user-profile --account-id <user_own_fbid> --profile-url https://instagram.com/<username>
Fetch posts a user has been tagged in. Omit --user-id to fetch the user's own tagged posts. Otherwise, --user-id should be the target user's FBID.
Use --since, --until, --sort-order, and --limit to narrow the shared engagement query.
instagram-cli tagged-posts --account-id <user_own_fbid>
instagram-cli tagged-posts --account-id <user_own_fbid> --after <cursor>
instagram-cli tagged-posts --account-id <user_own_fbid> --user-id 18841401449726893
instagram-cli tagged-posts --account-id <user_own_fbid> --user-id 18841401449726893,18841401449726894 --since 2026-01-01 --until 2026-02-01 --sort-order asc --limit 25
Fetch a single post by its media ID or full Instagram post/reel URL. Provide
exactly one of --id or --url.
instagram-cli post --account-id <user_own_fbid> --id 3599891547851922338_14631749
instagram-cli post --account-id <user_own_fbid> --id 3599891547851922338
instagram-cli post --account-id <user_own_fbid> --url https://www.instagram.com/p/SHORTCODE/
instagram-cli post --account-id <user_own_fbid> --url https://www.instagram.com/reels/anfiurkjnwed
Fetch comments for one or more posts by media ID. Pass a comma-separated list to --post-ids; batch multiple IDs into a single call instead of calling this command per post.Use --since, --until, --sort-order, --limit, and repeated/comma-separated --author-ids filters when needed.
instagram-cli fetch-post-comments --account-id <user_own_fbid> --post-ids 3599891547851922338
instagram-cli fetch-post-comments --account-id <user_own_fbid> --post-ids 3599891547851922338,3599891547851922339
instagram-cli fetch-post-comments --account-id <user_own_fbid> --post-ids 3599891547851922338 --limit 25 --after <cursor>
instagram-cli fetch-post-comments --account-id <user_own_fbid> --post-ids 3599891547851922338 --since 2026-01-01 --until 2026-02-01 --author-ids 18841401449726893
Fetch likers for one or more posts by media ID. Pass a comma-separated list to --post-ids; batch multiple IDs into a single call instead of calling this command per post.Use --since, --until, --sort-order, --limit, and repeated/comma-separated --reactor-ids filters when needed.
instagram-cli fetch-post-likers --account-id <user_own_fbid> --post-ids 3599891547851922338
instagram-cli fetch-post-likers --account-id <user_own_fbid> --post-ids 3599891547851922338,3599891547851922339
instagram-cli fetch-post-likers --account-id <user_own_fbid> --post-ids 3599891547851922338 --limit 25 --after <cursor>
instagram-cli fetch-post-likers --account-id <user_own_fbid> --post-ids 3599891547851922338 --since 2026-01-01 --until 2026-02-01 --reactor-ids 18841401449726893
Fetch the user's saved posts. Include an optional collection_id to fetch posts saved within a particular collection (you can get the collection_id from the saved-collections command).
Without --collection-id, saved-posts uses the shared engagement query and supports --since, --until, --sort-order, and --limit.
instagram-cli saved-posts --account-id <user_own_fbid>
instagram-cli saved-posts --account-id <user_own_fbid> --after <cursor>
instagram-cli saved-posts --account-id <user_own_fbid> --since 2026-01-01 --until 2026-02-01 --sort-order asc --limit 25
instagram-cli saved-posts --account-id <user_own_fbid> --after <cursor> --collection-id "2949392323392323"
Fetch the user's saved collections (folders/categories of saved posts).
instagram-cli saved-collections --account-id <user_own_fbid>
instagram-cli saved-collections --account-id <user_own_fbid> --after <cursor>
instagram-cli create-saved-collection --account-id <user_own_fbid> --name "Travel"
instagram-cli rename-saved-collection --account-id <user_own_fbid> --collection-id 2949392323392323 --name "Japan"
instagram-cli save-post --account-id <user_own_fbid> --media-ids 3599891547851922338
instagram-cli save-post --account-id <user_own_fbid> --media-ids 3599891547851922338,3599891547851922339 --collection-id 2949392323392323
instagram-cli unsave-post --account-id <user_own_fbid> --media-ids 3599891547851922338 --collection-id 2949392323392323
instagram-cli unsave-post --account-id <user_own_fbid> --media-ids 3599891547851922338
Saving with a collection both saves the post and adds it to that collection. Unsaving with a collection only removes it from that collection; omitting --collection-id unsaves it globally.
Fetch the user's own currently posted Instagram stories.
instagram-cli own-stories --account-id <user_own_fbid>
Fetch the user's own Instagram story archive. Use the previous response's next_max_id as --max-id to paginate. Omit on first request. If an item in the response has a non-empty video url, select that over the image url.
instagram-cli own-stories-archive --account-id <user_own_fbid>
instagram-cli own-stories-archive --account-id <user_own_fbid> --max-id <cursor>
Fetch the user's stories tray (currently available stories posted by people the user follows). --count is optional and defaults to 200. The response contains only media IDs — no links, images, or video. To get an actual media permalink for a specific story, pass its ID to story-media.
instagram-cli stories-tray --account-id <user_own_fbid>
instagram-cli stories-tray --account-id <user_own_fbid> --count 25
Be judicious about following up with story-media: do not eagerly fetch media for every story in the tray. Only fetch media for IDs the user explicitly asks about, or a small subset they've clearly requested.
Fetch media metadata (permalink, posted-at time, expires-at time) for one or more story items by ID. Pass a comma-separated list to --ids; batch multiple IDs into a single call instead of calling this command per item.
instagram-cli story-media --account-id <user_own_fbid> --ids 18103150772488230
instagram-cli story-media --account-id <user_own_fbid> --ids 18103150772488230,55858390399494949
Search Instagram locations with required --search-query. Optionally pass
both --latitude and --longitude to narrow the results.
instagram-cli location-search --account-id <user_own_fbid> --search-query "Central Park"
instagram-cli location-search --account-id <user_own_fbid> \
--search-query "Central Park" --latitude 40.7829 --longitude -73.9654
Before passing media to post-story, post-feed, or set-profile-picture,
ensure that every media and cover file is in the workspace path. If it is not,
copy it to the workspace. Never use a /tmp path.
Publish one JPEG, PNG, static WebP, MP4, or MOV file, preferably vertical 9:16
at 1080 x 1920 px. Strongly avoid letterboxing. --file is required and
limited to 100 MB. Directly posted videos require a matching JPEG, PNG, or
static WebP --cover; videos edited with stickers or text generate their cover
automatically.
Use post-story --draft with --file and --editor-json for all visible Story
text and supported native stickers. First run
instagram-cli post-story --help and follow its detailed parameter, text, sticker,
geometry, and media contract. Draft mode renders under
workspace/instagram/stories without posting. Always render from the same clean
media for revisions, show the returned media inline, and ask the user to confirm
it before posting. Record every returned draft output and cover path. After
confirmation, rerun the same command without --draft; it renders the approved
edit in the same directory and posts that output. Once publishing succeeds,
delete every earlier draft and draft cover by its exact recorded path. Keep the
last user-approved draft and the final published render, and never use a glob.
Only mention, location, and link native stickers are supported; refuse all
others. For a location sticker, select a result with location-search and
include its location_id in the location object passed to --editor-json.
Mention objects require user_fbid; link objects require url.
The final command automatically uploads the rendered output and its video cover:
EDITOR_JSON='[
{"type":"text","text":"SUMMER IN NYC","style":"poster","x":0.5,"y":0.2},
{"type":"mention","text":"@friend","user_fbid":"123","style":"default","x":0.5,"y":0.4},
{"type":"location","text":"Central Park","location_id":"456","style":"default","x":0.5,"y":0.65},
{"type":"link","text":"Learn more","url":"https://example.com","style":"default","x":0.5,"y":0.82}
]'
instagram-cli post-story --draft --account-id <user_own_fbid> \
--file <clean-media> --editor-json "$EDITOR_JSON"
instagram-cli post-story --account-id <user_own_fbid> --file <clean-media> \
--editor-json "$EDITOR_JSON"
Publish media to the user's feed. post-feed selects the post type from the
files supplied:
--cover.Each file may be at most 100 MB. --caption is optional, may include hashtags
and textual @mentions, and is limited to 2,200 characters. Whitespace-only
captions are treated as absent. --mentions takes a JSON array of user tags.
Each tag requires user_fbid; optional x and y coordinates run from 0 to 1
and default to 0.5. On a carousel, the CLI applies the supplied user tags to
every item.
For video media, --video-thumbnail-playback-offset-ms optionally selects a
non-negative video frame for the final thumbnail. Each video requires a JPEG,
PNG, or static WebP --cover, shown until frame extraction finishes. For a
carousel, repeat --cover once per video in the same order as the video files;
image items do not take covers. Do not pass either video option for an
image-only post or carousel.
# Image post
instagram-cli post-feed --account-id <user_own_fbid> \
--file /path/to/post.jpg --caption 'A feed caption' \
--mentions '[{"user_fbid":"<tagged_user_fbid>","x":0.5,"y":0.5}]'
# Reel shared to feed
instagram-cli post-feed --account-id <user_own_fbid> \
--file /path/to/reel.mp4 --cover /path/to/cover.jpg \
--video-thumbnail-playback-offset-ms 1200 \
--caption 'A caption with #hashtags and @mentions'
# Mixed carousel; file order is display order and cover order follows videos
instagram-cli post-feed --account-id <user_own_fbid> \
--file /path/to/first.jpg --file /path/to/second.mp4 \
--cover /path/to/second-cover.jpg \
--caption 'A carousel caption'
Do not use --retries for posting because an automatic retry could publish a
duplicate. Instagram also enforces a per-account daily publish limit.
Pass exactly one square (1:1) JPEG or PNG, preferably at least 320 x 320 px and no larger than 1080 x 1080 px. The file may be at most 100 MB.
instagram-cli set-profile-picture --account-id <user_own_fbid> \
--file /path/to/profile.jpg
Fetch media descriptions for one or more Instagram media FBIDs, including narrative summary and semantic understanding. Pass a comma-separated list to --media-ids; batch multiple IDs into a single call instead of calling this command per item.
instagram-cli media-understanding --account-id <user_own_fbid> --media-ids 18103150772488230
instagram-cli media-understanding --account-id <user_own_fbid> --media-ids 18103150772488230,55858390399494949
Fetch posts the user has recently liked.
instagram-cli recently-liked-posts --account-id <user_own_fbid>
instagram-cli recently-liked-posts --account-id <user_own_fbid> --limit 5
instagram-cli recently-liked-posts --account-id <user_own_fbid> --limit 10 --after <cursor>
instagram-cli recently-liked-posts --account-id <user_own_fbid> --since 2026-01-01 --until 2026-02-01 --sort-order asc
Fetch posts the user has recently commented on.
instagram-cli recently-commented-posts --account-id <user_own_fbid>
instagram-cli recently-commented-posts --account-id <user_own_fbid> --limit 5
instagram-cli recently-commented-posts --account-id <user_own_fbid> --limit 10 --after <cursor>
instagram-cli recently-commented-posts --account-id <user_own_fbid> --since 2026-01-01 --until 2026-02-01 --sort-order asc
Before analyzing Instagram performance, load the workflow skill that owns the request:
social_content_performance for the user's own accounts, posts, or
historical results.social_competitor_analysis for competitor, peer, or category
comparisons.social_content_performance.The CLI prints JSON to stdout. Post reads use the normalized collection above; other commands retain their provider-specific decoded JSON. When presenting results to the user, focus on meaningful content (names, text, images/video, links, captions etc.). Never expose raw IDs, cursors, unix timestamps, internal metadata, or implementation details; keep them only in tool calls.
Published skills whose descriptions closely match this one, with their headline benchmark lift.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.