> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Social media monitoring API for trending topics

> Monitor Reddit, GitHub, search trends, technology news, Wikipedia, prediction markets, and startup topics through one social media monitoring API with filters.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-radar-list-200">
      ```json theme={null}
      {
        "hasMore": false,
        "items": []
      }
      ```
    </Tab>

    <Tab title="400" id="response-radar-list-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-radar-list-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

    <Tab title="429" id="response-radar-list-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>
  </Tabs>
</Panel>

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Callout icon="circle-check" color="#16a34a">
  **Free.** This endpoint does not consume credits.
</Callout>

Build a social media monitoring feed from ranked public topics. Radar covers
Reddit, GitHub, technology news, search trends, Wikipedia, prediction markets,
and startup growth records. Apply the relevant source, category, region, and
time window to each request.

Authenticate every Radar request. You need no active subscription. Radar
consumes no credits.

## What is a social media monitoring API?

A social media monitoring API returns public posts and trends as
structured records. Radar exposes those records through one REST API
endpoint. Each response uses structured JSON and stable field names.

Radar gives every supported public source the same `RadarItem` shape. The
`GET /radar` endpoint filters items by source, category, region, and age. The
response ranks recent topics. Radar is not an exhaustive source archive.

Radar combines several public topic sources. It does not mirror every social
network. It also does not return X tweets, replies, followers, or timelines.
For X-specific monitoring, [Search Tweets](/api-reference/x/search-tweets)
finds brand mentions, hashtags, replies, and keyword matches.

Use stable fields to compare titles, regions, timestamps, and scores. You need
no separate adapter per source.
Keep full social listening data in a dedicated platform API.

Radar is not a social listening API for every major social platform. It does
not replace platform APIs for unsupported social platforms. Radar
returns ranked topics, not complete post, comment, or brand-mention records.
Radar provides no keyword search volume or long-term history. Radar includes no
more than 72 hours of history.

## Build a trending topics API feed

Use Radar as a trending topics API for dashboards, alerts, and research queues.
Start with a narrow time window. Apply source and category together or
separately.

1. Call `GET /radar` with your API key.
2. Filter one source when the request names a platform.
3. Limit the region when location affects the result.
4. Sort or filter records by `score` in your application.
5. Store each `id` to prevent duplicate dashboard rows.
6. Continue with `nextCursor` while `hasMore` stays `true`.

Use `source=reddit` for Reddit posts. Use `source=github` for trending
repositories. Other source identifiers work the same way. One
request format covers every supported feed.

## Is Radar real-time for monitoring trending topics?

Radar returns recently indexed topics. It does not stream every new event.
Use `publishedAt` for source timing. Use `createdAt` for indexing timing.

Start each scheduled poll without `after`. Use `nextCursor` only for later
pages within that poll. The contract guarantees neither cross-poll cursor
lifetime nor snapshots. Deduplicate records by `items[].id`. Never use an item
ID to order separate polling runs.

Respect every `429` rate limit response. Wait before the next poll. Polling
tracks recent changes. It promises no delivery deadline.

## Can Radar track brand mentions and sentiment?

Radar has no keyword query. Radar does not provide a complete brand monitoring
index. Compare returned titles and descriptions against a saved brand
dictionary. That comparison covers only the current Radar feed.

Radar does not analyze sentiment. The `score` value measures relevance, not
sentiment. Do not classify a high score as positive or negative sentiment.

Use [Search Tweets](/api-reference/x/search-tweets) to query exact X mentions.
Use Radar for ranked cross-source topics. Radar does not cover
every brand mention.

## How do you evaluate Radar topic accuracy?

Evaluate each item against the source fields. Do not treat a high trend score
as proof that a claim is correct or popular everywhere.

1. Match `source` and `sourceId` to the intended feed.
2. Open `url` when present. Compare its title and description with the item.
3. Compare `publishedAt` with `createdAt` to separate publication from indexing.
4. Confirm `region`, `category`, and `language` match the intended alert.
5. Interpret `metadata` with the source-specific fields documented below.
6. Deduplicate by `id`, then retain the score used for that polling run.

Radar does not guarantee complete source coverage or independent fact
verification. Review the original source before publishing an alert, report,
or customer-facing dashboard entry.

## Integrate Radar into a monitoring dashboard

Request one page, validate the response,
and render each `RadarItem`. Save the item ID, source, source ID, score, region,
and timestamps.

