{
  "openapi": "3.0.1",
  "info": {
    "title": "Bluesky Scraper - Posts, Search and Profile Feeds",
    "description": "Scrape Bluesky posts by keyword search, @handle or profile URL. Each post includes its full text and author profile with like, repost and reply counts plus hashtags, links and media. Filter results by post language for clean exports.",
    "version": "0.1",
    "x-build-id": "otirHeNJ4Atzg06XZ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/blackfalcondata~bsky-app-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-blackfalcondata-bsky-app-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/blackfalcondata~bsky-app-scraper/runs": {
      "post": {
        "operationId": "runs-sync-blackfalcondata-bsky-app-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/blackfalcondata~bsky-app-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-blackfalcondata-bsky-app-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": {
          "query": {
            "title": "🔍 Search Term(s)",
            "type": "string",
            "description": "What to search for. Bluesky search syntax works (e.g. \"climate from:nasa.gov\", \"#openai\"). Paste a @handle, a DID or a bsky.app profile URL instead to pull that account's own posts. Required if no startUrls provided."
          },
          "language": {
            "title": "🗣️ Post Language",
            "type": "string",
            "description": "Optional ISO 639-1 code (e.g. \"en\", \"da\", \"ja\") — returns only posts written in that language. Bluesky has no location filter."
          },
          "maxResults": {
            "title": "💯 Max Results",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum total posts (0 = unlimited).",
            "default": 100
          },
          "startUrls": {
            "title": "🔗 Start URLs",
            "type": "array",
            "description": "Paste bsky.app search, profile, hashtag, post, custom-feed or list URLs. Each URL becomes its own task; results are merged and deduped across all URLs. A post URL (/profile/<handle>/post/<id>) delivers that post plus its replies (turn replies off with includeReplies); a feed URL (/profile/<handle>/feed/<id>) and a list URL (/profile/<handle>/lists/<id>) deliver that feed or list. When provided, startUrls REPLACE the search term and language fields (other URLs are skipped, and if none is supported the run stops with an input error).",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "descriptionMaxLength": {
            "title": "✂️ Max Post Text Length",
            "minimum": 0,
            "type": "integer",
            "description": "Truncate each post's text to N characters. 0 = full text.",
            "default": 0
          },
          "compact": {
            "title": "📦 Compact Output",
            "type": "boolean",
            "description": "Core fields only (for AI-agent/MCP workflows).",
            "default": false
          },
          "excludeEmptyFields": {
            "title": "Exclude empty fields from output",
            "type": "boolean",
            "description": "Drop null, empty-string, and empty-array fields from each record before push. Smaller payloads for AI agents and dashboards.",
            "default": false
          },
          "incrementalMode": {
            "title": "♻️ Incremental Mode",
            "type": "boolean",
            "description": "Compare against previous run state. stateKey is optional — defaults to a value derived from your search inputs (search terms, language, startUrls) so different searches never share state.",
            "default": false
          },
          "stateKey": {
            "title": "🔑 State Key",
            "type": "string",
            "description": "Optional. Stable identifier for the tracked search universe. Leave empty to auto-generate from search inputs."
          },
          "skipReposts": {
            "title": "🚫 Skip Reposts",
            "type": "boolean",
            "description": "When incremental, skip posts whose text matches a post that disappeared in a prior run (cross-run duplicate detection).",
            "default": false
          },
          "includeReplies": {
            "title": "💬 Include Replies",
            "type": "boolean",
            "description": "Keep replies in author feeds, feeds, lists and search results. Turn off to get top-level posts only. For a post URL it also decides whether the post's reply tree is delivered with the post.",
            "default": true
          },
          "includeReposts": {
            "title": "🔁 Include Reposts",
            "type": "boolean",
            "description": "Keep native reposts (a post another account reposted) in author feeds and feeds. Turn off to see only posts the account wrote itself.",
            "default": true
          },
          "authorFeedFilter": {
            "title": "🧭 Profile Feed Filter",
            "enum": [
              "posts_with_replies",
              "posts_no_replies",
              "posts_with_media",
              "posts_with_video",
              "posts_and_author_threads"
            ],
            "type": "string",
            "description": "Which part of an account's feed a profile URL or @handle returns. Applies to profile feeds only.",
            "default": "posts_with_replies"
          },
          "emitUnchanged": {
            "title": "🔄 Emit Unchanged Posts",
            "type": "boolean",
            "description": "When incremental mode is on, also emit posts whose content has not changed since the last run.",
            "default": false
          },
          "emitExpired": {
            "title": "⚰️ Emit Deleted Posts",
            "type": "boolean",
            "description": "When incremental mode is on, also emit posts that were seen before but are no longer found (deleted or no longer matching).",
            "default": false
          },
          "notifyOnlyChanges": {
            "title": "🔄 Notify Only New/Updated",
            "type": "boolean",
            "description": "When Incremental Mode is on, only send notifications for NEW and UPDATED posts. Has no effect outside incremental mode.",
            "default": false
          },
          "notificationLimit": {
            "title": "📊 Max Posts Per Notification",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of posts included in each notification message (1–20).",
            "default": 5
          },
          "telegramToken": {
            "title": "🔑 Telegram Bot Token",
            "type": "string",
            "description": "Telegram bot token (from @BotFather). Required for Telegram notifications."
          },
          "telegramChatId": {
            "title": "💬 Telegram Chat ID",
            "type": "string",
            "description": "Telegram chat or channel ID (e.g. \"-100123456789\"). Required when telegramToken is set."
          },
          "discordWebhookUrl": {
            "title": "🎮 Discord Webhook URL",
            "type": "string",
            "description": "Discord incoming webhook URL. Server Settings → Integrations → Webhooks → New Webhook."
          },
          "slackWebhookUrl": {
            "title": "💼 Slack Webhook URL",
            "type": "string",
            "description": "Slack incoming webhook URL. api.slack.com/messaging/webhooks."
          },
          "whatsappPhoneNumberId": {
            "title": "📞 WhatsApp Phone Number ID",
            "type": "string",
            "description": "Your WhatsApp Business phone-number ID (numeric, from Meta dashboard). Required when whatsappAccessToken is set."
          },
          "whatsappAccessToken": {
            "title": "📱 WhatsApp Access Token",
            "type": "string",
            "description": "WhatsApp Cloud API permanent access token (System User token from Meta Business). Recipient must have messaged the business number within the last 24h (service-conversation window — free since Nov 2024)."
          },
          "whatsappTo": {
            "title": "📲 WhatsApp Recipient",
            "type": "string",
            "description": "Recipient phone in E.164 format without + (e.g. \"436641234567\"). Recipient must have messaged your business number within last 24h."
          },
          "webhookUrl": {
            "title": "🪝 Generic Webhook URL",
            "type": "string",
            "description": "Receives a JSON POST with {metadata, items} after each run. Universal escape hatch for n8n / Make / Zapier / custom backends."
          },
          "webhookHeaders": {
            "title": "📋 Webhook Headers",
            "type": "object",
            "description": "Optional JSON object of custom headers (e.g. {\"Authorization\":\"Bearer ...\"})."
          },
          "appConnector": {
            "title": "Send results to a connected app",
            "type": "string",
            "description": "Optional. Pick a connected app under Settings → API & Integrations to receive your results (including any contact details). Best-effort across MCP connectors as Apify expands its catalog."
          },
          "mcpIssueTeam": {
            "title": "Issue tracker team",
            "type": "string",
            "description": "Only when the connected app is an issue tracker: the team (name or ID) the summary issue is created under, if that app requires one."
          },
          "descriptionFormat": {
            "title": "📝 Description Format",
            "enum": [
              "all",
              "text",
              "html",
              "markdown"
            ],
            "type": "string",
            "description": "Choose which representation of the listing description to include. `all` keeps every variant; the others keep only the selected one.",
            "default": "all"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}