{
  "schemaVersion": "1.0",
  "item": {
    "slug": "instagram-page",
    "name": "Instagram Page",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/seph1709/instagram-page",
    "canonicalUrl": "https://clawhub.ai/seph1709/instagram-page",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/instagram-page",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=instagram-page",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "_meta.json"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/instagram-page"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/instagram-page",
    "agentPageUrl": "https://openagent3.xyz/skills/instagram-page/agent",
    "manifestUrl": "https://openagent3.xyz/skills/instagram-page/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/instagram-page/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "instagram-page - Universal Instagram Graph API Skill",
        "body": "Constructs and executes Instagram Graph API calls inline based on what the user wants. No scripts needed.\n\nRequires an Instagram Business or Creator account linked to a Facebook Page.\nPersonal Instagram accounts are not supported by the Instagram Graph API.\n\nAPI version: v25.0\nBase URL: https://graph.facebook.com/v25.0"
      },
      {
        "title": "STEP 1 - Load Credentials",
        "body": "Credentials are stored in ~/.config/instagram-page/credentials.json.\n\n$cfg      = Get-Content \"$HOME/.config/instagram-page/credentials.json\" -Raw | ConvertFrom-Json\n$token    = $cfg.IG_ACCESS_TOKEN\n$igUserId = $cfg.IG_USER_ID\n\nIf the file does not exist, guide setup. Required fields:\n\nFieldPurposeIG_ACCESS_TOKENLong-lived User access token - used for all API callsIG_USER_IDInstagram-scoped Business/Creator User ID (numeric)IG_APP_IDMeta App ID - only needed during token exchangeIG_APP_SECRETMeta App Secret - only needed during token exchange\n\nPrerequisites:\n\nInstagram account must be a Business or Creator account\nThe Instagram account must be linked to a Facebook Page\nA Meta App with instagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_insights permissions\n\nOne-time token exchange setup:\n\n# Provide: $appId, $appSecret, $shortToken (from Graph API Explorer with IG permissions), $fbPageId\n# 1. Exchange short-lived token for long-lived user token (valid 60 days)\n$r1 = Invoke-RestMethod \"https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=$appId&client_secret=$appSecret&fb_exchange_token=$shortToken\"\n$longToken = $r1.access_token\n# 2. Get Instagram Business Account ID linked to your Facebook Page\n$r2 = Invoke-RestMethod \"https://graph.facebook.com/v25.0/$fbPageId?fields=instagram_business_account&access_token=$longToken\"\n$igUserId = $r2.instagram_business_account.id\n# 3. Save - only these four fields\n@{\n    IG_USER_ID      = $igUserId\n    IG_ACCESS_TOKEN = $longToken\n    IG_APP_ID       = $appId\n    IG_APP_SECRET   = $appSecret\n} | ConvertTo-Json | Set-Content \"$HOME/.config/instagram-page/credentials.json\" -Encoding UTF8\n\nRestrict file permissions immediately after saving:\n\n# Windows\nicacls \"$HOME/.config/instagram-page/credentials.json\" /inheritance:r /grant:r \"$($env:USERNAME):(R,W)\"\n# macOS / Linux\n# chmod 600 ~/.config/instagram-page/credentials.json\n\nRefresh token before it expires (every ~50 days):\n\n$r = Invoke-RestMethod \"https://graph.facebook.com/oauth/access_token?grant_type=ig_refresh_token&access_token=$token\"\n$cfg.IG_ACCESS_TOKEN = $r.access_token\n$cfg | ConvertTo-Json | Set-Content \"$HOME/.config/instagram-page/credentials.json\" -Encoding UTF8\n\nDelete IG_APP_SECRET from credentials.json after setup - it is not needed for API calls.\nNever commit this file to version control. It contains long-lived secrets.\nThis skill makes no external calls other than to graph.facebook.com. No data is forwarded to third parties."
      },
      {
        "title": "STEP 2 - Figure Out the API Call",
        "body": "Instagram publishing uses a two-step flow for most media types:\n\nCreate a media container - uploads/registers the media, returns a creation_id\nPublish the container - makes it live on Instagram"
      },
      {
        "title": "Common Endpoints",
        "body": "What user wantsMethodEndpointPost single photoPOST x2Step 1: /$igUserId/media Step 2: /$igUserId/media_publishPost reel (video)POST x2Step 1: /$igUserId/media (media_type=REELS) Step 2: /$igUserId/media_publishPost storyPOST x2Step 1: /$igUserId/media (media_type=STORIES) Step 2: /$igUserId/media_publishPost carouselPOST x3+Step 1: item containers Step 2: carousel container Step 3: publishGet recent mediaGET/$igUserId/media?fields=id,caption,media_type,timestamp,like_count,comments_countGet account infoGET/$igUserId?fields=username,name,biography,followers_count,media_countGet commentsGET/{media-id}/comments?fields=text,username,timestampReply to commentPOST/{comment-id}/replies body: messageDelete commentDELETE/{comment-id}Hide/show commentPOST/{comment-id} body: hide=true/falseGet media insightsGET/{media-id}/insights?metric=impressions,reach,likes,comments,shares,savedGet account insightsGET/$igUserId/insights?metric=impressions,reach,follower_count&period=dayGet hashtag IDGETig/hashtags?user_id=$igUserId&q=hashtagSearch hashtag mediaGET/{hashtag-id}/top_media?user_id=$igUserId&fields=id,caption,media_typeGet tagged mediaGET/$igUserId/tags?fields=caption,media_url,timestamp"
      },
      {
        "title": "API Call Patterns",
        "body": "GET:\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/ENDPOINT?access_token=$token\" -ErrorAction Stop\n\nPOST (form body):\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/ENDPOINT\" -Method POST `\n    -Body @{ field1=\"value1\"; field2=\"value2\"; access_token=$token } -ErrorAction Stop\n\nDELETE:\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/{id}?access_token=$token\" -Method DELETE -ErrorAction Stop"
      },
      {
        "title": "Publishing Patterns",
        "body": "Single photo post:\n\n# image_url must be publicly accessible\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ image_url=$imageUrl; caption=$caption; access_token=$token } -ErrorAction Stop\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published post ID: $($post.id)\"\n\nReel post (video):\n\n# video_url must be publicly accessible MP4 (H.264, AAC audio, max 1GB, max 60s for feed)\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"REELS\"; video_url=$videoUrl; caption=$caption; share_to_feed=\"true\"; access_token=$token } -ErrorAction Stop\n# Poll for processing status - video upload is async\ndo {\n    Start-Sleep -Seconds 5\n    $status = Invoke-RestMethod \"https://graph.facebook.com/v25.0/$($container.id)?fields=status_code&access_token=$token\"\n} while ($status.status_code -eq \"IN_PROGRESS\")\nif ($status.status_code -ne \"FINISHED\") { throw \"Video processing failed: $($status.status_code)\" }\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published reel ID: $($post.id)\"\n\nCarousel post (2-10 images/videos):\n\n# Create item containers for each media URL\n$itemIds = @()\nforeach ($url in $mediaUrls) {\n    $item = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n        -Body @{ image_url=$url; is_carousel_item=\"true\"; access_token=$token } -ErrorAction Stop\n    $itemIds += $item.id\n}\n# Create carousel container\n$carousel = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"CAROUSEL\"; children=($itemIds -join \",\"); caption=$caption; access_token=$token } -ErrorAction Stop\n# Publish\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$carousel.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published carousel ID: $($post.id)\"\n\nStory:\n\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"STORIES\"; image_url=$imageUrl; access_token=$token } -ErrorAction Stop\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published story ID: $($post.id)\"\n\nImage/video URLs must be publicly accessible - local files are not accepted by the API.\nUpload to a public server or CDN before calling. Instagram limits ~50 API-published posts per 24h."
      },
      {
        "title": "STEP 3 - Handle Errors",
        "body": "try {\n    # ... API call ...\n} catch {\n    $err     = $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue\n    $code    = $err.error.code\n    $subcode = $err.error.error_subcode\n    $msg     = $err.error.message\n    Write-Host \"Error $code/$subcode : $msg\"\n}\n\nCodeSubcodeMeaningFix100-Invalid parameterCheck parameter values; image/video URL must be public102-Session expiredRefresh token - run the refresh snippet in STEP 1190460Token expired (60 days)Refresh token - run the refresh snippet in STEP 1190467Invalid tokenRe-run full setup to get a new token200-Permission deniedAdd the missing permission to your Meta App and regenerate token10-Permission denied (IG scope)Add permission listed in error.message; re-run setup24-No linked IG Business accountLink Instagram account to your Facebook Page in Instagram settings32-Page request limit reachedWait and retry; hourly rate limit hit368-Temporarily blockedWait and retry; account may be temporarily restricted9007-Publishing limit reachedInstagram limits ~50 API-published posts per 24h2207026-Video format invalidMP4 required; H.264 video, AAC audio, max 1GB, 60s for feed reels"
      },
      {
        "title": "Permissions Reference",
        "body": "PermissionRequired forinstagram_basicRead account info, media listinstagram_content_publishCreate and publish posts, reels, stories, carouselsinstagram_manage_commentsRead, reply to, hide, delete commentsinstagram_manage_insightsAccess account and media insightspages_show_listList Facebook Pages (needed during IG account lookup)pages_read_engagementRead Facebook Page linked to Instagram account\n\nIf a permission is missing:\n\nGo to Meta for Developers\nSelect your app -> Permissions and Features\nAdd the required permission\nRegenerate token via Graph API Explorer with the permission checked\nRe-run setup with the new token"
      },
      {
        "title": "AGENT RULES",
        "body": "Always load credentials first. If missing or incomplete, guide setup.\nOnly use IG_ACCESS_TOKEN and IG_USER_ID for API calls. IG_APP_ID and IG_APP_SECRET are for token exchange only.\nDelete IG_APP_SECRET from credentials.json after token exchange - it is not needed for API calls.\nToken expiry: IG_ACCESS_TOKEN expires every 60 days. Remind the user to refresh before expiry using the refresh snippet in STEP 1. Rotate immediately if the host is ever compromised.\nTwo-step publishing: always create a container first, then publish. Never try to publish in a single API call.\nPublic URLs only: image/video URLs must be publicly accessible. If the user provides a local file path, tell them to upload it to a public server or CDN first.\nReel processing: poll status_code until FINISHED before publishing - video processing is async and can take minutes.\nLeast-privilege: only request the permissions the use case needs.\nAll API calls go to graph.facebook.com only. No external forwarding, no third-party services.\nConstruct API calls inline from user intent - do not look for script files.\nOn any error: parse error.code + error.error_subcode, map to the table above, tell the user exactly what to do.\nIf a permission is missing: name it, link to Meta for Developers, say to re-run setup.\nBusiness/Creator only: if the user has a personal Instagram account, tell them to convert it to Business or Creator in Instagram settings first - personal accounts are not supported by the Instagram Graph API."
      }
    ],
    "body": "instagram-page - Universal Instagram Graph API Skill\n\nConstructs and executes Instagram Graph API calls inline based on what the user wants. No scripts needed.\n\nRequires an Instagram Business or Creator account linked to a Facebook Page. Personal Instagram accounts are not supported by the Instagram Graph API.\n\nAPI version: v25.0 Base URL: https://graph.facebook.com/v25.0\n\nSTEP 1 - Load Credentials\n\nCredentials are stored in ~/.config/instagram-page/credentials.json.\n\n$cfg      = Get-Content \"$HOME/.config/instagram-page/credentials.json\" -Raw | ConvertFrom-Json\n$token    = $cfg.IG_ACCESS_TOKEN\n$igUserId = $cfg.IG_USER_ID\n\n\nIf the file does not exist, guide setup. Required fields:\n\nField\tPurpose\nIG_ACCESS_TOKEN\tLong-lived User access token - used for all API calls\nIG_USER_ID\tInstagram-scoped Business/Creator User ID (numeric)\nIG_APP_ID\tMeta App ID - only needed during token exchange\nIG_APP_SECRET\tMeta App Secret - only needed during token exchange\n\nPrerequisites:\n\nInstagram account must be a Business or Creator account\nThe Instagram account must be linked to a Facebook Page\nA Meta App with instagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_insights permissions\n\nOne-time token exchange setup:\n\n# Provide: $appId, $appSecret, $shortToken (from Graph API Explorer with IG permissions), $fbPageId\n# 1. Exchange short-lived token for long-lived user token (valid 60 days)\n$r1 = Invoke-RestMethod \"https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=$appId&client_secret=$appSecret&fb_exchange_token=$shortToken\"\n$longToken = $r1.access_token\n# 2. Get Instagram Business Account ID linked to your Facebook Page\n$r2 = Invoke-RestMethod \"https://graph.facebook.com/v25.0/$fbPageId?fields=instagram_business_account&access_token=$longToken\"\n$igUserId = $r2.instagram_business_account.id\n# 3. Save - only these four fields\n@{\n    IG_USER_ID      = $igUserId\n    IG_ACCESS_TOKEN = $longToken\n    IG_APP_ID       = $appId\n    IG_APP_SECRET   = $appSecret\n} | ConvertTo-Json | Set-Content \"$HOME/.config/instagram-page/credentials.json\" -Encoding UTF8\n\n\nRestrict file permissions immediately after saving:\n\n# Windows\nicacls \"$HOME/.config/instagram-page/credentials.json\" /inheritance:r /grant:r \"$($env:USERNAME):(R,W)\"\n# macOS / Linux\n# chmod 600 ~/.config/instagram-page/credentials.json\n\n\nRefresh token before it expires (every ~50 days):\n\n$r = Invoke-RestMethod \"https://graph.facebook.com/oauth/access_token?grant_type=ig_refresh_token&access_token=$token\"\n$cfg.IG_ACCESS_TOKEN = $r.access_token\n$cfg | ConvertTo-Json | Set-Content \"$HOME/.config/instagram-page/credentials.json\" -Encoding UTF8\n\n\nDelete IG_APP_SECRET from credentials.json after setup - it is not needed for API calls. Never commit this file to version control. It contains long-lived secrets. This skill makes no external calls other than to graph.facebook.com. No data is forwarded to third parties.\n\nSTEP 2 - Figure Out the API Call\n\nInstagram publishing uses a two-step flow for most media types:\n\nCreate a media container - uploads/registers the media, returns a creation_id\nPublish the container - makes it live on Instagram\nCommon Endpoints\nWhat user wants\tMethod\tEndpoint\nPost single photo\tPOST x2\tStep 1: /$igUserId/media Step 2: /$igUserId/media_publish\nPost reel (video)\tPOST x2\tStep 1: /$igUserId/media (media_type=REELS) Step 2: /$igUserId/media_publish\nPost story\tPOST x2\tStep 1: /$igUserId/media (media_type=STORIES) Step 2: /$igUserId/media_publish\nPost carousel\tPOST x3+\tStep 1: item containers Step 2: carousel container Step 3: publish\nGet recent media\tGET\t/$igUserId/media?fields=id,caption,media_type,timestamp,like_count,comments_count\nGet account info\tGET\t/$igUserId?fields=username,name,biography,followers_count,media_count\nGet comments\tGET\t/{media-id}/comments?fields=text,username,timestamp\nReply to comment\tPOST\t/{comment-id}/replies body: message\nDelete comment\tDELETE\t/{comment-id}\nHide/show comment\tPOST\t/{comment-id} body: hide=true/false\nGet media insights\tGET\t/{media-id}/insights?metric=impressions,reach,likes,comments,shares,saved\nGet account insights\tGET\t/$igUserId/insights?metric=impressions,reach,follower_count&period=day\nGet hashtag ID\tGET\tig/hashtags?user_id=$igUserId&q=hashtag\nSearch hashtag media\tGET\t/{hashtag-id}/top_media?user_id=$igUserId&fields=id,caption,media_type\nGet tagged media\tGET\t/$igUserId/tags?fields=caption,media_url,timestamp\nAPI Call Patterns\n\nGET:\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/ENDPOINT?access_token=$token\" -ErrorAction Stop\n\n\nPOST (form body):\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/ENDPOINT\" -Method POST `\n    -Body @{ field1=\"value1\"; field2=\"value2\"; access_token=$token } -ErrorAction Stop\n\n\nDELETE:\n\n$result = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/{id}?access_token=$token\" -Method DELETE -ErrorAction Stop\n\nPublishing Patterns\n\nSingle photo post:\n\n# image_url must be publicly accessible\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ image_url=$imageUrl; caption=$caption; access_token=$token } -ErrorAction Stop\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published post ID: $($post.id)\"\n\n\nReel post (video):\n\n# video_url must be publicly accessible MP4 (H.264, AAC audio, max 1GB, max 60s for feed)\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"REELS\"; video_url=$videoUrl; caption=$caption; share_to_feed=\"true\"; access_token=$token } -ErrorAction Stop\n# Poll for processing status - video upload is async\ndo {\n    Start-Sleep -Seconds 5\n    $status = Invoke-RestMethod \"https://graph.facebook.com/v25.0/$($container.id)?fields=status_code&access_token=$token\"\n} while ($status.status_code -eq \"IN_PROGRESS\")\nif ($status.status_code -ne \"FINISHED\") { throw \"Video processing failed: $($status.status_code)\" }\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published reel ID: $($post.id)\"\n\n\nCarousel post (2-10 images/videos):\n\n# Create item containers for each media URL\n$itemIds = @()\nforeach ($url in $mediaUrls) {\n    $item = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n        -Body @{ image_url=$url; is_carousel_item=\"true\"; access_token=$token } -ErrorAction Stop\n    $itemIds += $item.id\n}\n# Create carousel container\n$carousel = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"CAROUSEL\"; children=($itemIds -join \",\"); caption=$caption; access_token=$token } -ErrorAction Stop\n# Publish\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$carousel.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published carousel ID: $($post.id)\"\n\n\nStory:\n\n$container = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media\" -Method POST `\n    -Body @{ media_type=\"STORIES\"; image_url=$imageUrl; access_token=$token } -ErrorAction Stop\n$post = Invoke-RestMethod -Uri \"https://graph.facebook.com/v25.0/$igUserId/media_publish\" -Method POST `\n    -Body @{ creation_id=$container.id; access_token=$token } -ErrorAction Stop\nWrite-Host \"Published story ID: $($post.id)\"\n\n\nImage/video URLs must be publicly accessible - local files are not accepted by the API. Upload to a public server or CDN before calling. Instagram limits ~50 API-published posts per 24h.\n\nSTEP 3 - Handle Errors\ntry {\n    # ... API call ...\n} catch {\n    $err     = $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue\n    $code    = $err.error.code\n    $subcode = $err.error.error_subcode\n    $msg     = $err.error.message\n    Write-Host \"Error $code/$subcode : $msg\"\n}\n\nCode\tSubcode\tMeaning\tFix\n100\t-\tInvalid parameter\tCheck parameter values; image/video URL must be public\n102\t-\tSession expired\tRefresh token - run the refresh snippet in STEP 1\n190\t460\tToken expired (60 days)\tRefresh token - run the refresh snippet in STEP 1\n190\t467\tInvalid token\tRe-run full setup to get a new token\n200\t-\tPermission denied\tAdd the missing permission to your Meta App and regenerate token\n10\t-\tPermission denied (IG scope)\tAdd permission listed in error.message; re-run setup\n24\t-\tNo linked IG Business account\tLink Instagram account to your Facebook Page in Instagram settings\n32\t-\tPage request limit reached\tWait and retry; hourly rate limit hit\n368\t-\tTemporarily blocked\tWait and retry; account may be temporarily restricted\n9007\t-\tPublishing limit reached\tInstagram limits ~50 API-published posts per 24h\n2207026\t-\tVideo format invalid\tMP4 required; H.264 video, AAC audio, max 1GB, 60s for feed reels\nPermissions Reference\nPermission\tRequired for\ninstagram_basic\tRead account info, media list\ninstagram_content_publish\tCreate and publish posts, reels, stories, carousels\ninstagram_manage_comments\tRead, reply to, hide, delete comments\ninstagram_manage_insights\tAccess account and media insights\npages_show_list\tList Facebook Pages (needed during IG account lookup)\npages_read_engagement\tRead Facebook Page linked to Instagram account\n\nIf a permission is missing:\n\nGo to Meta for Developers\nSelect your app -> Permissions and Features\nAdd the required permission\nRegenerate token via Graph API Explorer with the permission checked\nRe-run setup with the new token\nAGENT RULES\nAlways load credentials first. If missing or incomplete, guide setup.\nOnly use IG_ACCESS_TOKEN and IG_USER_ID for API calls. IG_APP_ID and IG_APP_SECRET are for token exchange only.\nDelete IG_APP_SECRET from credentials.json after token exchange - it is not needed for API calls.\nToken expiry: IG_ACCESS_TOKEN expires every 60 days. Remind the user to refresh before expiry using the refresh snippet in STEP 1. Rotate immediately if the host is ever compromised.\nTwo-step publishing: always create a container first, then publish. Never try to publish in a single API call.\nPublic URLs only: image/video URLs must be publicly accessible. If the user provides a local file path, tell them to upload it to a public server or CDN first.\nReel processing: poll status_code until FINISHED before publishing - video processing is async and can take minutes.\nLeast-privilege: only request the permissions the use case needs.\nAll API calls go to graph.facebook.com only. No external forwarding, no third-party services.\nConstruct API calls inline from user intent - do not look for script files.\nOn any error: parse error.code + error.error_subcode, map to the table above, tell the user exactly what to do.\nIf a permission is missing: name it, link to Meta for Developers, say to re-run setup.\nBusiness/Creator only: if the user has a personal Instagram account, tell them to convert it to Business or Creator in Instagram settings first - personal accounts are not supported by the Instagram Graph API."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/seph1709/instagram-page",
    "publisherUrl": "https://clawhub.ai/seph1709/instagram-page",
    "owner": "seph1709",
    "version": "1.0.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/instagram-page",
    "downloadUrl": "https://openagent3.xyz/downloads/instagram-page",
    "agentUrl": "https://openagent3.xyz/skills/instagram-page/agent",
    "manifestUrl": "https://openagent3.xyz/skills/instagram-page/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/instagram-page/agent.md"
  }
}