---
title: "Create New Search Query Monitor - API Reference"
description: "Create a monitor for any custom Twitter/X search query and get a webhook when a new tweet matches. Flat rate of $0.0002 per tweet found."
source: "https://docs.socialdata.tools/monitoring/create-search-query-monitor/"
---

Creates a new search query monitor. SocialData will run your monitor every `refresh_frequency` seconds, retrieve recent search results for `query`, and dispatch each new matching tweet as an individual webhook event.

Each execution reads the most recent page of results and pages back only as far as it needs to reach tweets it has already seen, up to a maximum of 3 pages. A monitor that keeps up with its query normally reads a single page per execution.

## Delivery behaviour

-   **The first execution delivers nothing.** It records which tweets already match your query so that only genuinely new ones are reported afterwards. Tweets posted before you created the monitor are never delivered.
-   **Each tweet is delivered once.** A tweet that keeps matching your query on later executions is not re-sent.
-   **Tweets that are already old when found are skipped.** If a tweet surfaces in search long after it was posted, it is not delivered. The cutoff is twice your `refresh_frequency`, or 10 minutes, whichever is longer.
-   **The monitor pauses if your balance runs out**, and resumes when you top up.

## Cost

Search monitors are billed **$0.0002 per delivered tweet**, and **$0.0002 for each execution that delivers nothing** — every execution runs a real Twitter search whether or not it matches. Your floor cost is therefore set by `refresh_frequency`: at the default 30 seconds, a monitor executes 2,880 times a day and costs at least ~$17/month even if it never matches anything. See [Pricing](https://docs.socialdata.tools/monitoring/pricing/#search-monitors) before choosing a frequency.

POST https://api.socialdata.tools/monitors/search-query

## Headers

**Authorization** `string` — required

Authorization Bearer header containing your SocialData API key

Example: Bearer YOUR\_API\_KEY

## Body

**query** `string` — required

A UTF-8, URL-encoded search query of up to 512 characters, including any [operators supported by Twitter's website search](https://docs.socialdata.tools/resources/twitter-search-operators/)

Example: from:elonmusk doge

**refresh\_frequency** `integer` — optional

How often the monitor executes, in seconds (value between 1 and 3600). This is the main driver of what the monitor costs — see [Pricing](https://docs.socialdata.tools/monitoring/pricing/#search-monitors)

Example: 300

**webhook\_url** `string` — optional

Monitor-specific webhook URL that will override your [global webhook URL](https://docs.socialdata.tools/monitoring/set-global-webhook-url/). Not required.

If you want to send events to Discord or Telegram, please read the [following section](#receiving-events-in-telegram-or-discord)

Example: https://my-website.com/webhook

## Code Examples

#### curl

```shellscript
curl -X POST "https://api.socialdata.tools/monitors/search-query" \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -d '{"refresh_frequency": 30, "query": "from:elonmusk"}'
```

#### JavaScript

```js
const API_KEY = 'YOUR_API_KEY_HERE';

fetch('https://api.socialdata.tools/monitors/search-query', {
    method: 'POST',
    headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    },
    body: JSON.stringify({
        refresh_frequency: 30,
        query: "from:elonmusk"
    })
})
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
```

#### Python

```python
import requests

API_KEY = 'YOUR_API_KEY_HERE'

url = 'https://api.socialdata.tools/monitors/search-query'

headers = {
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

payload = {
    'refresh_frequency': 30,
    'query': 'from:elonmusk'
}

response = requests.post(url, headers=headers, json=payload)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f"Error: {response.status_code}")
    print(response.text)
```

#### PHP

```php
$API_KEY = 'YOUR_API_KEY_HERE';

$url = "https://api.socialdata.tools/monitors/search-query";

$ch = curl_init();

$payload = json_encode([
    'refresh_frequency' => 30,
    'query' => 'from:elonmusk'
]);

curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $API_KEY",
        "Content-Type: application/json",
        "Accept: application/json"
    ],
    CURLOPT_POSTFIELDS => $payload
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);

curl_close($ch)
```

## Example Responses

#### 200

```json
{
    "status": "success",
    "data": {
        "id": "01jqty3m3dhg9xpsj373x12ck7",
        "created_at": "2025-04-02T09:42:51.000000Z",
        "monitor_type": "search_keyword",
        "status": "active",
        "webhook_url": "...",
        "parameters": {
            "query": "from:elonmusk"
        },
        "refresh_frequency": "30"
    }
}
```

#### 402

```json
{
    "status": "error",
    "message": "Insufficient balance"
}
```

## Response Codes

-   **200 OK** - request succeeded
-   **402 Payment Required** - not enough credits to perform this request
-   **422 Unprocessable Content** - validation failed (e.g. one of the required parameters was not provided)

## Webhook Payload Example

When a monitor detects a new tweet that matches the target search `query`, the API will make a `POST` request to your webhook URL with the following payload:

#### json

```json
{
    "event": "new_tweet",
    "data": {
        "tweet_created_at": "2025-02-12T02:43:10.000000Z",
        "id": 1889505498761703504,
        "id_str": "1889505498761703504",
        "conversation_id_str": "1889505498761703504",
        "text": null,
        "full_text": "Assange is right!",
        "source": "<a href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\">Twitter for iPhone<\/a>",
        "truncated": false,
        "in_reply_to_status_id": null,
        "in_reply_to_status_id_str": null,
        "in_reply_to_user_id": null,
        "in_reply_to_user_id_str": null,
        "in_reply_to_screen_name": null,
        "user": {
            "id": 44196397,
            "id_str": "44196397",
            "name": "Elon Musk",
            "screen_name": "elonmusk",
            "location": "",
            "url": null,
            "description": "",
            "protected": false,
            "verified": true,
            "followers_count": 217258406,
            "friends_count": 1013,
            "listed_count": 159662,
            "favourites_count": 122139,
            "statuses_count": 70054,
            "created_at": "2009-06-02T20:12:29.000000Z",
            "profile_banner_url": "https:\/\/pbs.twimg.com\/profile_banners\/44196397\/1726163678",
            "profile_image_url_https": "https:\/\/pbs.twimg.com\/profile_images\/1874558173962481664\/8HSTqIlD_normal.jpg",
            "can_dm": false
        },
        "quoted_status_id": null,
        "quoted_status_id_str": "1889494636323885155",
        "is_quote_status": true,
        "quoted_status": {
            "tweet_created_at": "2025-02-12T02:00:01.000000Z",
            "id": 1889494636323885155,
            "id_str": "1889494636323885155",
            "conversation_id_str": "1889494636323885155",
            "text": null,
            "full_text": "\ud83d\udea8ASSANGE ON USAID: \u2018CIVIL SOCIETY IS A FABLE\u2019\n\nAssange exposed how NGOs have been co-opted into political weapons, arguing that civil society is no longer independent but a \u201cbuyer\u2019s market\u201d for influence:\n\n\u201cThe last forty years have seen a huge proliferation of think tanks and political NGOs whose purpose, beneath all the verbiage, is to execute political agendas by proxy.\u201d\n\nHe singled out USAID, Freedom House, and \u2018civil society\u2019 events as vehicles for Western political interests masquerading as grassroots activism.\n\nSource: @WikiLeaks",
            "source": "<a href=\"http:\/\/twitter.com\" rel=\"nofollow\">Twitter Web Client<\/a>",
            "truncated": false,
            "in_reply_to_status_id": null,
            "in_reply_to_status_id_str": null,
            "in_reply_to_user_id": null,
            "in_reply_to_user_id_str": null,
            "in_reply_to_screen_name": null,
            "user": {
                "id": 1319287761048723458,
                "id_str": "1319287761048723458",
                "name": "Mario Nawfal",
                "screen_name": "MarioNawfal",
                "location": "",
                "url": "https:\/\/roundtable.live",
                "description": "Largest Show on X | Founder @ibcgroupio",
                "protected": false,
                "verified": true,
                "followers_count": 2030538,
                "friends_count": 44251,
                "listed_count": 8614,
                "favourites_count": 144210,
                "statuses_count": 109900,
                "created_at": "2020-10-22T14:42:25.000000Z",
                "profile_banner_url": "https:\/\/pbs.twimg.com\/profile_banners\/1319287761048723458\/1736691634",
                "profile_image_url_https": "https:\/\/pbs.twimg.com\/profile_images\/1670905743619268609\/pYItlWat_normal.jpg",
                "can_dm": true
            },
            "quoted_status_id": null,
            "quoted_status_id_str": null,
            "is_quote_status": false,
            "quoted_status": null,
            "retweeted_status": null,
            "quote_count": 16,
            "reply_count": 51,
            "retweet_count": 350,
            "favorite_count": 871,
            "views_count": 26067,
            "bookmark_count": 54,
            "lang": "en",
            "entities": {
                "user_mentions": [
                    {
                        "id_str": "16589206",
                        "name": "WikiLeaks",
                        "screen_name": "WikiLeaks",
                        "indices": [
                            532,
                            542
                        ]
                    }
                ],
                "urls": [],
                "hashtags": [],
                "symbols": []
            },
            "is_pinned": false
        },
        "retweeted_status": null,
        "quote_count": 0,
        "reply_count": 7,
        "retweet_count": 0,
        "favorite_count": 1,
        "views_count": null,
        "bookmark_count": 2,
        "lang": "en",
        "entities": {
            "user_mentions": [],
            "urls": [],
            "hashtags": [],
            "symbols": []
        },
        "is_pinned": false
    },
    "meta": {
        "monitor_id": "01jkt060zcz108b78fke6hm1g4",
        "monitor_type": "search_keyword",
        "monitored_query": "from:elonmusk"
    }
}
```

#### TypeScript

```js
interface NewTweetEvent {
  event: string;
  data: Tweet;
  meta: {
    monitor_id: string;
    monitor_type: string;
    // Search monitors report the query they matched. User monitors
    // report monitored_id_str and monitored_username instead.
    monitored_query: string;
  };
}

interface Tweet {
  tweet_created_at: string;
  id: number;
  id_str: string;
  conversation_id_str: string | null;
  text: string | null;
  full_text: string;
  source: string;
  truncated: boolean;
  in_reply_to_status_id: number | null;
  in_reply_to_status_id_str: string | null;
  in_reply_to_user_id: number | null;
  in_reply_to_user_id_str: string | null;
  in_reply_to_screen_name: string | null;
  user: User;
  quoted_status_id: number | null;
  quoted_status_id_str: string | null;
  is_quote_status: boolean;
  quoted_status: Tweet | null;
  retweeted_status: Tweet | null;
  quote_count: number;
  reply_count: number;
  retweet_count: number;
  favorite_count: number;
  views_count: number | null;
  bookmark_count: number;
  lang: string;
  entities: any;
  is_pinned: boolean;
}

interface User {
  id: number;
  id_str: string;
  name: string;
  screen_name: string;
  location: string;
  url: string | null;
  description: string;
  protected: boolean;
  verified: boolean;
  followers_count: number;
  friends_count: number;
  listed_count: number;
  favourites_count: number;
  statuses_count: number;
  created_at: string;
  profile_banner_url: string;
  profile_image_url_https: string;
  can_dm: boolean;
}
```

## Receiving Events in Telegram or Discord

The SocialData Monitor event schema differs from what Discord or Telegram expect. If you would like to receive notifications in your Discord channel or Telegram bot, we provide pre-built webhook handlers hosted on [Val Town](https://val.town), eliminating the need to develop your own custom application.

Simply copy the following webhook handler to your own Val Town account and configure your monitor’s `webhook_url` to direct events to your webhook handler: [**Tweet event webhook handler**](https://www.val.town/v/socialdata/twitterNewTweetAlert)

## Related endpoints

-   [Get search results](https://docs.socialdata.tools/reference/get-search-results/)
-   [Get community search results](https://docs.socialdata.tools/reference/get-community-search-results/)
-   [Twitter search operators](https://docs.socialdata.tools/resources/twitter-search-operators/)
-   [Create user tweets monitor](https://docs.socialdata.tools/monitoring/create-user-tweets-monitor/)
-   [Create user following monitor](https://docs.socialdata.tools/monitoring/create-user-following-monitor/)
-   [Create user profile monitor](https://docs.socialdata.tools/monitoring/create-user-profile-monitor/)

## Before you integrate

-   [Authentication](https://docs.socialdata.tools/getting-started/authentication/)
-   [Rate limits](https://docs.socialdata.tools/getting-started/rate-limits/)
-   [Errors](https://docs.socialdata.tools/getting-started/errors/)
-   [Monitoring API pricing](https://docs.socialdata.tools/monitoring/pricing/)
-   [Processing webhook events](https://docs.socialdata.tools/monitoring/processing-webhooks/)
