{
  "data": {
    "id": "KudCUoXaZ0RG342mm",
    "actId": "o7cusCXLyJuONdRYF",
    "userId": "zq8lKbpLzTjGDayPC",
    "startedAt": "2026-10-18T05:14:49.819Z",
    "finishedAt": "2026-10-18T05:14:53.505Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 3627,
      "runTimeSecs": 3.627,
      "computeUnits": 0.00403,
      "imageSizeBytes": 338365952
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "GK9YjZRyQZVzOdoH5",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Twitter (X) Articles Scraper\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"tweetUrls\": {\n      \"title\": \"Article announcement posts or Article links\",\n      \"type\": \"array\",\n      \"description\": \"Paste the post that announces the article (the post whose card opens the article), or the article link itself. For example https://x.com/vxunderground/status/1979885711579865307.\",\n      \"editor\": \"stringList\",\n      \"minItems\": 1,\n      \"maxItems\": 1000,\n      \"prefill\": [\n        \"https://x.com/vxunderground/status/1979885711579865307\"\n      ],\n      \"example\": [\n        \"https://x.com/vxunderground/status/1979885711579865307\",\n        \"https://x.com/i/article/1979885711579865307\",\n        \"https://x.com/NASA/status/2075599612610535438\"\n      ]\n    },\n    \"includeArticleBody\": {\n      \"title\": \"Include full article body\",\n      \"type\": \"boolean\",\n      \"description\": \"Include the complete article text: bodyText, bodyMarkdown, the rich content blocks, inline media and links.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeAnnouncementPost\": {\n      \"title\": \"Include announcement post\",\n      \"type\": \"boolean\",\n      \"description\": \"Attach the full announcement post (text, author, metrics, media) to every article row.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeAuthorProfile\": {\n      \"title\": \"Include full author profile\",\n      \"type\": \"boolean\",\n      \"description\": \"Enrich the author with their public profile (follower count, bio, verification, join date) so engagementRate can be computed.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeCoverImage\": {\n      \"title\": \"Include cover image\",\n      \"type\": \"boolean\",\n      \"description\": \"Include the article's cover image link.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includePreviewText\": {\n      \"title\": \"Include preview text\",\n      \"type\": \"boolean\",\n      \"description\": \"Include the short preview text X shows for the article.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"maxItems\": {\n      \"title\": \"Maximum articles\",\n      \"type\": \"integer\",\n      \"description\": \"Stop after this many article rows. Status rows are not counted.\",\n      \"default\": 1000,\n      \"prefill\": 3,\n      \"minimum\": 1,\n      \"maximum\": 1000\n    }\n  },\n  \"required\": [\n    \"tweetUrls\"\n  ]\n}",
    "readme": "# X Article Announcement Post Metadata Collector\n\nX Articles are long-form posts that live behind a card on a regular post — the \"announcement post.\" This actor takes that announcement post (or the article's own link) and returns the article's **full text** — as plain text, Markdown, and rich content blocks — plus its title, preview, cover image, dates, inline media, resolved links, and the announcement post with its author and engagement metrics. No login required. Article reading on x.com itself is behind a sign-in wall; this actor reads the public article payload X still serves to logged-out pages.\n\n## What this actor does\n\n- **Full article body:** `bodyText`, `bodyMarkdown`, the raw `contentBlocks` (with headings, lists, quotes, links and inline images), resolved `links` and inline `media`\n- **Article lookup by announcement post or article link:** paste the post that opens the article, or an article link\n- **Public metadata:** `articleId`, `articleUrl`, `title`, `previewText`, `coverImageUrl` (with dimensions), `publishedAt`, `modifiedAt`\n- **Announcement post:** optional full post row (text, author, metrics, media) attached to each article\n- **Author and engagement:** the author's public profile with `authorFollowers`, plus a derived `engagementRate` and post-level `likeCount` / `replyCount` / `retweetCount` / `quoteCount` / `bookmarkCount` / `viewCount`\n- **Honest provenance:** `bodyAvailable` and `bodySource` (`x` or `fxtwitter`) tell you exactly whether and where the body came from\n- **Status rows:** invalid links, deleted posts, posts without an article, raw article links that X cannot map, and body-less articles all produce an explicit `status` row with a message\n- **Empty fields are omitted** — the dataset never contains `null`, `\"\"`, `[]` or `{}`\n\n## Output per article\n\n- `articleId` — X's article ID\n- `articleUrl` — canonical article link (opens for signed-in readers)\n- `title` — article title\n- `previewText` — the short preview text X shows for the article (omitted when **Include preview text** is off)\n- `coverImageUrl`, `coverImageWidth`, `coverImageHeight` — cover image and dimensions (omitted when **Include cover image** is off)\n- `bodyAvailable` — `true` when the full body was collected\n- `bodyText` — complete article text\n- `bodyMarkdown` — the same body converted to Markdown (headings, lists, quotes, links, images)\n- `contentBlocks` — the raw rich-text blocks (`type`, `text`, ranges) for custom rendering\n- `links[]` — `{text, url}` for every link inside the article\n- `media[]` — inline images `{url, width, height, mediaId, position}`\n- `bodySource` — `x` when the body came from X's own article payload, `fxtwitter` when the public mirror was used\n- `publishedAt`, `modifiedAt` — publication and last-modification timestamps\n- `sourceTweetId`, `sourceTweetUrl` — the announcement post\n- `author`, `authorFollowers` — the author's public profile and follower count\n- `language` — post language code\n- `announcementTweet` — the full announcement post when **Include announcement post** is on\n- `likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `bookmarkCount`, `viewCount` — announcement post metrics\n- `engagementRate` — derived `(likes + retweets + replies) / followers` as a percentage; present only when the follower count is known\n- `type: \"article\"`, `collectedAt`\n\n### Sample record\n\n```json\n{\n  \"type\": \"article\",\n  \"articleId\": \"1979875955100258304\",\n  \"articleUrl\": \"https://x.com/i/article/1979875955100258304\",\n  \"title\": \"Wtf are these Threat Actors doing? XUbuntu malware is dumb and stinky\",\n  \"previewText\": \"Yesterday night before I went to bed I saw @sysadafterdark write they suspected...\",\n  \"coverImageUrl\": \"https://pbs.twimg.com/media/G3n2yXwW8AALy8G.jpg\",\n  \"bodyAvailable\": true,\n  \"bodyText\": \"Yesterday night before I went to bed I saw @sysadafterdark write they suspected Xubuntu-dot-org was compromised...\",\n  \"bodyMarkdown\": \"Yesterday night before I went to bed I saw [@sysadafterdark](https://x.com/sysadafterdark) write...\",\n  \"bodySource\": \"x\",\n  \"publishedAt\": \"2025-10-19T12:21:52+00:00\",\n  \"sourceTweetId\": \"1979885711579865307\",\n  \"sourceTweetUrl\": \"https://x.com/i/status/1979885711579865307\",\n  \"author\": { \"username\": \"vxunderground\", \"name\": \"vx-underground\", \"followers\": 454667 },\n  \"authorFollowers\": 454667,\n  \"likeCount\": 554,\n  \"engagementRate\": 0.1381,\n  \"collectedAt\": \"2026-10-17T00:00:00+00:00\"\n}\n```\n\n## Output per status row\n\nA `status` row is emitted when an input cannot be collected (or when a body could not be attached). It always has a `message`:\n\n- `type: \"status\"`\n- `status` — `noInput`, `invalidLink`, `notFound`, `articleLinkUnmapped`, `noArticle`, `bodyUnavailable`, `rateLimited` or `error`\n- `tweetUrl`, `tweetId` — the input it applies to\n- `collectedAt`\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `tweetUrls` | array | – | **Required.** Announcement post links (`x.com/<user>/status/<id>`), post IDs, or article links (`x.com/i/article/<id>`). |\n| `includeArticleBody` | boolean | `true` | Include the full article text, Markdown, rich blocks, links and inline media. |\n| `includeAnnouncementPost` | boolean | `true` | Attach the full announcement post (text, author, metrics, media) to every article row. |\n| `includeAuthorProfile` | boolean | `true` | Enrich the author with their public profile (follower count, bio, verification) so `engagementRate` can be computed. |\n| `includeCoverImage` | boolean | `true` | Include the article's cover image link and dimensions. |\n| `includePreviewText` | boolean | `true` | Include X's short preview text for the article. |\n| `maxItems` | integer | `1000` | Stop after this many article rows (1–1000). Status rows are not counted. |\n\n### Example: one announcement post\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/vxunderground/status/1979885711579865307\"]\n}\n```\n\n### Example: several articles, metadata and body\n\n```json\n{\n  \"tweetUrls\": [\n    \"https://x.com/vxunderground/status/1979885711579865307\",\n    \"https://x.com/thedankoe/status/2010751592346030461\"\n  ],\n  \"maxItems\": 10\n}\n```\n\n### Example: metadata only, no body\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/satyanadella/status/2066182223213293753\"],\n  \"includeArticleBody\": false,\n  \"includeAnnouncementPost\": false\n}\n```\n\n### Example: article link form\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/i/article/1979885711579865307\"],\n  \"includeAnnouncementPost\": true\n}\n```\n\n## Use cases\n\n- **LLM and RAG pipelines** — feed complete X Articles as Markdown into vector stores, NotebookLM, or chat assistants\n- **Content intelligence** — track which articles a set of accounts is publishing, with titles, bodies and cover images\n- **Media monitoring** — collect article announcements alongside their engagement metrics\n- **Research and archiving** — keep a structured, full-text index of public X Articles and their authors\n- **Competitive analysis** — compare article output and performance across creators or brands\n- **Newsroom workflows** — enrich a list of announcement posts with full article text and metadata\n\n## Limitations\n\n- **Raw article links cannot be resolved on their own.** X maps an article to its announcement post only for signed-in readers; for everyone else the article page is a sign-in wall. When you paste `x.com/i/article/<id>`, the actor returns an `articleLinkUnmapped` status row and tells you to paste the announcement post instead.\n- **An account's full article list is not available without signing in.** X's article tab is behind a login and article pages are not indexed by search engines, so paste the announcement links you need (or schedule the actor on the ones you care about).\n- **The body fallback is a public mirror.** X occasionally withholds an article payload for older posts; the actor then reads the same article from the public FxTwitter mirror and marks the row with `bodySource: \"fxtwitter\"` so you always know where the text came from. If every source fails, the row keeps its metadata and a `bodyUnavailable` status row is added.\n- **Posts that X removed or editors replaced** can return their newest state only; deleted articles cannot be recovered cookielessly.\n\n## FAQ\n\n**Does this actor return the full article text, or just the preview?**  The full text. X still serves the complete article payload to logged-out clients; the actor collects it as `bodyText`, `bodyMarkdown` and `contentBlocks`, and says `bodyAvailable: true`. The Markdown keeps headings, lists, quotes, links and images, and also renders embedded posts, code blocks and math. If X ever withholds a body, the actor says so via `bodyUnavailable` instead of guessing.\n\n**What is `bodySource`?**  Where the body came from. `x` means X's own public article payload; `fxtwitter` means the public FxTwitter mirror was used as a fallback because X's payload was unavailable at that moment.\n\n**Which links can I paste?**  The announcement post — `https://x.com/<user>/status/<id>` — is the reliable input. Raw `https://x.com/i/article/<id>` links cannot be resolved cookielessly (X maps article IDs to posts only for signed-in readers), so when they cannot be resolved the actor returns an `articleLinkUnmapped` status row explaining what to paste instead.\n\n**How do I find the announcement post for an article?**  Open the article and use the post whose card opens it; the link is usually shared alongside the article.\n\n**What happens with posts that are not articles?**  You get a `noArticle` status row. Deleted or private posts return a `notFound` status row.\n\n**Can I get every article an account published?**  Not cookielessly — X shows an account's article list only to signed-in readers, and article pages are not indexable. Paste the announcement links you need; the actor collects each one.\n\n**Do I need an X account, login or developer key?**  No. The actor reads only public article and post data, and there is no credential input at all.\n\n**How fresh is the data?**  Live — every run reads X at request time. Schedule the actor for daily or weekly refreshes.\n\n**How do I integrate the results?**  Use the dataset from the run page, the Apify API, webhooks, or a no-code connection such as Zapier, Make or Google Sheets.\n\n**Is this affiliated with X?**  No. This is a third-party actor that reads publicly available article and post data and is not affiliated with or endorsed by X Corp.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "x-article-announcement-post-metadata-collector",
      "title": "X Article Announcement Post Metadata Collector",
      "description": "Turn an X (Twitter) article's announcement post or article link into the full article: full text and Markdown, title, preview, cover image, publish dates, inline media, links, plus the announcement post with its author, metrics and engagement rate.",
      "seoTitle": "X Article Announcement Post Metadata Collector",
      "seoDescription": "Turn an X (Twitter) Article announcement post into its full text and Markdown plus title, preview, cover image, dates, author and engagement metrics.",
      "version": "1.0",
      "buildTag": "latest",
      "dockerfile": "./Dockerfile",
      "readme": "# X Article Announcement Post Metadata Collector\n\nX Articles are long-form posts that live behind a card on a regular post — the \"announcement post.\" This actor takes that announcement post (or the article's own link) and returns the article's **full text** — as plain text, Markdown, and rich content blocks — plus its title, preview, cover image, dates, inline media, resolved links, and the announcement post with its author and engagement metrics. No login required. Article reading on x.com itself is behind a sign-in wall; this actor reads the public article payload X still serves to logged-out pages.\n\n## What this actor does\n\n- **Full article body:** `bodyText`, `bodyMarkdown`, the raw `contentBlocks` (with headings, lists, quotes, links and inline images), resolved `links` and inline `media`\n- **Article lookup by announcement post or article link:** paste the post that opens the article, or an article link\n- **Public metadata:** `articleId`, `articleUrl`, `title`, `previewText`, `coverImageUrl` (with dimensions), `publishedAt`, `modifiedAt`\n- **Announcement post:** optional full post row (text, author, metrics, media) attached to each article\n- **Author and engagement:** the author's public profile with `authorFollowers`, plus a derived `engagementRate` and post-level `likeCount` / `replyCount` / `retweetCount` / `quoteCount` / `bookmarkCount` / `viewCount`\n- **Honest provenance:** `bodyAvailable` and `bodySource` (`x` or `fxtwitter`) tell you exactly whether and where the body came from\n- **Status rows:** invalid links, deleted posts, posts without an article, raw article links that X cannot map, and body-less articles all produce an explicit `status` row with a message\n- **Empty fields are omitted** — the dataset never contains `null`, `\"\"`, `[]` or `{}`\n\n## Output per article\n\n- `articleId` — X's article ID\n- `articleUrl` — canonical article link (opens for signed-in readers)\n- `title` — article title\n- `previewText` — the short preview text X shows for the article (omitted when **Include preview text** is off)\n- `coverImageUrl`, `coverImageWidth`, `coverImageHeight` — cover image and dimensions (omitted when **Include cover image** is off)\n- `bodyAvailable` — `true` when the full body was collected\n- `bodyText` — complete article text\n- `bodyMarkdown` — the same body converted to Markdown (headings, lists, quotes, links, images)\n- `contentBlocks` — the raw rich-text blocks (`type`, `text`, ranges) for custom rendering\n- `links[]` — `{text, url}` for every link inside the article\n- `media[]` — inline images `{url, width, height, mediaId, position}`\n- `bodySource` — `x` when the body came from X's own article payload, `fxtwitter` when the public mirror was used\n- `publishedAt`, `modifiedAt` — publication and last-modification timestamps\n- `sourceTweetId`, `sourceTweetUrl` — the announcement post\n- `author`, `authorFollowers` — the author's public profile and follower count\n- `language` — post language code\n- `announcementTweet` — the full announcement post when **Include announcement post** is on\n- `likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `bookmarkCount`, `viewCount` — announcement post metrics\n- `engagementRate` — derived `(likes + retweets + replies) / followers` as a percentage; present only when the follower count is known\n- `type: \"article\"`, `collectedAt`\n\n### Sample record\n\n```json\n{\n  \"type\": \"article\",\n  \"articleId\": \"1979875955100258304\",\n  \"articleUrl\": \"https://x.com/i/article/1979875955100258304\",\n  \"title\": \"Wtf are these Threat Actors doing? XUbuntu malware is dumb and stinky\",\n  \"previewText\": \"Yesterday night before I went to bed I saw @sysadafterdark write they suspected...\",\n  \"coverImageUrl\": \"https://pbs.twimg.com/media/G3n2yXwW8AALy8G.jpg\",\n  \"bodyAvailable\": true,\n  \"bodyText\": \"Yesterday night before I went to bed I saw @sysadafterdark write they suspected Xubuntu-dot-org was compromised...\",\n  \"bodyMarkdown\": \"Yesterday night before I went to bed I saw [@sysadafterdark](https://x.com/sysadafterdark) write...\",\n  \"bodySource\": \"x\",\n  \"publishedAt\": \"2025-10-19T12:21:52+00:00\",\n  \"sourceTweetId\": \"1979885711579865307\",\n  \"sourceTweetUrl\": \"https://x.com/i/status/1979885711579865307\",\n  \"author\": { \"username\": \"vxunderground\", \"name\": \"vx-underground\", \"followers\": 454667 },\n  \"authorFollowers\": 454667,\n  \"likeCount\": 554,\n  \"engagementRate\": 0.1381,\n  \"collectedAt\": \"2026-10-17T00:00:00+00:00\"\n}\n```\n\n## Output per status row\n\nA `status` row is emitted when an input cannot be collected (or when a body could not be attached). It always has a `message`:\n\n- `type: \"status\"`\n- `status` — `noInput`, `invalidLink`, `notFound`, `articleLinkUnmapped`, `noArticle`, `bodyUnavailable`, `rateLimited` or `error`\n- `tweetUrl`, `tweetId` — the input it applies to\n- `collectedAt`\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `tweetUrls` | array | – | **Required.** Announcement post links (`x.com/<user>/status/<id>`), post IDs, or article links (`x.com/i/article/<id>`). |\n| `includeArticleBody` | boolean | `true` | Include the full article text, Markdown, rich blocks, links and inline media. |\n| `includeAnnouncementPost` | boolean | `true` | Attach the full announcement post (text, author, metrics, media) to every article row. |\n| `includeAuthorProfile` | boolean | `true` | Enrich the author with their public profile (follower count, bio, verification) so `engagementRate` can be computed. |\n| `includeCoverImage` | boolean | `true` | Include the article's cover image link and dimensions. |\n| `includePreviewText` | boolean | `true` | Include X's short preview text for the article. |\n| `maxItems` | integer | `1000` | Stop after this many article rows (1–1000). Status rows are not counted. |\n\n### Example: one announcement post\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/vxunderground/status/1979885711579865307\"]\n}\n```\n\n### Example: several articles, metadata and body\n\n```json\n{\n  \"tweetUrls\": [\n    \"https://x.com/vxunderground/status/1979885711579865307\",\n    \"https://x.com/thedankoe/status/2010751592346030461\"\n  ],\n  \"maxItems\": 10\n}\n```\n\n### Example: metadata only, no body\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/satyanadella/status/2066182223213293753\"],\n  \"includeArticleBody\": false,\n  \"includeAnnouncementPost\": false\n}\n```\n\n### Example: article link form\n\n```json\n{\n  \"tweetUrls\": [\"https://x.com/i/article/1979885711579865307\"],\n  \"includeAnnouncementPost\": true\n}\n```\n\n## Use cases\n\n- **LLM and RAG pipelines** — feed complete X Articles as Markdown into vector stores, NotebookLM, or chat assistants\n- **Content intelligence** — track which articles a set of accounts is publishing, with titles, bodies and cover images\n- **Media monitoring** — collect article announcements alongside their engagement metrics\n- **Research and archiving** — keep a structured, full-text index of public X Articles and their authors\n- **Competitive analysis** — compare article output and performance across creators or brands\n- **Newsroom workflows** — enrich a list of announcement posts with full article text and metadata\n\n## Limitations\n\n- **Raw article links cannot be resolved on their own.** X maps an article to its announcement post only for signed-in readers; for everyone else the article page is a sign-in wall. When you paste `x.com/i/article/<id>`, the actor returns an `articleLinkUnmapped` status row and tells you to paste the announcement post instead.\n- **An account's full article list is not available without signing in.** X's article tab is behind a login and article pages are not indexed by search engines, so paste the announcement links you need (or schedule the actor on the ones you care about).\n- **The body fallback is a public mirror.** X occasionally withholds an article payload for older posts; the actor then reads the same article from the public FxTwitter mirror and marks the row with `bodySource: \"fxtwitter\"` so you always know where the text came from. If every source fails, the row keeps its metadata and a `bodyUnavailable` status row is added.\n- **Posts that X removed or editors replaced** can return their newest state only; deleted articles cannot be recovered cookielessly.\n\n## FAQ\n\n**Does this actor return the full article text, or just the preview?**  The full text. X still serves the complete article payload to logged-out clients; the actor collects it as `bodyText`, `bodyMarkdown` and `contentBlocks`, and says `bodyAvailable: true`. The Markdown keeps headings, lists, quotes, links and images, and also renders embedded posts, code blocks and math. If X ever withholds a body, the actor says so via `bodyUnavailable` instead of guessing.\n\n**What is `bodySource`?**  Where the body came from. `x` means X's own public article payload; `fxtwitter` means the public FxTwitter mirror was used as a fallback because X's payload was unavailable at that moment.\n\n**Which links can I paste?**  The announcement post — `https://x.com/<user>/status/<id>` — is the reliable input. Raw `https://x.com/i/article/<id>` links cannot be resolved cookielessly (X maps article IDs to posts only for signed-in readers), so when they cannot be resolved the actor returns an `articleLinkUnmapped` status row explaining what to paste instead.\n\n**How do I find the announcement post for an article?**  Open the article and use the post whose card opens it; the link is usually shared alongside the article.\n\n**What happens with posts that are not articles?**  You get a `noArticle` status row. Deleted or private posts return a `notFound` status row.\n\n**Can I get every article an account published?**  Not cookielessly — X shows an account's article list only to signed-in readers, and article pages are not indexable. Paste the announcement links you need; the actor collects each one.\n\n**Do I need an X account, login or developer key?**  No. The actor reads only public article and post data, and there is no credential input at all.\n\n**How fresh is the data?**  Live — every run reads X at request time. Schedule the actor for daily or weekly refreshes.\n\n**How do I integrate the results?**  Use the dataset from the run page, the Apify API, webhooks, or a no-code connection such as Zapier, Make or Google Sheets.\n\n**Is this affiliated with X?**  No. This is a third-party actor that reads publicly available article and post data and is not affiliated with or endorsed by X Corp.\n",
      "input": {
        "title": "Twitter (X) Articles Scraper",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "tweetUrls": {
            "title": "Article announcement posts or Article links",
            "type": "array",
            "description": "Paste the post that announces the article (the post whose card opens the article), or the article link itself. For example https://x.com/vxunderground/status/1979885711579865307.",
            "editor": "stringList",
            "minItems": 1,
            "maxItems": 1000,
            "prefill": [
              "https://x.com/vxunderground/status/1979885711579865307"
            ],
            "example": [
              "https://x.com/vxunderground/status/1979885711579865307",
              "https://x.com/i/article/1979885711579865307",
              "https://x.com/NASA/status/2075599612610535438"
            ]
          },
          "includeArticleBody": {
            "title": "Include full article body",
            "type": "boolean",
            "description": "Include the complete article text: bodyText, bodyMarkdown, the rich content blocks, inline media and links.",
            "default": true,
            "prefill": true
          },
          "includeAnnouncementPost": {
            "title": "Include announcement post",
            "type": "boolean",
            "description": "Attach the full announcement post (text, author, metrics, media) to every article row.",
            "default": true,
            "prefill": true
          },
          "includeAuthorProfile": {
            "title": "Include full author profile",
            "type": "boolean",
            "description": "Enrich the author with their public profile (follower count, bio, verification, join date) so engagementRate can be computed.",
            "default": true,
            "prefill": true
          },
          "includeCoverImage": {
            "title": "Include cover image",
            "type": "boolean",
            "description": "Include the article's cover image link.",
            "default": true,
            "prefill": true
          },
          "includePreviewText": {
            "title": "Include preview text",
            "type": "boolean",
            "description": "Include the short preview text X shows for the article.",
            "default": true,
            "prefill": true
          },
          "maxItems": {
            "title": "Maximum articles",
            "type": "integer",
            "description": "Stop after this many article rows. Status rows are not counted.",
            "default": 1000,
            "prefill": 3,
            "minimum": 1,
            "maximum": 1000
          }
        },
        "required": [
          "tweetUrls"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "X Article Announcement Post Metadata Collector Output",
        "type": "object",
        "properties": {
          "articles": {
            "type": "string",
            "title": "Articles",
            "description": "Collected article rows — full body text and Markdown, announcement post, author and engagement metrics — plus status rows.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "categories": [
        "SOCIAL_MEDIA"
      ],
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Articles",
              "transformation": {
                "fields": [
                  "type",
                  "title",
                  "author.username",
                  "articleId",
                  "bodyAvailable",
                  "sourceTweetUrl"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.0.3",
    "imageDigest": "6130b422c95e0218855a43d17126fa3d6d197d1390bc575abbbcc605caa865cb",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.00403
    }
  }
}