{
  "openapi": "3.0.1",
  "info": {
    "title": "Facebook Groups Posts Scraper",
    "description": "Scrape the posts of public Facebook groups, newest first, no account needed: text, author, date, reactions by type, comments, photos, videos, links, sale listings. Filters by date, keywords and reactions, new posts only. Export to JSON, CSV or Excel.",
    "version": "0.0",
    "x-build-id": "E7bkhAin9l6qLDjtz"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nice_dev~facebook-groups-posts-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nice_dev-facebook-groups-posts-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/nice_dev~facebook-groups-posts-scraper/runs": {
      "post": {
        "operationId": "runs-sync-nice_dev-facebook-groups-posts-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/nice_dev~facebook-groups-posts-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-nice_dev-facebook-groups-posts-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "startUrls": {
            "title": "Facebook groups",
            "maxItems": 1000,
            "type": "array",
            "description": "Links to public Facebook groups (`https://www.facebook.com/groups/selftaughtprogrammers/`) or to a post of the group (`https://www.facebook.com/groups/selftaughtprogrammers/posts/10166280720354467/`). The link of Facebook's Share / Copy link button (`https://www.facebook.com/share/g/1AbCdEfGhI/`) works too: the run follows it to the group; if it leads to anything but a group, only that link is skipped (message in the log) and you can paste the address the browser ends on instead. Only links here: a group ID or name goes in **Group IDs or names** below. A post link reads its whole group, up to **Max posts**. Private groups cannot be read: they are skipped with a message in the log. Max 1 000 groups.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "groupIds": {
            "title": "Group IDs or names",
            "maxItems": 1000,
            "uniqueItems": true,
            "type": "array",
            "description": "Groups given by their ID (`387875758242831`) or by their name, the last part of the group link (`selftaughtprogrammers`). Read like the links above, a group given twice is read once. Max 1 000 groups in all, with **Facebook groups**.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max posts",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum number of posts to save for the whole run (after deduplication and filters). 0 = no limit.",
            "default": 100
          },
          "maxItemsPerQuery": {
            "title": "Max posts per group",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Cap for EACH group, so that the first group cannot use up the whole **Max posts** budget. 0 = no per-group cap.",
            "default": 0
          },
          "includeGroupDetails": {
            "title": "Group details",
            "type": "boolean",
            "description": "Read each group's About page once (1 extra page per group) and add `groupDetails` to its posts: exact member count, posts in the last day, creation date, privacy, description, location and rules. Charged once per group (see Pricing).",
            "default": false
          },
          "extractContacts": {
            "title": "Contacts found in posts",
            "type": "boolean",
            "description": "Look for e-mail addresses and phone numbers in each post's text (and in the text of the post it shares) and return them in `emails` and `phones`. The author's contact button (WhatsApp, Messenger or a link, `actionLink`) is returned only with this option; its WhatsApp number counts as a phone. Charged only for the posts where at least one is found (see Pricing).",
            "default": false
          },
          "includeComments": {
            "title": "All comments",
            "type": "boolean",
            "description": "Read ALL the first-level comments of each post (Facebook gives 3 per request, so a long thread takes a while) and return them in `comments`: text, author, date, reactions and the number of replies (`repliesCount`; tick **Replies to comments** to read the replies themselves, see `includeReplies`). The `topComments` Facebook shows under every post stay free. Charged per comment saved (see Pricing).",
            "default": false
          },
          "maxCommentsPerPost": {
            "title": "Max comments per post",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "With **All comments**: the most comments kept for ONE post, from 1 to 5 000. A post with more is cut there (and you pay for the comments saved only). A post's row is also kept under 8 MB: past that the last comments and replies are dropped (and not charged), and the log says how many posts were cut.",
            "default": 100
          },
          "includeReplies": {
            "title": "Replies to comments",
            "type": "boolean",
            "description": "Also read the replies to each comment, and the replies to those replies (two levels: the deepest Facebook shows), and return them in `replies`, inside the comment and inside each reply (same fields, plus `parentCommentId`). Only works together with **All comments**: ticked alone, nothing more is read. One extra request per comment or reply that has replies, so a busy thread takes longer. Each reply saved, at either level, is charged like a comment (see Pricing).",
            "default": false
          },
          "maxRepliesPerComment": {
            "title": "Max replies per comment",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "With **Replies to comments**: the most replies kept for ONE comment, and for ONE reply (its replies), from 1 to 1 000. A comment or a reply with more is cut there (and you pay for the replies saved only).",
            "default": 20
          },
          "expandAlbums": {
            "title": "Complete albums",
            "type": "boolean",
            "description": "Facebook lists only the first 5 photos of an album in a group's feed. Open the album of each post that has more photos and add the others to `images` and `attachments` (1 extra page per album). Posts with 5 photos or less cost nothing more. Charged once per album opened (see Pricing).",
            "default": false
          },
          "includeListingLocation": {
            "title": "Listing location (buy and sell groups)",
            "type": "boolean",
            "description": "For each item for sale in a buy-and-sell group, read where it is and fill `listing.location`: city, state, the place as the seller shows it, latitude and longitude (1 extra page per listing). Posts that are not for sale cost nothing more. Charged per post saved with its location (an item posted twice: its page read once, charged with each post; see Pricing).",
            "default": false
          },
          "postedAfter": {
            "title": "Posted after",
            "type": "string",
            "description": "Only posts published on or after this date: `2026-09-01`, or a period before now such as `7 days`, `2 weeks`, `1 month` (API: `24 hours` and full ISO date-times work too). Reads the post's publication time (for groups that approve posts, the time of approval). Posts come newest first, so the group stops at the first older post."
          },
          "postedBefore": {
            "title": "Posted before",
            "type": "string",
            "description": "Only posts published on or before this date (the whole day is included), or older than a period such as `30 days`. Newer posts are skipped without being saved."
          },
          "onlyListings": {
            "title": "Only buy-and-sell listings",
            "type": "boolean",
            "description": "In groups with a sale section, read only the items for sale (Facebook's listings feed, newest first) and fill `listing` (title, price, currency, sold or not). Some groups have no listings feed: such a group is skipped with a message that says so (clear this box to read its posts), and the other groups are read.",
            "default": false
          },
          "keywords": {
            "title": "Keywords",
            "maxItems": 50,
            "uniqueItems": true,
            "type": "array",
            "description": "Only posts whose text (or the text of the post they share) contains at least one of these words or phrases (case and accents ignored). Facebook has no in-group search without a login, so the Actor reads the group and keeps the matching posts: a rare word reads far back (about 12,000 posts with Max posts 100, the whole group with no cap), each dropped post charged the filter fee — add **Posted after** to bound it. Empty = all posts.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Exclude keywords",
            "maxItems": 50,
            "uniqueItems": true,
            "type": "array",
            "description": "Drop the posts whose text contains one of these words (case and accents ignored).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minReactions": {
            "title": "Min reactions",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Only posts with at least this many reactions (all types). 0 = no minimum.",
            "default": 0
          },
          "minComments": {
            "title": "Min comments",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Only posts with at least this many comments. 0 = no minimum.",
            "default": 0
          },
          "onlyWithContact": {
            "title": "Only posts with a contact",
            "type": "boolean",
            "description": "Keep only the posts where an e-mail address or a phone number was found. Needs **Contacts found in posts** to be ticked too: without it the run is refused.",
            "default": false
          },
          "onlyNew": {
            "title": "Only new posts",
            "type": "boolean",
            "description": "Skip the posts that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and the group stops being read at the first one already seen. First run = everything is new.",
            "default": false
          },
          "stateKey": {
            "title": "Memory key",
            "pattern": "^[a-zA-Z0-9_-]{1,64}$",
            "maxLength": 64,
            "type": "string",
            "description": "Name of the memory used by **Only new posts**. Give each schedule / task its own key (e.g. `crypto-groups`) so that they do not share their memory. Letters, digits, `-` and `_`.",
            "default": "default"
          },
          "resetState": {
            "title": "Reset the memory",
            "type": "boolean",
            "description": "Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every post again. Untick it afterwards.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration (included proxy: paying users only)",
            "type": "object",
            "description": "Facebook only serves group posts to home (residential) IP addresses: keep **Apify Proxy** and the Actor uses residential IPs, included in the price (the proxy group, the country and **No proxy** chosen here are ignored). Your own proxies (`proxyUrls`) must be residential. On the Apify free plan the included proxy is not available: add your own proxy URLs, or the run stops at once with a message.",
            "default": {
              "useApifyProxy": true
            }
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of groups read in parallel (IP addresses taken from a pool).",
            "default": 4
          },
          "maxRequestsPerMinute": {
            "title": "Max requests per minute",
            "minimum": 10,
            "maximum": 600,
            "type": "integer",
            "description": "Most requests to Facebook in any 60 seconds, all groups together. A budget, not an even pace (spread them with the minimum delay below).",
            "default": 120
          },
          "minRequestIntervalMs": {
            "title": "Min delay between requests",
            "minimum": 0,
            "maximum": 60000,
            "type": "integer",
            "description": "Smallest gap between two requests, in milliseconds. 0 = no gap.",
            "default": 0
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Retries per request before it is marked as failed (at least 1: a feed call lost for good ends the group there). A request Facebook turns away (login wall, rate limit) is also retried on a new IP address up to 10 times without using up these retries, and the group goes on from where it stopped.",
            "default": 5
          },
          "debugLog": {
            "title": "Debug log",
            "type": "boolean",
            "description": "Include debug messages in the run log.",
            "default": false
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}