{
  "openapi": "3.0.1",
  "info": {
    "title": "Bluesky Scraper - Posts, Profiles & Keyword Search",
    "description": "Scrape Bluesky posts and profiles by handle with no login, or follow a keyword through topic feeds, live capture or, with your app password, the full archive. Each post row holds the text, time, likes, reposts, replies, quotes, link and author. $2.00 per 1,000 posts.",
    "version": "0.1",
    "x-build-id": "sAehsSusHmVV77w5u"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/dami_studio~bluesky-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-dami_studio-bluesky-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/dami_studio~bluesky-scraper/runs": {
      "post": {
        "operationId": "runs-sync-dami_studio-bluesky-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/dami_studio~bluesky-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-dami_studio-bluesky-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": {
          "searchQuery": {
            "title": "Search query",
            "type": "string",
            "description": "Keyword(s) to match in Bluesky posts (e.g. \"artificial intelligence\"). Quoted \"phrases\" stay whole and several words must all appear. With a Bluesky handle + app password below this searches the full post archive; without one it captures matching posts live from Bluesky's public post stream, because Bluesky no longer serves archive search to signed-out clients. Leave empty to scrape specific authors instead."
          },
          "searchMode": {
            "title": "Search mode",
            "enum": [
              "auto",
              "live",
              "archive"
            ],
            "type": "string",
            "description": "How to answer a search query. \"Auto\" uses the full archive when you supply an app password and captures live posts when you do not. \"Live capture\" always watches the public post stream. \"Archive only\" never substitutes live capture: without credentials it reports that archive search is unavailable and returns nothing (uncharged).",
            "default": "auto"
          },
          "blueskyIdentifier": {
            "title": "Bluesky handle (only for archive search)",
            "type": "string",
            "description": "Your Bluesky handle or email, e.g. yourname.bsky.social. Needed ONLY to search the full post archive - Bluesky returns 403 for signed-out archive search. Author handles, profiles and live capture need no login."
          },
          "blueskyAppPassword": {
            "title": "Bluesky app password (only for archive search)",
            "type": "string",
            "description": "An app password from bsky.app -> Settings -> Privacy and security -> App passwords. Never your account password. Needed ONLY to search the full post archive."
          },
          "authorHandles": {
            "title": "Author handles",
            "type": "array",
            "description": "Bluesky handles to scrape (e.g. bsky.app, jay.bsky.team). For each handle the actor returns the author's profile plus their recent posts. The leading @ is optional. Leave empty if using a Search query instead.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Post language",
            "enum": [
              "any",
              "ar",
              "eu",
              "ca",
              "zh",
              "cs",
              "da",
              "nl",
              "en",
              "fi",
              "fr",
              "gl",
              "de",
              "el",
              "he",
              "hi",
              "hu",
              "id",
              "it",
              "ja",
              "ko",
              "ne",
              "fa",
              "pl",
              "pt",
              "ro",
              "ru",
              "es",
              "sv",
              "tl",
              "th",
              "tr",
              "uk",
              "vi"
            ],
            "type": "string",
            "description": "Keep only posts their author tagged with this language. Works on author handles and on the topic-feed lane. Posts with no language tag are left out, since there is nothing to check them against, and some accounts never set one. Left-out posts are not charged. Each handle and each topic feed is read at most 1,000 posts deep, so a language an account rarely uses can return fewer posts than you asked for. Archive search and live capture do not take a language: a keyword that would use either is refused before anything is read.",
            "default": "any"
          },
          "liveWatchSecs": {
            "title": "Live capture window (seconds)",
            "minimum": 10,
            "maximum": 900,
            "type": "integer",
            "description": "How long live capture watches Bluesky's public post stream before it stops. It also stops early once it has collected \"maxItems\" matches. Common keywords fill up in seconds; a rare keyword needs a longer window.",
            "default": 60
          },
          "maxItems": {
            "title": "Max items per query/author",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum number of posts to return per search query or per author handle. Pagination follows the API cursor until this limit is reached.",
            "default": 100
          },
          "notionConnector": {
            "title": "Notion connector (optional)",
            "type": "string",
            "description": "Optional. Write each post as a page into your Notion when the run finishes. Authorize a Notion connector once in Settings → API & Integrations → MCP connectors, then pick it here. Leave empty to skip (default), results are always saved to the dataset regardless."
          },
          "notionParentId": {
            "title": "Notion target data source ID",
            "type": "string",
            "description": "Optional. The Notion data source ID of the database to write into (only used if a Notion connector is set). Leave empty to create the pages privately in your workspace instead."
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Optional, and not needed for a normal run.",
            "default": {
              "useApifyProxy": 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}