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

# Engajamento com publicações

Comentários, citações e repostagens mostram como as pessoas interagem com uma publicação do X. Os contadores resumem o volume; os endpoints da Sorsa revelam quem participou e o que escreveu. Este guia vai das métricas gerais às respostas, citações e perfis individuais.

> Veja análises adicionais e fluxos completos no [guia de engajamento do blog](https://api.sorsa.io/blog/twitter-engagement-api).

## Comece pelas métricas

`/tweet-info` retorna o objeto completo e todos os contadores de engajamento.

```bash theme={null}
curl -X POST https://api.sorsa.io/v3/tweet-info \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tweet_link": "https://x.com/elonmusk/status/1234567890"}'
```

```python theme={null}
import requests

API_KEY = "YOUR_API_KEY"

def get_tweet(tweet_link):
    resp = requests.post(
        "https://api.sorsa.io/v3/tweet-info",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return resp.json()


tweet = get_tweet("https://x.com/elonmusk/status/1234567890")

print(f"Text: {tweet['full_text'][:100]}...")
print(f"Likes:    {tweet.get('likes_count', 0):,}")
print(f"Retweets: {tweet.get('retweet_count', 0):,}")
print(f"Quotes:   {tweet.get('quote_count', 0):,}")
print(f"Replies:  {tweet.get('reply_count', 0):,}")
print(f"Views:    {tweet.get('view_count', 0):,}")
print(f"Bookmarks:{tweet.get('bookmark_count', 0):,}")
```

`tweet_link` aceita uma URL completa ou apenas o ID numérico. Para até 100 publicações, use `/tweet-info-bulk`. Veja [otimização](https://docs.sorsa.io/pt-BR/optimizing-api-usage).

> Cada conta nova tem 100 requisições gratuitas, sem cartão ou validade. Teste os endpoints no [API Playground](https://api.sorsa.io/playground).

## Comentários e respostas

**Endpoint:** `POST /v3/comments`

Retorna até 20 respostas por página. Cada resposta é um objeto Tweet completo, com métricas e perfil do autor.

### Exemplo

```python theme={null}
def get_comments(tweet_link):
    resp = requests.post(
        "https://api.sorsa.io/v3/comments",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return resp.json()

data = get_comments("https://x.com/elonmusk/status/1234567890")
for comment in data.get("tweets", []):
    print(f"@{comment['user']['username']}: {comment['full_text'][:80]}")
```

### Parâmetros

| Parâmetro     | Tipo   | Obrigatório | Descrição                                         |
| :------------ | :----- | :---------- | :------------------------------------------------ |
| `tweet_link`  | string | Sim         | URL completa ou ID da publicação.                 |
| `order_by`    | string | Não         | `"Relevance"` (padrão), `"Recency"` ou `"Likes"`. |
| `next_cursor` | string | Não         | Cursor para a próxima página.                     |

Use `"Likes"` para ordenar pelo engajamento no servidor. Se precisar apenas das principais respostas, a primeira página já traz as mais curtidas, evitando coletar tudo para ordenar localmente.

### Percorrer todos os comentários

```python theme={null}
import time

def get_all_comments(tweet_link, max_pages=20):
    """Fetch all comments under a tweet with pagination."""
    all_comments = []
    next_cursor = None

    for page in range(max_pages):
        body = {"tweet_link": tweet_link}
        if next_cursor:
            body["next_cursor"] = next_cursor

        resp = requests.post(
            "https://api.sorsa.io/v3/comments",
            headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
            json=body,
        )
        resp.raise_for_status()
        data = resp.json()

        comments = data.get("tweets", [])
        all_comments.extend(comments)

        next_cursor = data.get("next_cursor")
        if not next_cursor:
            break
        time.sleep(0.1)

    return all_comments


comments = get_all_comments("https://x.com/elonmusk/status/1234567890")
print(f"Collected {len(comments)} comments")
```

Você pode ordenar por `likes_count`, filtrar textos com `?` para encontrar perguntas ou enviar `full_text` a um classificador de sentimento.

```python theme={null}
# Find the most-liked comments
top_comments = sorted(comments, key=lambda c: c.get("likes_count", 0), reverse=True)

for c in top_comments[:5]:
    print(f"@{c['user']['username']} ({c['likes_count']} likes): {c['full_text'][:80]}")
```

## Citações

**Endpoint:** `POST /v3/quotes`

Retorna publicações que citaram a original, incluindo o comentário adicionado, métricas e autor.

### Exemplo

```python theme={null}
def get_quotes(tweet_link):
    resp = requests.post(
        "https://api.sorsa.io/v3/quotes",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return resp.json()

data = get_quotes("https://x.com/elonmusk/status/1234567890")
for quote in data.get("tweets", []):
    print(f"@{quote['user']['username']} quoted: {quote['full_text'][:80]}")
```

| Parâmetro     | Tipo   | Obrigatório | Descrição                         |
| :------------ | :----- | :---------- | :-------------------------------- |
| `tweet_link`  | string | Sim         | URL ou ID da publicação original. |
| `next_cursor` | string | Não         | Cursor de paginação.              |

### Percorrer todas as citações

```python theme={null}
def get_all_quotes(tweet_link, max_pages=20):
    """Fetch all quote tweets of a specific tweet."""
    all_quotes = []
    next_cursor = None

    for page in range(max_pages):
        body = {"tweet_link": tweet_link}
        if next_cursor:
            body["next_cursor"] = next_cursor

        resp = requests.post(
            "https://api.sorsa.io/v3/quotes",
            headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
            json=body,
        )
        resp.raise_for_status()
        data = resp.json()

        quotes = data.get("tweets", [])
        all_quotes.extend(quotes)

        next_cursor = data.get("next_cursor")
        if not next_cursor:
            break
        time.sleep(0.1)

    return all_quotes
```

Use o perfil e o texto de cada citação para ordenar autores por tamanho da audiência:

```python theme={null}
quotes = get_all_quotes("https://x.com/brand/status/1234567890")

# Find quotes that reached the largest audiences
quotes.sort(key=lambda q: q["user"].get("followers_count", 0), reverse=True)

for q in quotes[:5]:
    u = q["user"]
    print(f"@{u['username']} ({u['followers_count']:,} followers)")
    print(f"  \"{q['full_text'][:80]}...\"\n")
```

## Usuários que repostaram

**Endpoint:** `POST /v3/retweeters`

Retorna **usuários**, com os mais recentes primeiro. Diferentemente de comentários e citações, a estrutura é `UsersResponse`, não `TweetsResponse`.

### Exemplo

```python theme={null}
def get_retweeters(tweet_link):
    resp = requests.post(
        "https://api.sorsa.io/v3/retweeters",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return resp.json()

data = get_retweeters("https://x.com/elonmusk/status/1234567890")
for user in data.get("users", []):
    print(f"@{user['username']} ({user['followers_count']} followers) retweeted")
```

| Parâmetro     | Tipo   | Obrigatório | Descrição                |
| :------------ | :----- | :---------- | :----------------------- |
| `tweet_link`  | string | Sim         | URL ou ID da publicação. |
| `next_cursor` | string | Não         | Cursor de paginação.     |

### Diferenças nas respostas

| Endpoint      | Retorna     | Chave    | Conteúdo                |
| :------------ | :---------- | :------- | :---------------------- |
| `/comments`   | Publicações | `tweets` | Texto e autor completos |
| `/quotes`     | Publicações | `tweets` | Texto e autor completos |
| `/retweeters` | Usuários    | `users`  | Apenas perfis           |

Repostagens redistribuem o original sem texto próprio, por isso o endpoint retorna os perfis.

### Percorrer todos os usuários

```python theme={null}
def get_all_retweeters(tweet_link, max_pages=20):
    """Fetch all users who retweeted a tweet."""
    all_users = []
    next_cursor = None

    for page in range(max_pages):
        body = {"tweet_link": tweet_link}
        if next_cursor:
            body["next_cursor"] = next_cursor

        resp = requests.post(
            "https://api.sorsa.io/v3/retweeters",
            headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
            json=body,
        )
        resp.raise_for_status()
        data = resp.json()

        users = data.get("users", [])
        all_users.extend(users)

        next_cursor = data.get("next_cursor")
        if not next_cursor:
            break
        time.sleep(0.1)

    return all_users
```

A soma dos seguidores pode servir como indicador de audiência potencial. **Não é alcance medido:** as audiências se sobrepõem, e seguir uma conta não significa ter visto a publicação.

```python theme={null}
retweeters = get_all_retweeters("https://x.com/brand/status/1234567890")

total_reach = sum(u.get("followers_count", 0) for u in retweeters)
verified_count = sum(1 for u in retweeters if u.get("verified"))

print(f"Retweeters: {len(retweeters)}")
print(f"Combined follower reach: {total_reach:,}")
print(f"Verified retweeters: {verified_count}")
```

## Análise completa de uma publicação

Combine os três endpoints. Como cada tipo é paginado, isso pode gerar muitas chamadas, uma por página. Reserve o fluxo para publicações que realmente exigem análise detalhada.

```python theme={null}
def full_engagement_report(tweet_link):
    """Generate a complete engagement report for a single tweet."""

    tweet = get_tweet(tweet_link)
    print(f"Tweet by @{tweet['user']['username']}:")
    print(f"  \"{tweet['full_text'][:100]}...\"")
    print(f"  Likes: {tweet.get('likes_count', 0):,} | "
          f"Views: {tweet.get('view_count', 0):,}")
    print()

    comments = get_all_comments(tweet_link, max_pages=10)
    print(f"Comments: {len(comments)}")
    if comments:
        top_comment = max(comments, key=lambda c: c.get("likes_count", 0))
        print(f"  Most liked: @{top_comment['user']['username']} "
              f"({top_comment['likes_count']} likes)")
        print(f"  \"{top_comment['full_text'][:80]}...\"")
    print()

    quotes = get_all_quotes(tweet_link, max_pages=10)
    print(f"Quotes: {len(quotes)}")
    if quotes:
        biggest_quoter = max(quotes, key=lambda q: q["user"].get("followers_count", 0))
        print(f"  Highest reach: @{biggest_quoter['user']['username']} "
              f"({biggest_quoter['user']['followers_count']:,} followers)")
        print(f"  \"{biggest_quoter['full_text'][:80]}...\"")
    print()

    retweeters = get_all_retweeters(tweet_link, max_pages=10)
    total_reach = sum(u.get("followers_count", 0) for u in retweeters)
    print(f"Retweeters: {len(retweeters)}")
    print(f"  Combined reach: {total_reach:,} followers")
    if retweeters:
        top_rt = max(retweeters, key=lambda u: u.get("followers_count", 0))
        print(f"  Biggest amplifier: @{top_rt['username']} "
              f"({top_rt['followers_count']:,} followers)")

    return {
        "tweet": tweet,
        "comments": comments,
        "quotes": quotes,
        "retweeters": retweeters,
    }


report = full_engagement_report("https://x.com/brand/status/1234567890")
```

### Exemplo de saída

```text theme={null}
Tweet by @brand:
  "We're excited to announce our Series B funding round of $50M..."
  Likes: 2,847 | Views: 892,000

Comments: 156
  Most liked: @tech_journalist (89 likes)
  "Congrats! What's the plan for international expansion?..."

Quotes: 43
  Highest reach: @vc_partner (284,000 followers)
  "This team has been on our radar for two years. Well deserved...."

Retweeters: 312
  Combined reach: 4,218,000 followers
  Biggest amplifier: @industry_leader (892,000 followers)
```

## Analisar várias publicações

Obtenha a lista com `/user-tweets` ou `/search-tweets` e analise cada item:

```python theme={null}
def compare_tweet_engagement(tweet_links):
    """Compare engagement breakdown across multiple tweets."""
    results = []

    for link in tweet_links:
        tweet = get_tweet(link)
        comments = get_all_comments(link, max_pages=3)
        quotes = get_all_quotes(link, max_pages=3)
        retweeters = get_all_retweeters(link, max_pages=3)

        rt_reach = sum(u.get("followers_count", 0) for u in retweeters)

        results.append({
            "text": tweet["full_text"][:60],
            "likes": tweet.get("likes_count", 0),
            "comments": len(comments),
            "quotes": len(quotes),
            "retweets": len(retweeters),
            "retweet_reach": rt_reach,
        })
        time.sleep(0.5)

    print(f"{'Tweet':<62} {'Likes':>6} {'Cmts':>5} {'Qts':>4} {'RTs':>4} {'RT Reach':>10}")
    print("-" * 100)
    for r in results:
        print(f"{r['text']:<62} {r['likes']:>6} {r['comments']:>5} "
              f"{r['quotes']:>4} {r['retweets']:>4} {r['retweet_reach']:>10,}")

    return results
```

> Para métricas agregadas sem os participantes individuais, prefira `/tweet-info-bulk`, com até 100 publicações por chamada. Veja [otimização](https://docs.sorsa.io/pt-BR/optimizing-api-usage).

## Exportar para CSV

```python theme={null}
import csv

def export_comments_to_csv(comments, output_file="comments.csv"):
    fields = [
        "comment_id", "created_at", "full_text", "likes", "retweets",
        "author_username", "author_followers", "author_verified",
    ]
    with open(output_file, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fields)
        writer.writeheader()
        for c in comments:
            u = c.get("user", {})
            writer.writerow({
                "comment_id": c["id"],
                "created_at": c["created_at"],
                "full_text": c["full_text"],
                "likes": c.get("likes_count", 0),
                "retweets": c.get("retweet_count", 0),
                "author_username": u.get("username", ""),
                "author_followers": u.get("followers_count", 0),
                "author_verified": u.get("verified", False),
            })
    print(f"Exported {len(comments)} comments to {output_file}")
```

O mesmo padrão funciona para citações. Para quem repostou, exporte campos de usuário em vez de campos de publicação.

## Verificar a ação de um usuário específico

Em campanhas e sorteios, use os endpoints dedicados:

* `/check-comment`: o usuário respondeu?
* `/check-quoted`: citou?
* `/check-retweet`: repostou?

`/check-retweet` pode exigir paginação; `/check-quoted` retorna um status, não um booleano. Veja [verificação de campanhas](https://docs.sorsa.io/pt-BR/Marketing-Campaign-Verification).

## Próximos passos

* [Busca](https://docs.sorsa.io/pt-BR/search-tweets): encontre publicações por tema.
* [Menções](https://docs.sorsa.io/pt-BR/search-mentions): analise as mais discutidas.
* [Concorrentes](https://docs.sorsa.io/pt-BR/Competitor-Analysis): compare padrões de engajamento.
* [Dados históricos](https://docs.sorsa.io/pt-BR/historical-data): consulte publicações antigas.
* [Campanhas](https://docs.sorsa.io/pt-BR/Marketing-Campaign-Verification): verifique ações individuais.
* [Referência da API](https://docs.sorsa.io/pt-BR/api-reference-guide): especificações completas.
