{
  "data": {
    "id": "OmzUBfZ01FOWJ3Y1P",
    "actId": "eVCmIqrAiaiMAKEF7",
    "userId": "zq8lKbpLzTjGDayPC",
    "startedAt": "2026-11-05T06:29:17.330Z",
    "finishedAt": "2026-11-05T06:29:48.388Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 30978,
      "runTimeSecs": 30.978,
      "computeUnits": 0.03442,
      "imageSizeBytes": 3129950208
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "ojStZBKB4jwIBgimj",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Instagram Profile Scraper Input\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"usernames\": {\n      \"title\": \"Instagram Usernames\",\n      \"type\": \"array\",\n      \"description\": \"Instagram profiles to scrape. Each entry can be a username (with or without @) or a profile link such as https://www.instagram.com/natgeo/. Each profile is scraped in turn. Example: 'instagram', '@instagram' or 'https://www.instagram.com/instagram/'.\",\n      \"editor\": \"stringList\",\n      \"example\": [\n        \"instagram\"\n      ],\n      \"prefill\": [\n        \"instagram\"\n      ],\n      \"minItems\": 1\n    },\n    \"maxPosts\": {\n      \"title\": \"Maximum Posts to Scrape\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of posts to extract per profile (after the date and pinned-post filters below). Set to 0 to only extract profile data without posts. Public profiles need no sign-in, however many posts you ask for.\",\n      \"default\": 12,\n      \"minimum\": 0,\n      \"maximum\": 500,\n      \"prefill\": 3,\n      \"example\": 50\n    },\n    \"newerThan\": {\n      \"title\": \"Only posts newer than\",\n      \"type\": \"string\",\n      \"description\": \"Skip posts published before this date. Leave empty for no date filter. Must be a date from 2000-01-01 up to the day before the run. The date is read from the post's id, so it can be off by up to a day.\",\n      \"editor\": \"datepicker\",\n      \"dateType\": \"absolute\",\n      \"nullable\": true\n    },\n    \"skipPinnedPosts\": {\n      \"title\": \"Skip pinned posts\",\n      \"type\": \"boolean\",\n      \"description\": \"Leave out the posts a profile has pinned to the top of its grid. A pinned post that is also the newest post cannot be recognised and stays in.\",\n      \"default\": false\n    },\n    \"cookies\": {\n      \"title\": \"Instagram Cookies (Optional)\",\n      \"type\": \"string\",\n      \"description\": \"Optional. Leave empty to scrape public profiles without signing in. Paste your own Instagram cookies in JSON format to also scrape private profiles your account follows and age-restricted posts. It is a secret input, so the Apify Console hides and encrypts it.\\n\\nFormat: [{\\\"name\\\":\\\"sessionid\\\",\\\"value\\\":\\\"...\\\",\\\"domain\\\":\\\".instagram.com\\\"}, ...]\",\n      \"editor\": \"textarea\",\n      \"isSecret\": true\n    }\n  },\n  \"required\": [\n    \"usernames\"\n  ]\n}",
    "readme": "# Instagram Profile Scraper - Bio & Posts\n\nLook up one or many public Instagram accounts and get a clean record for each: display name, bio, follower and following counts, verified flag and bio links. Add recent posts with captions, hashtags, mentions, likes, comments, media links, location and music, then export everything to Excel, CSV or JSON. Built for marketers, agencies, analysts and researchers who need to size up creators, competitors and brands quickly.\n\n## What this actor does\n\n- **Many accounts per run** — enter a list of usernames, with or without the `@`, and each one is processed in turn\n- **Profile snapshot** — name, bio, follower and following counts, verification and bio links\n- **Recent posts on demand** — up to 500 posts per profile, covering photos, videos, reels, carousels and IGTV, with no sign-in for public profiles\n- **Date and pin filters** — keep only posts newer than a date, and leave out the posts a profile has pinned\n- **Profile-only mode** — set `maxPosts` to `0` to skip posts and collect just the account details\n\n## Output per profile\n\nWhen `maxPosts` is `0` (or the account has no posts to show), each username produces one record with a single `author_meta` object. The same object is attached to every post record of that account.\n\n`author_meta` fields:\n\n- `username` — Instagram username\n- `full_name` — display name\n- `biography` — bio text\n- `profile_pic_url` — profile picture URL\n- `profile_url` — link to the profile on Instagram\n- `is_verified` — `true` if the account has a verified badge\n- `is_private` — `true` if the account is private\n- `followers_count` — number of followers\n- `following_count` — number of accounts followed\n- `external_urls` — links listed in the bio (empty list if none)\n\n## Output per post\n\nOne record per post when `maxPosts` is greater than `0`.\n\n- `post_url` — direct link to the post\n- `status` — `success`, `post_not_found`, `post_age_restricted`, `post_is_private`, `error`, `blocked` or `invalid_url`\n- `author_meta` — the profile object described above\n- `shortcode` — Instagram's short ID for the post\n- `post_id` — Instagram's numeric media ID\n- `username` — username of the post author\n- `caption` — full caption text\n- `hashtags` — hashtags found in the caption\n- `mentions` — @mentions found in the caption\n- `tagged_users` — accounts tagged in the post\n- `collaborators` — accounts listed as co-authors\n- `caption_is_edited` — `true` if the caption was edited after posting\n- `pub_date` — publication date and time (ISO 8601)\n- `media_type` — `Photo`, `Video`, `Carousel`, `Reel` or `IGTV`\n- `media_count` — number of images / videos in the post\n- `thumbnail_url` — cover image URL\n- `media_items` — every image or video in the post, in order, each with `index`, `type`, `url`, `width` and `height`; videos also carry `duration` and `has_audio`\n- `accessibility_caption` — Instagram's automatic alt-text for the media\n- `like_count` — number of likes\n- `comment_count` — number of comments\n- `likes_hidden` — `true` if the author hid the like count\n- `comments_disabled` — `true` if comments are turned off\n- `location` — tagged location, when there is one\n- `music` — audio attribution, when there is one (mostly reels)\n- `scraped_at` — when the record was collected (ISO 8601)\n\nOnly `success` posts carry the full set of fields. Posts with any other status contain just `post_url`, `status` and `author_meta`. The `status` values mean:\n\n- `success` — the post was collected in full\n- `post_not_found` — the post no longer exists or is not available\n- `post_age_restricted` — Instagram restricts the post to older viewers\n- `post_is_private` — the post belongs to a private account\n- `blocked` — Instagram refused the request for that post\n- `invalid_url` — the post link was not a valid Instagram post URL\n- `error` — something else went wrong while collecting that post\n\nA profile that could not be scraped gets a record with a `status` that names the cause and only the `username` and `profile_url` (a private profile also shows the public details above). The explanation is in the run log, one line per profile, followed by a closing `Done:` summary, and the run moves on to the next username. The profile statuses are `profile_not_found`, `profile_is_private`, `profile_age_restricted` (an age check, for example alcohol brands), `profile_restricted` (\"unavailable for certain audiences\"), `cookies_unusable` (a private or restricted profile needed your cookies and Instagram did not accept them), `blocked` and `error`; a scraped profile is `success`. The post statuses are listed under Output per post. While the run is going, the status message shows a live count such as `Scraped 2/5 profiles`.\n\n### Profile field availability\n\nThe profile details are read the way a visitor who is not signed in sees them. Instagram shows that visitor the name, bio, picture, verified and private flags, the exact follower and following counts and the bio links. The post count is in the page description: exact up to 9,999 posts, and rounded to whole thousands from 10,000 posts (Instagram writes \"32K Posts\", so `posts_count` is 32000). It does not show the business flag, the category or a business email and phone, so those are not in the record. A private profile shows the same details.\n\n| `author_meta` field | Available |\n|---|---|\n| `username`, `full_name`, `biography`, `profile_pic_url`, `profile_url`, `is_verified`, `is_private`, `followers_count`, `following_count`, `external_urls` | Yes |\n| `posts_count` | Yes. When the profile has 10,000 posts or more, an approximate post count is given instead of the exact one: Instagram only gives a figure rounded to whole thousands (32K becomes 32000). Below 10,000 it is exact. It comes from a cached copy and can lag a little |\n| `is_business`, `category`, `email`, `phone` | No (shown by Instagram only to signed-in visitors) |\n\n## Authentication\n\nPublic profiles and public posts need no sign-in, however many posts you ask for: a profile is always read first the way Instagram shows it to a visitor who is not signed in, even when you give cookies. Only a private profile (your account must follow it) and age-restricted posts need a signed-in view, and only your own cookies can give one. Export your instagram.com cookies as JSON from a logged-in browser session using any cookie-export browser extension, then paste the JSON into the optional `cookies` field. The field is a secret input, so the Apify Console hides and encrypts it, and the cookies are used only during your run. Before anything is read with them, the actor asks Instagram whether it recognises the cookies; if they are invalid, expired or signed out, the run log says so. Without cookies those cases are reported with their status. The actor does not sign in with any account of its own.\n\nIf your cookies expire mid-run, re-export them from your browser and restart the actor.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `usernames` | array of strings | – (required) | Instagram usernames to scrape, with or without `@`, or profile links such as `https://www.instagram.com/natgeo/`. At least one is needed |\n| `maxPosts` | integer | `12` | Posts to collect per profile, from `0` to `500`. Posts left out by the two filters below do not count. `0` returns profile data only |\n| `newerThan` | string | – | Optional date (`YYYY-MM-DD`). Posts published before it are skipped. Empty means no date filter. It must be from 2000-01-01 up to the day before the run, otherwise it is ignored with a warning in the log. The date is read from the post's id, so it can be off by up to a day |\n| `skipPinnedPosts` | boolean | `false` | Leave out the posts a profile has pinned to the top of its grid. Instagram does not mark pinned posts for a visitor who is not signed in, so they are recognised by their place and date; a pinned post that is also the profile's newest post cannot be told apart and stays in |\n| `cookies` | string (secret) | – | Optional. Your own Instagram cookies as JSON, used for private profiles your account follows and age-restricted posts. See Authentication |\n\n### Example: quick look at one brand\n\n```json\n{\n  \"usernames\": [\"nike\"],\n  \"maxPosts\": 12\n}\n```\n\n### Example: compare several publishers side by side\n\n```json\n{\n  \"usernames\": [\"natgeo\", \"@nytimes\", \"bbcnews\"],\n  \"maxPosts\": 30\n}\n```\n\n### Example: account details only for a vetting list\n\n```json\n{\n  \"usernames\": [\"nasa\", \"spacex\", \"esa\"],\n  \"maxPosts\": 0\n}\n```\n\n### Example: deep pull with your own cookies\n\n```json\n{\n  \"usernames\": [\"redbull\"],\n  \"maxPosts\": 500,\n  \"cookies\": \"<your cookies JSON>\"\n}\n```\n\n## Example output\n\nA profile-only record (`maxPosts: 0`); the values are illustrative.\n\n```json\n{\n  \"status\": \"success\",\n  \"author_meta\": {\n    \"username\": \"examplebrand\",\n    \"full_name\": \"Example Brand\",\n    \"biography\": \"Better ingredients, better you\",\n    \"profile_pic_url\": \"https://.../profile.jpg\",\n    \"is_verified\": true,\n    \"is_private\": false,\n    \"followers_count\": 30213,\n    \"following_count\": 12,\n    \"profile_url\": \"https://www.instagram.com/examplebrand/\",\n    \"external_urls\": [\"https://example.com/shop\"]\n  }\n}\n```\n\n## Use cases\n\n- **Influencer marketers** — check follower counts, verification and posting activity before signing a creator\n- **Agency account managers** — compare a client's profile and recent posts with competitors in one export\n- **Social media analysts** — see which post types, captions and hashtags earn the most likes and comments\n- **Partnership teams** — vet creators and brands in a niche by their bio, follower counts and bio links before contacting them individually\n- **Brand and PR teams** — audit how tagged collaborators appear on a brand's feed\n- **Academic researchers** — gather public captions, hashtags, locations and engagement counts for communication studies\n\n## Responsible use\n\nThe data this actor returns is publicly available on Instagram, but bios (which can hold contact details), names, photos and tagged accounts can still identify real people. Before you collect or store them you need a lawful basis (for example under the GDPR), and you should keep only what your purpose requires. Do not use the results to profile, track or target minors, and do not use them to single out people by special categories of personal data such as health, religion, political opinion or sexual orientation. Contact details found on a profile are meant for the business purpose they were published for, not for unsolicited bulk messaging.\n\n## FAQ\n\n**Do I need an Instagram account?**\nNo, not for public profiles. Only private profiles and age-restricted posts need cookies, and you can paste your own in the optional `cookies` field (see Authentication above).\n\n**Can it scrape private accounts?**\nOnly with your own cookies, from an account that follows it. Without cookies you get one record with the public profile details and the status `profile_is_private`.\n\n**How many posts can I get per profile?**\nUp to 500 per profile in one run. Use `maxPosts` to choose any number from `1` to `500`, or `0` for profile details only. Accounts with fewer posts simply return fewer.\n\n**Which post types are included?**\nPhotos, videos, reels, carousels and IGTV. For carousels, every slide is listed in `media_items`, in order.\n\n**Why are `email`, `phone`, `category` and `is_business` missing, and is `posts_count` exact?**\nThe first four are shown by Instagram only to signed-in visitors, and the actor reads profiles without signing in. `posts_count` is exact below 10,000 posts. When a profile has 10,000 posts or more, an approximate post count is given instead: Instagram writes it as an abbreviation such as \"32K\", and the actor turns it into 32000 (see Profile field availability).\n\n**What happens if a username does not exist or fails?**\nThat username gets a record with a `status` such as `profile_not_found` or `error` (the log explains it), and the run continues with the rest of your list.\n\n**How current is the data?**\nIt is collected live when you run the actor, so follower counts, likes and comments reflect that moment.\n\n**Do I need to set up a proxy?**\nNo. The actor handles its connection to Instagram automatically. Just enter your usernames and run it.\n\n**Is this affiliated with Instagram or Meta?**\nNo. It is an independent tool that works with publicly available profile data. It is not affiliated with, endorsed by or sponsored by Instagram or Meta Platforms, Inc.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "instagram-profile-scraper-bio-and-posts",
      "title": "Instagram Profile Scraper - Bio & Posts",
      "description": "Scrape public Instagram profiles from usernames or profile links: bio, followers, following, post count, verified badge and bio links. Add recent posts with captions, hashtags, likes and comments, with a date filter and an option to skip pinned posts. No login needed for public profiles. Export to Excel, CSV or JSON.",
      "version": "0.0",
      "environmentVariables": {
        "MONGO_URI": "@igMongoUri",
        "MONGO_DB": "@igMongoDb",
        "MONGO_COLLECTION": "@igMongoCollection",
        "SMTP_USER": "@igSmtpUser",
        "SMTP_PASSWORD": "@igSmtpPassword",
        "ALERT_RECIPIENTS": "@igAlertRecipients",
        "GH_WORKFLOW_TOKEN": "@igGhWorkflowToken",
        "GH_WORKFLOW_REPO": "@igGhWorkflowRepo",
        "GH_WORKFLOW_EVENT": "@igGhWorkflowEvent",
        "COOKIE_CHECK_POST_URL": "@igCookieCheckPostUrl",
        "COOKIE_CHECK_POST_MARKER": "@igCookieCheckPostMarker",
        "USE_POOL_COOKIES": "@igUsePoolCookies"
      },
      "meta": {
        "templateId": "python-playwright"
      },
      "input": {
        "title": "Instagram Profile Scraper Input",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "usernames": {
            "title": "Instagram Usernames",
            "type": "array",
            "description": "Instagram profiles to scrape. Each entry can be a username (with or without @) or a profile link such as https://www.instagram.com/natgeo/. Each profile is scraped in turn. Example: 'instagram', '@instagram' or 'https://www.instagram.com/instagram/'.",
            "editor": "stringList",
            "example": [
              "instagram"
            ],
            "prefill": [
              "instagram"
            ],
            "minItems": 1
          },
          "maxPosts": {
            "title": "Maximum Posts to Scrape",
            "type": "integer",
            "description": "Maximum number of posts to extract per profile (after the date and pinned-post filters below). Set to 0 to only extract profile data without posts. Public profiles need no sign-in, however many posts you ask for.",
            "default": 12,
            "minimum": 0,
            "maximum": 500,
            "prefill": 3,
            "example": 50
          },
          "newerThan": {
            "title": "Only posts newer than",
            "type": "string",
            "description": "Skip posts published before this date. Leave empty for no date filter. Must be a date from 2000-01-01 up to the day before the run. The date is read from the post's id, so it can be off by up to a day.",
            "editor": "datepicker",
            "dateType": "absolute",
            "nullable": true
          },
          "skipPinnedPosts": {
            "title": "Skip pinned posts",
            "type": "boolean",
            "description": "Leave out the posts a profile has pinned to the top of its grid. A pinned post that is also the newest post cannot be recognised and stays in.",
            "default": false
          },
          "cookies": {
            "title": "Instagram Cookies (Optional)",
            "type": "string",
            "description": "Optional. Leave empty to scrape public profiles without signing in. Paste your own Instagram cookies in JSON format to also scrape private profiles your account follows and age-restricted posts. It is a secret input, so the Apify Console hides and encrypts it.\n\nFormat: [{\"name\":\"sessionid\",\"value\":\"...\",\"domain\":\".instagram.com\"}, ...]",
            "editor": "textarea",
            "isSecret": true
          }
        },
        "required": [
          "usernames"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Instagram Profile Scraper Output",
        "type": "object",
        "properties": {
          "posts": {
            "type": "string",
            "title": "Scraped Posts & Profiles",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Instagram Posts & Profiles",
          "fields": {
            "type": "object",
            "properties": {
              "post_url": {
                "type": "string",
                "description": "Direct URL to the Instagram post"
              },
              "shortcode": {
                "type": "string",
                "description": "Instagram shortcode identifying the post"
              },
              "post_id": {
                "type": "string",
                "description": "Internal Instagram media id of the post"
              },
              "status": {
                "type": "string",
                "description": "success for a scraped post or profile. Otherwise the reason there is none: post_age_restricted, post_is_private, post_not_found, blocked, error, invalid_url, cookies_unusable, profile_not_found, profile_is_private, profile_age_restricted or profile_restricted. The log explains each one"
              },
              "username": {
                "type": "string",
                "description": "Instagram username of the post author"
              },
              "author_meta": {
                "type": "object",
                "description": "Full profile data of the scraped account",
                "properties": {
                  "username": {
                    "type": "string"
                  },
                  "full_name": {
                    "type": "string",
                    "nullable": true
                  },
                  "biography": {
                    "type": "string",
                    "nullable": true
                  },
                  "profile_pic_url": {
                    "type": "string",
                    "nullable": true
                  },
                  "is_verified": {
                    "type": "boolean"
                  },
                  "is_private": {
                    "type": "boolean"
                  },
                  "is_business": {
                    "type": "boolean"
                  },
                  "followers_count": {
                    "type": "integer"
                  },
                  "following_count": {
                    "type": "integer"
                  },
                  "posts_count": {
                    "type": "integer"
                  },
                  "profile_url": {
                    "type": "string"
                  },
                  "external_urls": {
                    "type": "array"
                  },
                  "email": {
                    "type": "string",
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "nullable": true
                  },
                  "category": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "caption": {
                "type": "string",
                "nullable": true,
                "description": "Full caption text of the post"
              },
              "hashtags": {
                "type": "array",
                "description": "Hashtags extracted from the caption"
              },
              "mentions": {
                "type": "array",
                "description": "@mentions extracted from the caption"
              },
              "tagged_users": {
                "type": "array",
                "description": "Usernames tagged in the post"
              },
              "collaborators": {
                "type": "array",
                "description": "Usernames listed as co-authors of the post"
              },
              "caption_is_edited": {
                "type": "boolean",
                "description": "Whether the caption was edited after posting"
              },
              "pub_date": {
                "type": "string",
                "nullable": true,
                "description": "ISO 8601 datetime when the post was published"
              },
              "media_type": {
                "type": "string",
                "description": "Type of post: Photo, Video, Carousel, Reel, or IGTV"
              },
              "media_count": {
                "type": "integer",
                "nullable": true,
                "description": "Number of media items in the post (1 for single image/video)"
              },
              "thumbnail_url": {
                "type": "string",
                "nullable": true,
                "description": "Direct URL to the post's cover image"
              },
              "media_items": {
                "type": "array",
                "nullable": true,
                "description": "Every image/video in the post, in order, with per-item url/dimensions"
              },
              "accessibility_caption": {
                "type": "string",
                "nullable": true,
                "description": "Instagram's auto-generated alt-text description of the media"
              },
              "like_count": {
                "type": "integer",
                "nullable": true,
                "description": "Number of likes on the post"
              },
              "comment_count": {
                "type": "integer",
                "nullable": true,
                "description": "Number of comments on the post"
              },
              "likes_hidden": {
                "type": "boolean",
                "description": "Whether the author hid the like count"
              },
              "comments_disabled": {
                "type": "boolean",
                "description": "Whether commenting is disabled on the post"
              },
              "location": {
                "type": "object",
                "nullable": true,
                "description": "Tagged location, when present"
              },
              "music": {
                "type": "object",
                "nullable": true,
                "description": "Music/audio attribution, when present (reels)"
              },
              "scraped_at": {
                "type": "string",
                "description": "ISO 8601 datetime when this record was scraped"
              }
            }
          },
          "views": {
            "overview": {
              "title": "Posts",
              "transformation": {
                "fields": [
                  "username",
                  "post_url",
                  "media_type",
                  "caption",
                  "like_count",
                  "comment_count",
                  "pub_date",
                  "media_count",
                  "thumbnail_url",
                  "status",
                  "scraped_at",
                  "author_meta.full_name",
                  "author_meta.followers_count",
                  "author_meta.is_verified",
                  "author_meta.is_business",
                  "author_meta.category"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "author_meta.full_name": {
                    "label": "Name",
                    "format": "text"
                  },
                  "username": {
                    "label": "Username",
                    "format": "text"
                  },
                  "media_type": {
                    "label": "Type",
                    "format": "text"
                  },
                  "caption": {
                    "label": "Caption",
                    "format": "text"
                  },
                  "like_count": {
                    "label": "Likes",
                    "format": "number"
                  },
                  "comment_count": {
                    "label": "Comments",
                    "format": "number"
                  },
                  "pub_date": {
                    "label": "Published",
                    "format": "text"
                  },
                  "media_count": {
                    "label": "Media Count",
                    "format": "number"
                  },
                  "thumbnail_url": {
                    "label": "Thumbnail",
                    "format": "text"
                  },
                  "post_url": {
                    "label": "Post URL",
                    "format": "text"
                  },
                  "status": {
                    "label": "Status",
                    "format": "text"
                  },
                  "author_meta.followers_count": {
                    "label": "Followers",
                    "format": "number"
                  },
                  "author_meta.is_verified": {
                    "label": "Verified",
                    "format": "boolean"
                  },
                  "author_meta.is_business": {
                    "label": "Business",
                    "format": "boolean"
                  }
                }
              }
            }
          }
        }
      },
      "readme": "# Instagram Profile Scraper - Bio & Posts\n\nLook up one or many public Instagram accounts and get a clean record for each: display name, bio, follower and following counts, verified flag and bio links. Add recent posts with captions, hashtags, mentions, likes, comments, media links, location and music, then export everything to Excel, CSV or JSON. Built for marketers, agencies, analysts and researchers who need to size up creators, competitors and brands quickly.\n\n## What this actor does\n\n- **Many accounts per run** — enter a list of usernames, with or without the `@`, and each one is processed in turn\n- **Profile snapshot** — name, bio, follower and following counts, verification and bio links\n- **Recent posts on demand** — up to 500 posts per profile, covering photos, videos, reels, carousels and IGTV, with no sign-in for public profiles\n- **Date and pin filters** — keep only posts newer than a date, and leave out the posts a profile has pinned\n- **Profile-only mode** — set `maxPosts` to `0` to skip posts and collect just the account details\n\n## Output per profile\n\nWhen `maxPosts` is `0` (or the account has no posts to show), each username produces one record with a single `author_meta` object. The same object is attached to every post record of that account.\n\n`author_meta` fields:\n\n- `username` — Instagram username\n- `full_name` — display name\n- `biography` — bio text\n- `profile_pic_url` — profile picture URL\n- `profile_url` — link to the profile on Instagram\n- `is_verified` — `true` if the account has a verified badge\n- `is_private` — `true` if the account is private\n- `followers_count` — number of followers\n- `following_count` — number of accounts followed\n- `external_urls` — links listed in the bio (empty list if none)\n\n## Output per post\n\nOne record per post when `maxPosts` is greater than `0`.\n\n- `post_url` — direct link to the post\n- `status` — `success`, `post_not_found`, `post_age_restricted`, `post_is_private`, `error`, `blocked` or `invalid_url`\n- `author_meta` — the profile object described above\n- `shortcode` — Instagram's short ID for the post\n- `post_id` — Instagram's numeric media ID\n- `username` — username of the post author\n- `caption` — full caption text\n- `hashtags` — hashtags found in the caption\n- `mentions` — @mentions found in the caption\n- `tagged_users` — accounts tagged in the post\n- `collaborators` — accounts listed as co-authors\n- `caption_is_edited` — `true` if the caption was edited after posting\n- `pub_date` — publication date and time (ISO 8601)\n- `media_type` — `Photo`, `Video`, `Carousel`, `Reel` or `IGTV`\n- `media_count` — number of images / videos in the post\n- `thumbnail_url` — cover image URL\n- `media_items` — every image or video in the post, in order, each with `index`, `type`, `url`, `width` and `height`; videos also carry `duration` and `has_audio`\n- `accessibility_caption` — Instagram's automatic alt-text for the media\n- `like_count` — number of likes\n- `comment_count` — number of comments\n- `likes_hidden` — `true` if the author hid the like count\n- `comments_disabled` — `true` if comments are turned off\n- `location` — tagged location, when there is one\n- `music` — audio attribution, when there is one (mostly reels)\n- `scraped_at` — when the record was collected (ISO 8601)\n\nOnly `success` posts carry the full set of fields. Posts with any other status contain just `post_url`, `status` and `author_meta`. The `status` values mean:\n\n- `success` — the post was collected in full\n- `post_not_found` — the post no longer exists or is not available\n- `post_age_restricted` — Instagram restricts the post to older viewers\n- `post_is_private` — the post belongs to a private account\n- `blocked` — Instagram refused the request for that post\n- `invalid_url` — the post link was not a valid Instagram post URL\n- `error` — something else went wrong while collecting that post\n\nA profile that could not be scraped gets a record with a `status` that names the cause and only the `username` and `profile_url` (a private profile also shows the public details above). The explanation is in the run log, one line per profile, followed by a closing `Done:` summary, and the run moves on to the next username. The profile statuses are `profile_not_found`, `profile_is_private`, `profile_age_restricted` (an age check, for example alcohol brands), `profile_restricted` (\"unavailable for certain audiences\"), `cookies_unusable` (a private or restricted profile needed your cookies and Instagram did not accept them), `blocked` and `error`; a scraped profile is `success`. The post statuses are listed under Output per post. While the run is going, the status message shows a live count such as `Scraped 2/5 profiles`.\n\n### Profile field availability\n\nThe profile details are read the way a visitor who is not signed in sees them. Instagram shows that visitor the name, bio, picture, verified and private flags, the exact follower and following counts and the bio links. The post count is in the page description: exact up to 9,999 posts, and rounded to whole thousands from 10,000 posts (Instagram writes \"32K Posts\", so `posts_count` is 32000). It does not show the business flag, the category or a business email and phone, so those are not in the record. A private profile shows the same details.\n\n| `author_meta` field | Available |\n|---|---|\n| `username`, `full_name`, `biography`, `profile_pic_url`, `profile_url`, `is_verified`, `is_private`, `followers_count`, `following_count`, `external_urls` | Yes |\n| `posts_count` | Yes. When the profile has 10,000 posts or more, an approximate post count is given instead of the exact one: Instagram only gives a figure rounded to whole thousands (32K becomes 32000). Below 10,000 it is exact. It comes from a cached copy and can lag a little |\n| `is_business`, `category`, `email`, `phone` | No (shown by Instagram only to signed-in visitors) |\n\n## Authentication\n\nPublic profiles and public posts need no sign-in, however many posts you ask for: a profile is always read first the way Instagram shows it to a visitor who is not signed in, even when you give cookies. Only a private profile (your account must follow it) and age-restricted posts need a signed-in view, and only your own cookies can give one. Export your instagram.com cookies as JSON from a logged-in browser session using any cookie-export browser extension, then paste the JSON into the optional `cookies` field. The field is a secret input, so the Apify Console hides and encrypts it, and the cookies are used only during your run. Before anything is read with them, the actor asks Instagram whether it recognises the cookies; if they are invalid, expired or signed out, the run log says so. Without cookies those cases are reported with their status. The actor does not sign in with any account of its own.\n\nIf your cookies expire mid-run, re-export them from your browser and restart the actor.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `usernames` | array of strings | – (required) | Instagram usernames to scrape, with or without `@`, or profile links such as `https://www.instagram.com/natgeo/`. At least one is needed |\n| `maxPosts` | integer | `12` | Posts to collect per profile, from `0` to `500`. Posts left out by the two filters below do not count. `0` returns profile data only |\n| `newerThan` | string | – | Optional date (`YYYY-MM-DD`). Posts published before it are skipped. Empty means no date filter. It must be from 2000-01-01 up to the day before the run, otherwise it is ignored with a warning in the log. The date is read from the post's id, so it can be off by up to a day |\n| `skipPinnedPosts` | boolean | `false` | Leave out the posts a profile has pinned to the top of its grid. Instagram does not mark pinned posts for a visitor who is not signed in, so they are recognised by their place and date; a pinned post that is also the profile's newest post cannot be told apart and stays in |\n| `cookies` | string (secret) | – | Optional. Your own Instagram cookies as JSON, used for private profiles your account follows and age-restricted posts. See Authentication |\n\n### Example: quick look at one brand\n\n```json\n{\n  \"usernames\": [\"nike\"],\n  \"maxPosts\": 12\n}\n```\n\n### Example: compare several publishers side by side\n\n```json\n{\n  \"usernames\": [\"natgeo\", \"@nytimes\", \"bbcnews\"],\n  \"maxPosts\": 30\n}\n```\n\n### Example: account details only for a vetting list\n\n```json\n{\n  \"usernames\": [\"nasa\", \"spacex\", \"esa\"],\n  \"maxPosts\": 0\n}\n```\n\n### Example: deep pull with your own cookies\n\n```json\n{\n  \"usernames\": [\"redbull\"],\n  \"maxPosts\": 500,\n  \"cookies\": \"<your cookies JSON>\"\n}\n```\n\n## Example output\n\nA profile-only record (`maxPosts: 0`); the values are illustrative.\n\n```json\n{\n  \"status\": \"success\",\n  \"author_meta\": {\n    \"username\": \"examplebrand\",\n    \"full_name\": \"Example Brand\",\n    \"biography\": \"Better ingredients, better you\",\n    \"profile_pic_url\": \"https://.../profile.jpg\",\n    \"is_verified\": true,\n    \"is_private\": false,\n    \"followers_count\": 30213,\n    \"following_count\": 12,\n    \"profile_url\": \"https://www.instagram.com/examplebrand/\",\n    \"external_urls\": [\"https://example.com/shop\"]\n  }\n}\n```\n\n## Use cases\n\n- **Influencer marketers** — check follower counts, verification and posting activity before signing a creator\n- **Agency account managers** — compare a client's profile and recent posts with competitors in one export\n- **Social media analysts** — see which post types, captions and hashtags earn the most likes and comments\n- **Partnership teams** — vet creators and brands in a niche by their bio, follower counts and bio links before contacting them individually\n- **Brand and PR teams** — audit how tagged collaborators appear on a brand's feed\n- **Academic researchers** — gather public captions, hashtags, locations and engagement counts for communication studies\n\n## Responsible use\n\nThe data this actor returns is publicly available on Instagram, but bios (which can hold contact details), names, photos and tagged accounts can still identify real people. Before you collect or store them you need a lawful basis (for example under the GDPR), and you should keep only what your purpose requires. Do not use the results to profile, track or target minors, and do not use them to single out people by special categories of personal data such as health, religion, political opinion or sexual orientation. Contact details found on a profile are meant for the business purpose they were published for, not for unsolicited bulk messaging.\n\n## FAQ\n\n**Do I need an Instagram account?**\nNo, not for public profiles. Only private profiles and age-restricted posts need cookies, and you can paste your own in the optional `cookies` field (see Authentication above).\n\n**Can it scrape private accounts?**\nOnly with your own cookies, from an account that follows it. Without cookies you get one record with the public profile details and the status `profile_is_private`.\n\n**How many posts can I get per profile?**\nUp to 500 per profile in one run. Use `maxPosts` to choose any number from `1` to `500`, or `0` for profile details only. Accounts with fewer posts simply return fewer.\n\n**Which post types are included?**\nPhotos, videos, reels, carousels and IGTV. For carousels, every slide is listed in `media_items`, in order.\n\n**Why are `email`, `phone`, `category` and `is_business` missing, and is `posts_count` exact?**\nThe first four are shown by Instagram only to signed-in visitors, and the actor reads profiles without signing in. `posts_count` is exact below 10,000 posts. When a profile has 10,000 posts or more, an approximate post count is given instead: Instagram writes it as an abbreviation such as \"32K\", and the actor turns it into 32000 (see Profile field availability).\n\n**What happens if a username does not exist or fails?**\nThat username gets a record with a `status` such as `profile_not_found` or `error` (the log explains it), and the run continues with the rest of your list.\n\n**How current is the data?**\nIt is collected live when you run the actor, so follower counts, likes and comments reflect that moment.\n\n**Do I need to set up a proxy?**\nNo. The actor handles its connection to Instagram automatically. Just enter your usernames and run it.\n\n**Is this affiliated with Instagram or Meta?**\nNo. It is an independent tool that works with publicly available profile data. It is not affiliated with, endorsed by or sponsored by Instagram or Meta Platforms, Inc.\n"
    },
    "buildNumber": "0.0.10",
    "imageDigest": "5556c463d024fd6e217afdd5d147673854d30d5db726cd8ab92c9a20159fddd0",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "0.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.03442
    }
  }
}