Skip to main content

Track Mentions

The /mentions endpoint returns tweets that mention a specific handle. Use it to monitor brand mentions, support inquiries, campaign engagement, and competitive activity. Results are paginated (up to ~20 per page) and support engagement and date filters built into the request body.
Note: For a complete guide with production code examples, multi-channel monitoring patterns, and competitive analysis workflows, see How to Track Twitter Mentions With API on the blog.

Quick Start

curl -X POST https://api.sorsa.io/v3/mentions \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "AppleSupport",
    "order": "latest",
    "min_likes": 10,
    "since_date": "2026-03-01"
  }'
Tip: Test the endpoint without code in the API Playground.

Endpoint Reference

POST https://api.sorsa.io/v3/mentions
ParameterTypeRequiredDescription
querystringYesThe handle to track, without the @ symbol. Example: "elonmusk".
orderstringNo"latest" (default, chronological) or "popular" (engagement-ranked).
since_datestringNoStart date in YYYY-MM-DD format.
until_datestringNoEnd date in YYYY-MM-DD format.
min_likesintegerNoMinimum likes a mention must have.
min_retweetsintegerNoMinimum retweets a mention must have.
min_repliesintegerNoMinimum replies a mention must have.
next_cursorstringNoPagination cursor from a previous response.

Response

{
  "tweets": [
    {
      "id": "2031847200012345678",
      "full_text": "@AppleSupport My iPhone keeps restarting after the latest update. Anyone else?",
      "created_at": "Sat Mar 08 14:22:31 +0000 2026",
      "likes_count": 47,
      "retweet_count": 12,
      "reply_count": 8,
      "view_count": 15200,
      "lang": "en",
      "is_reply": false,
      "user": {
        "id": "9876543210",
        "username": "frustrated_user",
        "display_name": "Alex",
        "followers_count": 1240,
        "verified": false
      }
    }
  ],
  "next_cursor": "DAABCgABGSmiaxkA..."
}
Each mention includes full engagement metrics and the embedded author profile. When next_cursor is present, more pages are available. When it is null or absent, you have reached the end. See Pagination for handling patterns.

/mentions vs /search-tweets

The two endpoints solve different problems:
  • Use /mentions for posts that tag a specific handle (@brand). The endpoint catches @-tags, replies, and references, with min_likes, min_retweets, min_replies, since_date, and until_date available as first-class parameters.
  • Use /search-tweets for keyword-based matches that don’t include the handle. Searching "Nike" -from:Nike lang:en catches posts that name the brand in prose. Use this endpoint when you need Boolean logic, media filters, or other operators that go beyond what /mentions supports.
For complete brand coverage, run both endpoints in parallel and deduplicate by tweet ID.

Common Patterns

Filter by engagement

Pull only mentions that have reached an audience. Useful for reputation dashboards and PR monitoring.
import requests

API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/mentions"

body = {"query": "nike", "order": "popular", "min_likes": 100}
resp = requests.post(URL, headers={"ApiKey": API_KEY, "Content-Type": "application/json"}, json=body)
mentions = resp.json().get("tweets", [])

Pull every mention (support queue)

Omit engagement filters and sort chronologically. Catches every mention, including zero-engagement ones.
body = {"query": "YourBrandSupport", "order": "latest", "since_date": "2026-05-10"}
resp = requests.post(URL, headers={"ApiKey": API_KEY, "Content-Type": "application/json"}, json=body)

Date-windowed campaign analysis

Bound mentions to a campaign window with since_date and until_date. Loop through next_cursor until exhausted.
import time

def all_mentions(handle, since, until, max_pages=50):
    out, cursor = [], None
    for _ in range(max_pages):
        body = {"query": handle, "order": "latest", "since_date": since, "until_date": until}
        if cursor:
            body["next_cursor"] = cursor
        resp = requests.post(URL, headers={"ApiKey": API_KEY, "Content-Type": "application/json"}, json=body)
        resp.raise_for_status()
        data = resp.json()
        out.extend(data.get("tweets", []))
        cursor = data.get("next_cursor")
        if not cursor:
            break
        time.sleep(0.1)
    return out

Polling for new mentions

Track the most recent tweet ID across iterations to detect new mentions only.
last_seen_id = None
while True:
    resp = requests.post(URL, headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
                         json={"query": "yourbrand", "order": "latest"})
    tweets = resp.json().get("tweets", [])
    if tweets and last_seen_id is None:
        last_seen_id = tweets[0]["id"]
    elif tweets:
        new = [t for t in tweets if t["id"] > last_seen_id]
        # handle `new` mentions
        if new:
            last_seen_id = new[0]["id"]
    time.sleep(15)
Persist last_seen_id to disk or Redis so the loop survives restarts. For the full real-time pattern with deduplication and backoff, see Real-Time Monitoring.

Common Pitfalls

  • min_likes set too high for support use cases. A bug report with 2 likes is more important than a meme with 500. For support queues, set min_likes to 0 and rely on keyword routing instead.
  • Single-page reads on high-volume handles. One request returns ~20 mentions. For brands with hundreds of daily mentions, always paginate through next_cursor.
  • Confusing /mentions with full coverage. /mentions only catches @-tagged posts. Combine with /search-tweets to catch untagged brand references.
  • Aggressive polling on low-volume accounts. Match polling interval to mention volume. Every 15 seconds for high-traffic brands, every minute or two for smaller accounts. Universal rate limit is 20 req/s (Rate Limits).
  • Not persisting state across restarts. Without a durable checkpoint, a restarted monitor either re-alerts on old mentions or skips the gap.

Next Steps