{
  "properties": {
    "author": {
      "description": "Only keep posts written by this handle (with or without @).",
      "editor": "textfield",
      "nullable": true,
      "title": "Posted by handle",
      "type": "string"
    },
    "authorHandles": {
      "description": "Used by the 'Posts by author' mode. Accepts @handle, handle, or https://x.com/handle profile URLs.",
      "editor": "stringList",
      "example": [
        "@apify",
        "https://x.com/OpenAI"
      ],
      "items": {
        "type": "string"
      },
      "title": "Author handles or profile URLs",
      "type": "array"
    },
    "conversationId": {
      "description": "Used by the 'Conversation thread' mode. Paste the root post ID or a post URL in that thread.",
      "editor": "textfield",
      "nullable": true,
      "title": "Conversation ID or post URL",
      "type": "string"
    },
    "dateFrom": {
      "description": "Only keep posts published on or after this date (UTC).",
      "editor": "datepicker",
      "nullable": true,
      "title": "Start date",
      "type": "string"
    },
    "dateTo": {
      "description": "Only keep posts published on or before this date (UTC).",
      "editor": "datepicker",
      "nullable": true,
      "title": "End date",
      "type": "string"
    },
    "excludeReplies": {
      "default": false,
      "description": "Drop replies and keep top-level posts only.",
      "prefill": false,
      "title": "Exclude replies",
      "type": "boolean"
    },
    "excludeRetweets": {
      "default": false,
      "description": "Drop reposts and keep original posts only.",
      "prefill": false,
      "title": "Exclude reposts",
      "type": "boolean"
    },
    "inReplyTo": {
      "description": "Only keep posts that are replies to this handle (with or without @).",
      "editor": "textfield",
      "nullable": true,
      "title": "Replying to handle",
      "type": "string"
    },
    "keywords": {
      "description": "Words, phrases or hashtags to search for. Each keyword is collected separately and every row shows the keyword that found it (searchTerm).",
      "editor": "stringList",
      "example": [
        "web scraping",
        "#AI",
        "OpenAI"
      ],
      "items": {
        "type": "string"
      },
      "prefill": [
        "apify"
      ],
      "title": "Keywords or phrases",
      "type": "array"
    },
    "language": {
      "default": "Any language",
      "description": "Only keep posts in this language. The default searches every language.",
      "editor": "select",
      "enum": [
        "Any language",
        "en",
        "es",
        "zh",
        "hi",
        "ar",
        "bn",
        "pt",
        "ru",
        "ja",
        "de",
        "fr",
        "ko",
        "tr",
        "vi",
        "te",
        "mr",
        "ta",
        "ur",
        "it",
        "th",
        "gu",
        "fa",
        "pl",
        "uk",
        "ml",
        "kn",
        "id",
        "ms",
        "sw",
        "ha",
        "am",
        "my",
        "pa",
        "nl",
        "ro",
        "el",
        "he",
        "sv",
        "hu",
        "cs"
      ],
      "enumTitles": [
        "Any language",
        "English",
        "Spanish",
        "Chinese",
        "Hindi",
        "Arabic",
        "Bengali",
        "Portuguese",
        "Russian",
        "Japanese",
        "German",
        "French",
        "Korean",
        "Turkish",
        "Vietnamese",
        "Telugu",
        "Marathi",
        "Tamil",
        "Urdu",
        "Italian",
        "Thai",
        "Gujarati",
        "Persian",
        "Polish",
        "Ukrainian",
        "Malayalam",
        "Kannada",
        "Indonesian",
        "Malay",
        "Swahili",
        "Hausa",
        "Amharic",
        "Burmese",
        "Punjabi",
        "Dutch",
        "Romanian",
        "Greek",
        "Hebrew",
        "Swedish",
        "Hungarian",
        "Czech"
      ],
      "prefill": "Any language",
      "title": "Language",
      "type": "string"
    },
    "maxItems": {
      "default": 20,
      "description": "Stop after this many posts per keyword or author. The URL and conversation modes use it as a total cap.",
      "maximum": 1000,
      "minimum": 1,
      "prefill": 3,
      "sectionCaption": "Collection",
      "sectionDescription": "Coverage and result limits.",
      "title": "Maximum posts",
      "type": "integer"
    },
    "mentioning": {
      "description": "Only keep posts that mention this handle (with or without @). Applied after collection.",
      "editor": "textfield",
      "nullable": true,
      "sectionCaption": "Post filters",
      "sectionDescription": "These are applied to collected posts, never sent as opaque search operators.",
      "title": "Mentioning handle",
      "type": "string"
    },
    "minimumLikes": {
      "description": "Drop posts below this like count. Posts whose count is unavailable are dropped and reported in the run summary.",
      "maximum": 100000000,
      "minimum": 0,
      "nullable": true,
      "title": "Minimum likes",
      "type": "integer"
    },
    "minimumReplies": {
      "description": "Drop posts below this reply count. Posts with no available reply count are dropped and reported.",
      "maximum": 100000000,
      "minimum": 0,
      "nullable": true,
      "title": "Minimum replies",
      "type": "integer"
    },
    "minimumRetweets": {
      "description": "Drop posts below this repost count. Counts are filled from the public fallback source when available.",
      "maximum": 100000000,
      "minimum": 0,
      "nullable": true,
      "title": "Minimum reposts",
      "type": "integer"
    },
    "mode": {
      "default": "search",
      "description": "Search by keyword, collect an author's posts, fetch specific post URLs, or open a conversation thread.",
      "editor": "select",
      "enum": [
        "search",
        "byAuthor",
        "byUrls",
        "conversation"
      ],
      "enumTitles": [
        "Search by keyword",
        "Posts by author",
        "Specific post URLs",
        "Conversation thread"
      ],
      "prefill": "search",
      "sectionCaption": "Mode and targets",
      "sectionDescription": "Choose one mode, then fill the target field that belongs to it.",
      "title": "What do you want to collect?",
      "type": "string"
    },
    "onlyImages": {
      "default": false,
      "description": "Keep posts that contain at least one photo.",
      "prefill": false,
      "title": "Posts with images only",
      "type": "boolean"
    },
    "onlyQuotes": {
      "default": false,
      "description": "Keep posts that quote another post.",
      "prefill": false,
      "title": "Quote posts only",
      "type": "boolean"
    },
    "onlyVerifiedUsers": {
      "default": false,
      "description": "Keep posts from verified or blue-check accounts only.",
      "prefill": false,
      "title": "Verified accounts only",
      "type": "boolean"
    },
    "onlyVideos": {
      "default": false,
      "description": "Keep posts that contain at least one video or GIF.",
      "prefill": false,
      "title": "Posts with videos only",
      "type": "boolean"
    },
    "postUrls": {
      "description": "Used by the 'Specific post URLs' mode. Accepts x.com or twitter.com post links and bare post IDs.",
      "editor": "stringList",
      "example": [
        "https://x.com/apify/status/2118015298603274372"
      ],
      "items": {
        "type": "string"
      },
      "title": "Post URLs or IDs",
      "type": "array"
    },
    "proxyConfiguration": {
      "description": "Optional. No proxy is needed. If supplied, it is used for the best-effort guest search supplement as well as page requests.",
      "editor": "proxy",
      "nullable": true,
      "sectionCaption": "Advanced",
      "sectionDescription": "Optional settings for special network environments.",
      "title": "Proxy configuration",
      "type": "object"
    },
    "sort": {
      "default": "Top",
      "description": "Latest is newest first. Top is ordered by likes and reposts. Top + Latest returns the top half by engagement, then the newest remaining posts.",
      "editor": "select",
      "enum": [
        "Top",
        "Latest",
        "Top + Latest"
      ],
      "enumTitles": [
        "Top - most engagement first",
        "Latest - newest first",
        "Top + Latest - both"
      ],
      "prefill": "Latest",
      "title": "Result order",
      "type": "string"
    }
  },
  "required": [
    "mode"
  ],
  "schemaVersion": 1,
  "title": "X Keyword Search with Mention & Reply Operators",
  "type": "object"
}