Group rows by `source` for a multi-feed dashboard. Rank dashboard rows by the
returned `score` value, then filter them by `publishedAt`. Open the returned
`url` when present.

Use `hasMore` and `nextCursor` for background ingestion. Never construct a
cursor. Keep it with matching filters during one pagination run. Changing
`source`, `category`, `region`, or `hours` starts a different result set.

Choose a searchable news API for exact keyword or domain matching. Use Radar
for normalized records from its documented sources only.

## Headers

<ParamField header="x-api-key" type="string">
  Your API key. Xquik also accepts session cookie authentication. Generate a key from the [dashboard](https://xquik.com/dashboard).
</ParamField>

## Query parameters

<ParamField query="source" type="string">
  Filter with one source identifier. Use `reddit` for Reddit, `github` for
  GitHub, `trustmrr` for startup growth, `hacker_news` for technology news,
  `google_trends` for search trends, `wikipedia` for Wikipedia, or `polymarket`
  for prediction markets.
  Omit this filter to return every available stream.
</ParamField>

<ParamField query="category" type="string">
  Filter by category. One of: `general`, `tech`, `dev`, `science`, `culture`, `politics`, `business`, `entertainment`. Omit to return all categories. Xquik assigns categories from each source and item.
</ParamField>

<ParamField query="hours" type="integer" default="6">
  Look-back window in hours. Range: 1-72. Smaller values return the most recent trends. Larger values give a broader snapshot. Default is 6 hours.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Items per page. Range: 1-100. Use smaller values (10-20) for quick polling, larger values for batch processing. Default is 50.
</ParamField>

<ParamField query="region" type="string" default="global">
  Region filter. Values: `US`, `GB`, `TR`, `ES`, `DE`, `FR`, `JP`, `IN`, `BR`, `CA`, `MX`, `global`. Default `global` returns items from all regions.
</ParamField>

<ParamField query="after" type="string">
  Cursor for pagination. Pass `nextCursor` from the previous response. Treat cursors as opaque base64 strings. Do not construct them.
</ParamField>

| Radar monitoring column | Response source | Queue rule |
| - | - | - |
| Item ID | `items[].id` | Deduplicate one indexed Radar item. |
| Source record | `items[].source` and `items[].sourceId` | Keep the original source and its record ID. |
| Topic | `items[].title` | Display the concrete trend or discussion. |
| Category | `items[].category` | Route technology, business, culture, or other topics. |
| Region | `items[].region` | Keep the market with every queue row. |
| Trend score | `items[].score` | Sort higher-scoring items first. |
| Published at | `items[].publishedAt` | Measure source freshness. |
| Source fields | `items[].metadata` | Interpret the fields documented below for that source. |
| Next page | `nextCursor` | Continue only when `hasMore` is `true`. |

## Response

<ResponseField name="items" type="RadarItem[]" required>
  Array of radar items sorted by score (descending).
</ResponseField>

<ResponseField name="hasMore" type="boolean" required>
  Whether more items are available after this page.
</ResponseField>

<ResponseField name="nextCursor" type="string">
  Pagination cursor. Present only when `hasMore` is `true`. Pass as the `after` query parameter on the next request.
</ResponseField>

### RadarItem fields

<ResponseField name="id" type="string" required>
  Radar item identifier.
</ResponseField>

<ResponseField name="title" type="string" required>
  Item title.
</ResponseField>

<ResponseField name="description" type="string">
  Item description. The API omits this field when the source provides no value.
</ResponseField>

<ResponseField name="url" type="string">
  Link to the original source. The API omits this field when no link exists.
</ResponseField>

<ResponseField name="imageUrl" type="string">
  Source image URL. Startup growth items return the logo here. The API omits
  this field when no image exists.
</ResponseField>

<ResponseField name="source" type="string" required>
  Radar source identifier. Reuse this value in `source` to request the same stream.
</ResponseField>

<ResponseField name="sourceId" type="string" required>
  Unique identifier within the source.
</ResponseField>

<ResponseField name="category" type="string" required>
  One of: `general`, `tech`, `dev`, `science`, `culture`, `politics`, `business`, `entertainment`.
</ResponseField>

<ResponseField name="region" type="string" required>
  Region code (for example `US`, `TR`, `global`).
</ResponseField>

<ResponseField name="language" type="string" required>
  The `language` value uses a BCP-47 code such as `en`, `tr`, or `ja`. The value
  `und` means the source did not identify a language.
</ResponseField>

<ResponseField name="score" type="number" required>
  This 0-10,000 relevance score ranks trending items. Higher values indicate a
  stronger trend signal within the result set.
</ResponseField>

<ResponseField name="metadata" type="object" required>
  Source-specific fields appear here. See the source tables below.
</ResponseField>

<ResponseField name="publishedAt" type="string" required>
  This shows when the source published the item or Radar found it. The value follows ISO 8601.
</ResponseField>

<ResponseField name="createdAt" type="string" required>
  This records when Radar indexed the item. The value follows ISO 8601.
</ResponseField>

## Metadata

Use `source` to interpret `metadata`. Multiword fields use camelCase in the
default REST response and snake\_case through API MCP.

### Reddit

Every Reddit item identifies `author`, `subreddit`, and `sourceFormat`. Current
items combine public listing discovery with server-rendered post fields. They
include available post content, media, and engagement metrics. Legacy rows can
still identify `sourceFormat` as `json` or `rss`.

| Fields | Description |
| - | - |
| `author`, `authorId` | Author username and optional Reddit author ID |
| `subreddit`, `subredditId`, `subredditSubscribers` | Community name and optional ID. Legacy JSON rows can include subscriber count |
| `sourceFormat` | `html` for current rich items. `json` and `rss` identify legacy rows |
| `score`, `upvoteRatio` | Reddit's public net score and public upvote ratio |
| `estimatedUpvotes`, `estimatedDownvotes` | Estimates derived from score and ratio |
| `numberComments`, `totalAwardsReceived` | Available engagement counts |
| `selftext`, `contentUrl`, `domain`, `postHint`, `linkFlairText` | Available post text, destination, and labels |
| `numberCrossposts`, `viewCount`, `distinguished`, `editedAt`, `galleryImageUrls`, `redditVideo` | Additional fields retained on legacy JSON rows |
| `archived`, `contestMode`, `isCrosspostable`, `isMeta`, `isNsfw`, `isOriginalContent`, `isRobotIndexable`, `isSelf`, `isSpoiler`, `isVideo`, `locked`, `stickied` | Post state flags |

Reddit does not publish exact upvote and downvote counts. Treat
`estimatedUpvotes` and `estimatedDownvotes` as estimates because Reddit may fuzz
the public score and ratio. `numberComments` is a count. Radar returns no comment
bodies.

### Startup growth

Startup growth items always include `mrr`, `growthPercent`, `last30Days`,
`total`, `customers`, `activeSubscriptions`, and `onSale`.

| Fields | Description |
| - | - |
| `xHandle` | Founder X username without `@` |
| `category`, `country`, `foundedDate`, `targetAudience` | Available company details |
| `askingPrice`, `multiple`, `paymentProvider` | Available sale and payment details |
| `growthMrrPercent`, `profitMarginLast30Days`, `revenuePerVisitor` | Available reported growth and efficiency metrics |
| `googleSearchImpressionsLast30Days`, `visitorsLast30Days` | Available 30-day acquisition metrics |
| `rank` | Revenue rank reported by the source |

Radar orders these items by reported 30-day revenue growth. `metadata.rank` is
the revenue rank reported by the source. It does not equal the result position.
The top-level `imageUrl` contains the startup logo when available.

### Other sources

| Source | Metadata |
| - | - |
| GitHub (`github`) | Stars added today in `starsToday` |
| Technology news (`hacker_news`) | Public points and comment count in `points` and `numberComments` |
| Search trends (`google_trends`) | Approximate traffic in `approxTraffic` |
| Polymarket (`polymarket`) | Reported 24-hour volume in `volume24hr` |
| Wikipedia (`wikipedia`) | Public page views in `views` |

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://xquik.com/api/v1/radar?category=tech&hours=12&limit=10" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/radar?category=tech&hours=12&limit=10", {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const { items, hasMore, nextCursor } = await response.json();

  for (const item of items) {
    console.log(`[${item.source}] ${item.title} (score: ${item.score})`);
  }
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://xquik.com/api/v1/radar",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      params={"category": "tech", "hours": 12, "limit": 10},
  )
  data = response.json()

  for item in data["items"]:
      print(f"[{item['source']}] {item['title']} (score: {item['score']})")
  ```

  ```go Go theme={null}
  req, _ := http.NewRequest("GET", "https://xquik.com/api/v1/radar?category=tech&hours=12&limit=10", nil)
  req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
      log.Fatal(err)
  }
  defer resp.Body.Close()

  var data struct {
      Items      []map[string]interface{} `json:"items"`
      HasMore    bool                     `json:"hasMore"`
      NextCursor string                   `json:"nextCursor"`
  }
  json.NewDecoder(resp.Body).Decode(&data)

  for _, item := range data.Items {
      fmt.Printf("[%s] %s (score: %.0f)\n", item["source"], item["title"], item["score"])
  }
  ```
</CodeGroup>

**Response.**

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    {
      "items": [
        {
          "id": "12345",
          "title": "Open-source deployment platform launches preview environments",
          "description": "A self-hosted platform adds preview environments and edge functions.",
          "url": "https://example.com/radar/items/12345",
          "source": "github",
          "sourceId": "github_12345",
          "category": "dev",
          "region": "global",
          "language": "en",
          "score": 450,
          "metadata": {
            "starsToday": 450,
            "language": "TypeScript"
          },
          "publishedAt": "2026-03-04T08:30:00.000Z",
          "createdAt": "2026-03-04T08:35:00.000Z"
        }
      ],
      "hasMore": true,
      "nextCursor": "NDUwfDIwMjYtMDMtMDRUMDg6MzA6MDAuMDAwWnwxMjM0NQ=="
    }
    ```
  </Tab>

  <Tab title="400 Invalid input">
    ```json theme={null}
    { "error": "invalid_input" }
    ```

    Invalid `source` or `category` value. Xquik clips numeric `hours` and `limit` values to the accepted range. Non-numeric values use defaults.
  </Tab>

  <Tab title="401 Unauthenticated">
    ```json theme={null}
    { "error": "unauthenticated" }
    ```

    Missing or invalid API key. Check the `x-api-key` header value.
  </Tab>

  <Tab title="429 Rate limited">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "message": "Too many requests. Try again later.", "retryAfter": 1 }
    ```

    Wait for the `Retry-After` value before requesting another Radar page.
  </Tab>
</Tabs>

## Pagination

Radar uses cursor-based pagination. When `hasMore` is `true`, pass `nextCursor` as `after` to fetch the next page.

<CodeGroup>
  ```bash cURL theme={null}
  # First page
  curl "https://xquik.com/api/v1/radar?limit=20" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq

  # Next page
  curl "https://xquik.com/api/v1/radar?limit=20&after=NDUwfDIwMjYtMDMtMDRUMDg6MzA6MDAuMDAwWnwxMjM0NQ==" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  let cursor = undefined;
  const allItems = [];

  do {
    const params = new URLSearchParams({ limit: "20" });
    if (cursor) params.set("after", cursor);

    const data = await fetch(`https://xquik.com/api/v1/radar?${params}`, {
      headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
    }).then((r) => r.json());

    allItems.push(...data.items);
    cursor = data.hasMore ? data.nextCursor : undefined;
  } while (cursor);
  ```

  ```python Python theme={null}
  all_items = []
  cursor = None

  while True:
      params = {"limit": 20}
      if cursor:
          params["after"] = cursor

      data = requests.get(
          "https://xquik.com/api/v1/radar",
          headers={"x-api-key": "xq_YOUR_KEY_HERE"},
          params=params,
      ).json()

      all_items.extend(data["items"])

      if data["hasMore"]:
          cursor = data["nextCursor"]
      else:
          break
  ```

  ```go Go theme={null}
  var allItems []map[string]interface{}
  cursor := ""

  for {
      url := "https://xquik.com/api/v1/radar?limit=20"
      if cursor != "" {
          url += "&after=" + cursor
      }

      req, _ := http.NewRequest("GET", url, nil)
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")

      resp, _ := http.DefaultClient.Do(req)
      var data struct {
          Items      []map[string]interface{} `json:"items"`
          HasMore    bool                     `json:"hasMore"`
          NextCursor string                   `json:"nextCursor"`
      }
      json.NewDecoder(resp.Body).Decode(&data)
      resp.Body.Close()

      allItems = append(allItems, data.Items...)

      if !data.HasMore {
          break
      }
      cursor = data.NextCursor
  }
  ```
</CodeGroup>

<Note>
  **Next steps.** [Trends guide](/guides/trends) for content strategy workflows · [Create Tweet](/api-reference/x-write/create-tweet) to post about trending topics · [Compose](/api-reference/compose/create) to plan and check a draft about a Radar item
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.