{
  "openapi": "3.0.1",
  "info": {
    "title": "Bluesky Mentions Monitor: Keyword Alerts to Slack",
    "description": "Bluesky keyword, brand and competitor mention monitor. Alert me when my handle is mentioned on Bluesky, or watch new posts from a list of accounts. One row per public post, plus new-post alerts to Slack, Discord or Telegram. Bluesky brand monitoring from n8n. Bills only for new posts. No API key.",
    "version": "1.0",
    "x-build-id": "cG1hakhUs4sCm9Ojd"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/accountable_eel~bluesky-mentions-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-accountable_eel-bluesky-mentions-monitor",
        "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/accountable_eel~bluesky-mentions-monitor/runs": {
      "post": {
        "operationId": "runs-sync-accountable_eel-bluesky-mentions-monitor",
        "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/accountable_eel~bluesky-mentions-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-accountable_eel-bluesky-mentions-monitor",
        "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": {
          "queries": {
            "title": "Keywords or domains to watch",
            "type": "array",
            "description": "One search per line: a keyword, a phrase in quotes, or a bare domain such as apify.com. Each line is searched across public Bluesky posts. Mentions and watched accounts are set in their own fields below. Accepted formats: apify, \"open source\", apify.com. You're only charged for the ones we actually find — a miss costs nothing.",
            "items": {
              "type": "string"
            }
          },
          "mentionHandles": {
            "title": "Accounts whose @mentions to watch (optional)",
            "type": "array",
            "description": "Bluesky handles, for example someone.bsky.social. Each one returns posts that mention the account. Leave empty to skip.",
            "items": {
              "type": "string"
            }
          },
          "watchHandles": {
            "title": "Accounts whose new posts to return (optional)",
            "type": "array",
            "description": "Bluesky handles. Each one returns that account's own recent posts (reposts excluded). Leave empty to skip.",
            "items": {
              "type": "string"
            }
          },
          "testRun": {
            "title": "Try it first — only process the first 5",
            "type": "boolean",
            "description": "Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.",
            "default": false
          },
          "onlyFound": {
            "title": "Hide rows with no result",
            "type": "boolean",
            "description": "Only keep rows where something was actually found. Misses are always free, whether or not you show them here.",
            "default": false
          },
          "includeKeywords": {
            "title": "Only keep rows containing",
            "type": "array",
            "description": "Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip rows containing",
            "type": "array",
            "description": "Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Max posts per search",
            "type": "integer",
            "description": "Caps how many posts you get (and pay for) from each keyword, mention or watched account. Default 100, maximum 1,000.",
            "default": 100
          },
          "sinceHours": {
            "title": "Only posts from the last N hours",
            "type": "integer",
            "description": "How far back to search, from 1 to 720 hours. Default 24. Applied as a date filter on Bluesky, before you are billed.",
            "default": 24
          },
          "language": {
            "title": "Language (optional)",
            "type": "string",
            "description": "A two-letter language code such as en or de. Leave empty for every language.",
            "default": ""
          },
          "excludeReplies": {
            "title": "Skip replies",
            "type": "boolean",
            "description": "When on, posts that reply to another post are dropped before you are billed.",
            "default": false
          },
          "minLikes": {
            "title": "Minimum likes",
            "type": "integer",
            "description": "Keep a post only when it has at least this many likes. Default 0.",
            "default": 0
          },
          "onlyNewSinceLastRun": {
            "title": "Only return posts that are new since the last run",
            "type": "boolean",
            "description": "Turns each search, mention and account into an alert. A post counts as new when its Bluesky URI has not been returned for that item by a previous run of the same watchlist. Already-seen posts are dropped before you are billed, so a run with nothing new costs only the start fee. URIs not seen for 30 days are forgotten.",
            "default": false
          },
          "deltaName": {
            "title": "Watchlist name (optional)",
            "type": "string",
            "description": "Leave empty and one is derived from your search settings. Type your own name to keep two schedules of the same search apart. With the checkbox above off, every post is returned and stamped 'Is this post new?' so you can filter in Sheets, n8n or Make.",
            "default": ""
          },
          "notifyUrl": {
            "title": "Send alerts to (Discord or Slack webhook, Telegram bot link, or any URL)",
            "type": "string",
            "description": "Optional. After the posts are billed, each NEW post is posted here as one message: author, text, engagement and a link, with a NEW POST badge. Discord or Slack: paste the channel webhook URL. Telegram: https://api.telegram.org/bot<token>/sendMessage?chat_id=<chat id>. Any other URL receives JSON. Messages are free, and a message that fails never fails the run (the row's notifyErrors says why). Stored encrypted, never logged or written to the results. Alerts only go out with monitoring on."
          },
          "notifyFormat": {
            "title": "Message format",
            "enum": [
              "auto",
              "discord",
              "slack",
              "telegram",
              "json"
            ],
            "type": "string",
            "description": "Leave on \"Detect from the link\": discord.com links get Discord messages, hooks.slack.com Slack, api.telegram.org Telegram, anything else JSON. Pick one only to override that.",
            "default": "auto"
          },
          "maxNotificationsPerRun": {
            "title": "Most alert messages per run",
            "type": "integer",
            "description": "Up to 100. Above this, one \"+N more\" message says how many more posts are in the run's dataset. 0 sends only that one summary message.",
            "default": 20
          },
          "columns": {
            "title": "Which columns do you want?",
            "type": "array",
            "description": "Choose which pieces of information to include in each result row. All are included by default.",
            "items": {
              "type": "string",
              "enum": [
                "postUrl",
                "text",
                "authorHandle",
                "authorDisplayName",
                "createdAt",
                "likeCount",
                "repostCount",
                "replyCount",
                "matchedQuery",
                "isNew",
                "firstSeenAt"
              ],
              "enumTitles": [
                "Post link",
                "Post text",
                "Author handle",
                "Author name",
                "Posted",
                "Likes",
                "Reposts",
                "Replies",
                "Matched search",
                "Is this post new?",
                "First seen on a run"
              ]
            },
            "default": [
              "postUrl",
              "text",
              "authorHandle",
              "authorDisplayName",
              "createdAt",
              "likeCount",
              "repostCount",
              "replyCount",
              "matchedQuery",
              "isNew",
              "firstSeenAt"
            ]
          },
          "expandRows": {
            "title": "One row per post (recommended) — turn off for one row per search instead",
            "type": "boolean",
            "description": "When on, each post found gets its own row instead of being grouped under its search. You're still only charged once per search, no matter how many rows it produces.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.",
            "default": 2
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy config. Residential recommended for anti-bot-sensitive targets.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}