> ## 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.

# Migração da API oficial do X

# Migrar da API oficial do X v2 para a Sorsa API v3

Esta referência cobre autenticação, mapeamento de endpoints, estruturas de resposta, paginação, métodos HTTP, sintaxe de busca, erros e exemplos em cURL, Python e JavaScript.

A Sorsa é somente de leitura. Se sua integração publica, envia mensagens, curte ou segue contas, mantenha a API oficial para essas operações e migre apenas as leituras. As 100 requisições gratuitas, sem cartão, permitem validar os endpoints antes de transferir tráfego de produção.

> Veja comparações de custo e exemplos passo a passo no [guia completo de migração](https://api.sorsa.io/blog/migrate-from-twitter-api).

## Resumo das mudanças

| Aspecto                | API oficial do X v2                         | Sorsa API v3                        |
| ---------------------- | ------------------------------------------- | ----------------------------------- |
| URL base               | `https://api.x.com/2`                       | `https://api.sorsa.io/v3`           |
| Autenticação           | OAuth 2.0 Bearer / OAuth 1.0a               | Chave de API no cabeçalho `ApiKey`  |
| Seleção de campos      | `tweet.fields`, `user.fields`, `expansions` | Todos os campos por padrão          |
| Estrutura da resposta  | `data` + `includes` + `meta`                | Objeto plano com relações incluídas |
| Paginação              | `pagination_token` / `meta.next_token`      | `next_cursor` (nível superior)      |
| Limites de requisições | Por endpoint em janelas de 15 minutos       | 20 req/s para todos                 |
| Formato de erro        | `errors[]` com `type`, `title`, `detail`    | `{ "message": "..." }`              |

## Autenticação

A API oficial usa OAuth 2.0 Bearer para chamadas da aplicação e OAuth 1.0a User Context para chamadas no contexto do usuário.

```bash theme={null}
# Official API (OAuth 2.0 App-Only)
curl "https://api.x.com/2/users/by/username/elonmusk" \
  -H "Authorization: Bearer $BEARER_TOKEN"
```

Na Sorsa, envie a chave em `ApiKey`. Gere chaves no [painel](https://api.sorsa.io/overview/keys).

```bash theme={null}
curl "https://api.sorsa.io/v3/info?username=elonmusk" \
  -H "ApiKey: $API_KEY"
```

```python theme={null}
import requests

response = requests.get(
    "https://api.sorsa.io/v3/info",
    params={"username": "elonmusk"},
    headers={"ApiKey": API_KEY},
)
user = response.json()
```

```javascript theme={null}
const response = await fetch("https://api.sorsa.io/v3/info?username=elonmusk", {
  headers: { ApiKey: API_KEY },
});
const user = await response.json();
```

Veja [autenticação](https://docs.sorsa.io/pt-BR/authentication).

## Mapeamento de endpoints

### Usuários

| Ação                     | API oficial do X v2                  | Sorsa API v3                                |
| ------------------------ | ------------------------------------ | ------------------------------------------- |
| Obter usuário pelo nome  | `GET /2/users/by/username/:username` | `GET /info?username=:username`              |
| Obter usuário pelo ID    | `GET /2/users/:id`                   | `GET /info?user_id=:id`                     |
| Obter vários usuários    | `GET /2/users?ids=...`               | `GET /info-batch?user_ids=...&user_ids=...` |
| Obter seguidores         | `GET /2/users/:id/followers`         | `GET /followers?user_id=:id`                |
| Obter contas seguidas    | `GET /2/users/:id/following`         | `GET /follows?user_id=:id`                  |
| Seguidores verificados   | Indisponível                         | `GET /verified-followers?user_id=:id`       |
| Metadados About da conta | Indisponível                         | `GET /about?username=:username`             |

* `GET /info-batch` aceita até 100 nomes ou IDs. Repita o parâmetro: `?usernames=a&usernames=b`.
* `GET /followers` e `GET /follows` retornam até **200 perfis completos por página**, com bio, contadores e verificação.

### Publicações

| Ação                     | API oficial do X v2              | Sorsa API v3                                              |
| ------------------------ | -------------------------------- | --------------------------------------------------------- |
| Obter uma publicação     | `GET /2/tweets/:id`              | `POST /tweet-info` corpo: `{ "tweet_link": ":id" }`       |
| Obter várias publicações | `GET /2/tweets?ids=...`          | `POST /tweet-info-bulk` corpo: `{ "tweet_links": [...] }` |
| Timeline do usuário      | `GET /2/users/:id/tweets`        | `POST /user-tweets` corpo: `{ "user_id": ":id" }`         |
| Citações                 | `GET /2/tweets/:id/quote_tweets` | `POST /quotes` corpo: `{ "tweet_link": ":id" }`           |
| Usuários que repostaram  | `GET /2/tweets/:id/retweeted_by` | `POST /retweeters` corpo: `{ "tweet_link": ":id" }`       |
| Respostas (comentários)  | Sem endpoint dedicado            | `POST /comments` corpo: `{ "tweet_link": ":id" }`         |
| Artigo longo do X        | Indisponível                     | `POST /article` corpo: `{ "tweet_link": ":id" }`          |

* `tweet_link` aceita URL, como `https://x.com/user/status/123`, ou ID string, como `"123"`.
* `POST /tweet-info-bulk` retorna até 100 itens por chamada, reduzindo o total em até 100 vezes em comparação com chamadas individuais.
* `POST /user-tweets` não tem teto de 3.200. Percorra `next_cursor` até ficar ausente. Veja [dados históricos](https://docs.sorsa.io/pt-BR/historical-data).

### Busca

| Ação                        | API oficial do X v2                     | Sorsa API v3                                      |
| --------------------------- | --------------------------------------- | ------------------------------------------------- |
| Buscar publicações recentes | `GET /2/tweets/search/recent?query=...` | `POST /search-tweets` corpo: `{ "query": "..." }` |
| Buscar no arquivo completo  | `GET /2/tweets/search/all?query=...`    | `POST /search-tweets` (histórico incluído)        |
| Buscar menções              | `GET .../search/recent?query=@user`     | `POST /mentions` corpo: `{ "query": "user" }`     |
| Buscar usuários             | Indisponível na v2                      | `POST /search-users` corpo: `{ "query": "..." }`  |

* A Sorsa usa a sintaxe da busca avançada da interface web do X. Termos básicos podem ser reaproveitados, mas revise operadores específicos da API v2. Veja [operadores](https://docs.sorsa.io/pt-BR/search-operators).
* `POST /mentions` acrescenta filtros no corpo: `min_likes`, `min_replies`, `min_retweets`, `since_date` e `until_date`.

### Listas

| Ação                 | API oficial do X v2          | Sorsa API v3                        |
| -------------------- | ---------------------------- | ----------------------------------- |
| Membros da lista     | `GET /2/lists/:id/members`   | `GET /list-members?list_id=:id`     |
| Seguidores da lista  | `GET /2/lists/:id/followers` | `GET /list-followers?list_link=:id` |
| Publicações da lista | `GET /2/lists/:id/tweets`    | `GET /list-tweets?list_id=:id`      |

### Comunidades

A API oficial não expõe os endpoints de comunidades abaixo.

| Ação                  | Sorsa API v3                                                                         |
| --------------------- | ------------------------------------------------------------------------------------ |
| Membros da comunidade | `POST /community-members` corpo: `{ "community_link": ":id" }`                       |
| Feed da comunidade    | `POST /community-tweets` corpo: `{ "community_id": ":id", "order": "popular" }`      |
| Busca na comunidade   | `POST /community-search-tweets` corpo: `{ "community_link": ":id", "query": "..." }` |

Consulte os formatos e a nota de disponibilidade em [listas e comunidades](https://docs.sorsa.io/pt-BR/lists-and-communities). Confirme com o suporte antes de migrar esse fluxo.

### Verificação

As verificações respondem a perguntas sobre ações individuais. Sem um equivalente direto na API oficial, seria necessário consultar listas e procurar o usuário no cliente. Algumas verificações podem exigir paginação; veja o guia específico.

| Pergunta                               | Sorsa API v3                                     |
| -------------------------------------- | ------------------------------------------------ |
| O usuário A segue B?                   | `POST /check-follow`                             |
| O usuário X comentou na publicação Y?  | `GET /check-comment?tweet_link=...&username=...` |
| O usuário X citou ou repostou Y?       | `POST /check-quoted`                             |
| O usuário X repostou Y?                | `POST /check-retweet`                            |
| O usuário X participa da comunidade Y? | `POST /check-community-member`                   |

Veja [verificação de campanhas](https://docs.sorsa.io/pt-BR/Marketing-Campaign-Verification).

### Análises exclusivas da Sorsa

| Ação                             | Sorsa API v3                         |
| -------------------------------- | ------------------------------------ |
| Pontuação de influência          | `GET /score?username=...`            |
| Variações de Score (7 e 30 dias) | `GET /score-changes?username=...`    |
| Seguidores por categoria         | `GET /followers-stats?username=...`  |
| Top 20 seguidores por Score      | `GET /top-followers?username=...`    |
| Top 20 contas seguidas por Score | `GET /top-following?username=...`    |
| Novos seguidores (7 dias)        | `GET /new-followers-7d?username=...` |
| Novas contas seguidas (7 dias)   | `GET /new-following-7d?username=...` |

Esses endpoints cobrem o subconjunto cripto de contas acompanhadas: influenciadores, projetos e fundos. Veja [Sorsa Score](https://docs.sorsa.io/pt-BR/sorsa-score-and-crypto-analytics).

### Utilitários

| Ação                    | Sorsa API v3                  |
| ----------------------- | ----------------------------- |
| Nome de usuário para ID | `GET /username-to-id/:handle` |
| ID para nome de usuário | `GET /id-to-username/:id`     |
| URL de perfil para ID   | `GET /link-to-id?link=...`    |
| Consumo da chave de API | `GET /key-usage-info`         |

Veja [conversão de IDs](https://docs.sorsa.io/pt-BR/ID-Conversion).

## Mudanças na resposta

A v2 oficial usa `data`, `includes` e `meta`. A Sorsa retorna objetos planos, com autor incluído na publicação.

### Perfil

**API oficial v2, com seleção de campos:**

```json theme={null}
{
  "data": {
    "id": "44196397",
    "name": "Elon Musk",
    "username": "elonmusk",
    "verified": false,
    "profile_image_url": "https://pbs.twimg.com/...",
    "public_metrics": {
      "followers_count": 100000000,
      "following_count": 500,
      "tweet_count": 30000,
      "listed_count": 12000
    }
  }
}
```

**Sorsa v3:**

```json theme={null}
{
  "id": "44196397",
  "username": "elonmusk",
  "display_name": "Elon Musk",
  "description": "...",
  "location": "Austin, TX",
  "profile_image_url": "https://pbs.twimg.com/...",
  "profile_background_image_url": "...",
  "followers_count": 100000000,
  "followings_count": 500,
  "tweets_count": 30000,
  "favourites_count": 50000,
  "media_count": 1200,
  "verified": false,
  "protected": false,
  "can_dm": true,
  "possibly_sensitive": false,
  "created_at": "2009-06-02T20:12:29Z",
  "bio_urls": ["https://example.com"],
  "pinned_tweet_ids": ["17823..."]
}
```

### Publicação

**API oficial v2, com `expansions=author_id`:**

```json theme={null}
{
  "data": {
    "id": "1234567890",
    "text": "Hello world",
    "created_at": "2024-01-15T12:00:00.000Z",
    "author_id": "44196397",
    "conversation_id": "1234567890",
    "lang": "en",
    "public_metrics": {
      "retweet_count": 100,
      "reply_count": 50,
      "like_count": 500,
      "quote_count": 25,
      "bookmark_count": 10,
      "impression_count": 50000
    }
  },
  "includes": {
    "users": [
      { "id": "44196397", "name": "Elon Musk", "username": "elonmusk" }
    ]
  }
}
```

**Sorsa v3:**

```json theme={null}
{
  "id": "1234567890",
  "full_text": "Hello world",
  "created_at": "2024-01-15T12:00:00Z",
  "lang": "en",
  "conversation_id_str": "1234567890",
  "likes_count": 500,
  "retweet_count": 100,
  "reply_count": 50,
  "quote_count": 25,
  "view_count": 50000,
  "bookmark_count": 10,
  "is_reply": false,
  "is_quote_status": false,
  "is_replies_limited": false,
  "in_reply_to_tweet_id": null,
  "in_reply_to_username": null,
  "user": {
    "id": "44196397",
    "username": "elonmusk",
    "display_name": "Elon Musk",
    "followers_count": 100000000
  },
  "entities": [],
  "quoted_status": null,
  "retweeted_status": null
}
```

### Mapeamento de campos

#### Usuários

| API oficial do X v2              | Sorsa API v3                   | Observações                              |
| -------------------------------- | ------------------------------ | ---------------------------------------- |
| `id`                             | `id`                           | Igual                                    |
| `username`                       | `username`                     | Igual                                    |
| `name`                           | `display_name`                 | Renomeado                                |
| `description`                    | `description`                  | Igual                                    |
| `location`                       | `location`                     | Igual                                    |
| `verified`                       | `verified`                     | Igual                                    |
| `protected`                      | `protected`                    | Igual                                    |
| `profile_image_url`              | `profile_image_url`            | Igual                                    |
| `created_at`                     | `created_at`                   | Igual                                    |
| `public_metrics.followers_count` | `followers_count`              | Movido para o nível superior             |
| `public_metrics.following_count` | `followings_count`             | Movido para o nível superior e renomeado |
| `public_metrics.tweet_count`     | `tweets_count`                 | Movido para o nível superior e renomeado |
| `public_metrics.listed_count`    | Indisponível                   |                                          |
| Indisponível                     | `favourites_count`             | Exclusivo da Sorsa                       |
| Indisponível                     | `media_count`                  | Exclusivo da Sorsa                       |
| Indisponível                     | `can_dm`                       | Exclusivo da Sorsa                       |
| Indisponível                     | `bio_urls`                     | Exclusivo da Sorsa                       |
| Indisponível                     | `pinned_tweet_ids`             | Exclusivo da Sorsa                       |
| Indisponível                     | `profile_background_image_url` | Exclusivo da Sorsa                       |
| Indisponível                     | `possibly_sensitive`           | Exclusivo da Sorsa                       |

#### Publicações

| API oficial do X v2                         | Sorsa API v3                                        | Observações                                                 |
| ------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------- |
| `id`                                        | `id`                                                | Igual                                                       |
| `text`                                      | `full_text`                                         | Renomeado                                                   |
| `created_at`                                | `created_at`                                        | Igual                                                       |
| `lang`                                      | `lang`                                              | Igual                                                       |
| `conversation_id`                           | `conversation_id_str`                               | Renomeado                                                   |
| `in_reply_to_user_id`                       | `in_reply_to_username`                              | Retorna nome de usuário em vez de ID                        |
| `public_metrics.like_count`                 | `likes_count`                                       | Movido para o nível superior e renomeado (observe o plural) |
| `public_metrics.retweet_count`              | `retweet_count`                                     | Movido para o nível superior                                |
| `public_metrics.reply_count`                | `reply_count`                                       | Movido para o nível superior                                |
| `public_metrics.quote_count`                | `quote_count`                                       | Movido para o nível superior                                |
| `public_metrics.bookmark_count`             | `bookmark_count`                                    | Movido para o nível superior                                |
| `public_metrics.impression_count`           | `view_count`                                        | Movido para o nível superior e renomeado                    |
| `author_id` + `includes.users[]`            | `user` (objeto completo incluído)                   | Incluído                                                    |
| Publicações referenciadas por `includes`    | `quoted_status`, `retweeted_status`                 | Objetos incluídos                                           |
| Indisponível                                | `is_reply`, `is_quote_status`, `is_replies_limited` | Booleanos exclusivos da Sorsa                               |
| Indisponível                                | `in_reply_to_tweet_id`                              | Exclusivo da Sorsa                                          |
| `entities` (URLs, menções, hashtags, mídia) | `entities` array de `{ type, link, preview }`       | Estrutura diferente                                         |

## Paginação

A API oficial envia `pagination_token` e retorna `meta.next_token`. A Sorsa usa `next_cursor` nos dois sentidos.

**GET:** parâmetro de consulta.

```bash theme={null}
curl "https://api.sorsa.io/v3/followers?username=elonmusk&next_cursor=ABC123" \
  -H "ApiKey: $API_KEY"
```

**POST:** corpo JSON.

```bash theme={null}
curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "from:elonmusk", "next_cursor": "ABC123" }'
```

O cursor é retornado no nível superior:

```json theme={null}
{
  "tweets": [...],
  "next_cursor": "XYZ789"
}
```

Quando estiver ausente ou nulo, as páginas terminaram. Veja [paginação](https://docs.sorsa.io/pt-BR/pagination).

## Diferenças de métodos HTTP

| Ação                         | API oficial              | Sorsa API |
| ---------------------------- | ------------------------ | --------- |
| Obter publicação             | GET                      | **POST**  |
| Buscar publicações           | GET                      | **POST**  |
| Timeline do usuário          | GET                      | **POST**  |
| Citações                     | GET                      | **POST**  |
| Usuários que repostaram      | GET                      | **POST**  |
| Respostas (comentários)      | (sem equivalente direto) | **POST**  |
| Perfil de usuário            | GET                      | GET       |
| Seguidores / contas seguidas | GET                      | GET       |
| Listas                       | GET                      | GET       |

Conteúdo de publicações, busca e comunidades usam POST com JSON, incluindo `/user-tweets`. Usuários, listas e utilitários usam GET com parâmetros de consulta ou caminho. A exceção entre as verificações é `/check-comment`, que usa GET mesmo recebendo um link de publicação. Consulte a referência em caso de dúvida.

## Exemplos de migração de código

### Consultar um perfil

**Antes: API oficial**

```bash theme={null}
curl "https://api.x.com/2/users/by/username/elonmusk?user.fields=description,public_metrics,profile_image_url,verified,created_at" \
  -H "Authorization: Bearer $BEARER_TOKEN"
```

```python theme={null}
import requests

response = requests.get(
    "https://api.x.com/2/users/by/username/elonmusk",
    params={"user.fields": "description,public_metrics,profile_image_url,verified,created_at"},
    headers={"Authorization": f"Bearer {BEARER_TOKEN}"},
)
user = response.json()["data"]
followers = user["public_metrics"]["followers_count"]
name = user["name"]
```

```javascript theme={null}
const url = "https://api.x.com/2/users/by/username/elonmusk" +
  "?user.fields=description,public_metrics,profile_image_url,verified,created_at";
const res = await fetch(url, {
  headers: { Authorization: `Bearer ${BEARER_TOKEN}` },
});
const { data: user } = await res.json();
const followers = user.public_metrics.followers_count;
const name = user.name;
```

**Depois: Sorsa**

```bash theme={null}
curl "https://api.sorsa.io/v3/info?username=elonmusk" \
  -H "ApiKey: $API_KEY"
```

```python theme={null}
import requests

response = requests.get(
    "https://api.sorsa.io/v3/info",
    params={"username": "elonmusk"},
    headers={"ApiKey": API_KEY},
)
user = response.json()
followers = user["followers_count"]
name = user["display_name"]
```

```javascript theme={null}
const res = await fetch("https://api.sorsa.io/v3/info?username=elonmusk", {
  headers: { ApiKey: API_KEY },
});
const user = await res.json();
const followers = user.followers_count;
const name = user.display_name;
```

### Buscar publicações

**Antes**

```bash theme={null}
curl "https://api.x.com/2/tweets/search/recent?query=from%3Aelonmusk%20since%3A2024-01-01&tweet.fields=created_at,public_metrics,lang&expansions=author_id&user.fields=username,name&max_results=10" \
  -H "Authorization: Bearer $BEARER_TOKEN"
```

```python theme={null}
params = {
    "query": "from:elonmusk since:2024-01-01",
    "tweet.fields": "created_at,public_metrics,lang",
    "expansions": "author_id",
    "user.fields": "username,name",
    "max_results": 10,
}
response = requests.get(
    "https://api.x.com/2/tweets/search/recent",
    headers={"Authorization": f"Bearer {BEARER_TOKEN}"},
    params=params,
)
data = response.json()

tweets = data["data"]
users = {u["id"]: u for u in data.get("includes", {}).get("users", [])}
next_token = data.get("meta", {}).get("next_token")

for tweet in tweets:
    author = users.get(tweet["author_id"])
    print(tweet["text"], "by", author["username"])
```

```javascript theme={null}
const params = new URLSearchParams({
  query: "from:elonmusk since:2024-01-01",
  "tweet.fields": "created_at,public_metrics,lang",
  expansions: "author_id",
  "user.fields": "username,name",
  max_results: "10",
});
const res = await fetch(`https://api.x.com/2/tweets/search/recent?${params}`, {
  headers: { Authorization: `Bearer ${BEARER_TOKEN}` },
});
const data = await res.json();

const tweets = data.data || [];
const users = Object.fromEntries((data.includes?.users || []).map(u => [u.id, u]));

for (const t of tweets) {
  const author = users[t.author_id];
  console.log(t.text, "by", author.username);
}
```

**Depois**

```bash theme={null}
curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "from:elonmusk since:2024-01-01"}'
```

```python theme={null}
response = requests.post(
    "https://api.sorsa.io/v3/search-tweets",
    headers={"ApiKey": API_KEY},
    json={"query": "from:elonmusk since:2024-01-01"},
)
data = response.json()

for tweet in data["tweets"]:
    print(tweet["full_text"], "by", tweet["user"]["username"])
```

```javascript theme={null}
const res = await fetch("https://api.sorsa.io/v3/search-tweets", {
  method: "POST",
  headers: { ApiKey: API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ query: "from:elonmusk since:2024-01-01" }),
});
const data = await res.json();

for (const t of data.tweets) {
  console.log(t.full_text, "by", t.user.username);
}
```

### Percorrer seguidores

**Antes**

```python theme={null}
def fetch_all_followers_official(user_id, token):
    url = f"https://api.x.com/2/users/{user_id}/followers"
    headers = {"Authorization": f"Bearer {token}"}
    followers = []
    pagination_token = None

    while True:
        params = {"max_results": 1000}
        if pagination_token:
            params["pagination_token"] = pagination_token

        r = requests.get(url, headers=headers, params=params)
        r.raise_for_status()
        data = r.json()

        followers.extend(data.get("data", []))
        pagination_token = data.get("meta", {}).get("next_token")
        if not pagination_token:
            break

    return followers
```

**Depois**

```bash theme={null}
CURSOR=""
while :; do
  RES=$(curl -s "https://api.sorsa.io/v3/followers?username=elonmusk${CURSOR:+&next_cursor=$CURSOR}" \
    -H "ApiKey: $API_KEY")
  echo "$RES" | jq '.users'
  CURSOR=$(echo "$RES" | jq -r '.next_cursor // empty')
  [ -z "$CURSOR" ] && break
done
```

```python theme={null}
def fetch_all_followers(user_id, api_key):
    url = "https://api.sorsa.io/v3/followers"
    headers = {"ApiKey": api_key}
    followers = []
    next_cursor = None

    while True:
        params = {"user_id": user_id}
        if next_cursor:
            params["next_cursor"] = next_cursor

        r = requests.get(url, headers=headers, params=params)
        r.raise_for_status()
        data = r.json()

        followers.extend(data.get("users", []))
        next_cursor = data.get("next_cursor")
        if not next_cursor:
            break

    return followers
```

```javascript theme={null}
async function fetchAllFollowers(userId, apiKey) {
  const followers = [];
  let nextCursor = null;

  do {
    const params = new URLSearchParams({ user_id: userId });
    if (nextCursor) params.set("next_cursor", nextCursor);

    const res = await fetch(
      `https://api.sorsa.io/v3/followers?${params}`,
      { headers: { ApiKey: apiKey } }
    );
    const json = await res.json();

    followers.push(...(json.users || []));
    nextCursor = json.next_cursor || null;
  } while (nextCursor);

  return followers;
}
```

Cada página da Sorsa retorna até 200 perfis completos. Na API oficial, dados mínimos podem exigir consultas adicionais para completar os perfis.

## Sintaxe de busca

Revise os operadores da API v2 antes de reaproveitá-los na sintaxe web do X. Termos, frases, `from:` e `to:` podem ser mantidos quando apropriado. Use, por exemplo, `-filter:nativeretweets` para excluir repostagens nativas.

| Operador            | Exemplo                                         |
| ------------------- | ----------------------------------------------- |
| `from:`             | `from:elonmusk`                                 |
| `to:`               | `to:elonmusk`                                   |
| `since:` / `until:` | `since:2024-01-01 until:2024-02-01`             |
| Hashtag             | `#bitcoin`                                      |
| Frase exata         | `"hello world"`                                 |
| `OR`                | `bitcoin OR ethereum`                           |
| Exclusão            | `-filter:nativeretweets`                        |
| Combinação          | `from:elonmusk #bitcoin -filter:nativeretweets` |

Veja a referência de [operadores](https://docs.sorsa.io/pt-BR/search-operators). `/mentions` também aceita `min_likes`, `min_replies`, `min_retweets`, `since_date` e `until_date`; veja [menções](https://docs.sorsa.io/pt-BR/search-mentions).

## Tratamento de erros

A API oficial retorna um array `errors`:

```json theme={null}
{
  "errors": [
    {
      "message": "Not Found",
      "type": "https://api.x.com/2/problems/resource-not-found",
      "title": "Not Found Error",
      "detail": "Could not find tweet with id: [123].",
      "status": 404
    }
  ]
}
```

A Sorsa usa uma estrutura simples:

```json theme={null}
{ "message": "Tweet not found" }
```

Os códigos são `400`, `401`, `403`, `404`, `429` e `500`. Veja [códigos de erro](https://docs.sorsa.io/pt-BR/error-codes).

Ao receber 429, aguarde e tente novamente. O limite de **20 req/s** é compartilhado entre endpoints, sem janelas individuais. Veja [limites](https://docs.sorsa.io/pt-BR/rate-limits).

Função de novas tentativas compatível com as duas APIs:

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

def call_with_retry(method, url, max_retries=3, **kwargs):
    for attempt in range(max_retries):
        r = requests.request(method, url, **kwargs)
        if r.status_code == 429:
            time.sleep(2 ** attempt)
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError(f"Failed after {max_retries} retries")
```

## Checklist de migração

* Troque `Authorization: Bearer ...` por `ApiKey: ...`.
* Remova a lógica de assinatura OAuth 1.0a do caminho migrado.
* Troque `https://api.x.com/2` por `https://api.sorsa.io/v3`.
* Mapeie os caminhos pelas tabelas.
* Troque GET por POST nos endpoints de publicações, busca, comentários, citações e repostagens.
* Remova `tweet.fields`, `user.fields`, `media.fields` e `expansions`.
* Atualize os parsers, removendo a estrutura `data`/`includes`/`meta`.
* Renomeie campos, como `name` para `display_name` e `text` para `full_text`.
* Acesse métricas sem `public_metrics`.
* Troque `pagination_token`/`next_token` por `next_cursor`.
* Trate o formato `{ "message": "..." }`.
* Ajuste o limitador para 20 req/s, sem janelas por endpoint.
* Teste operações críticas no [API Playground](https://api.sorsa.io/playground).
* Monitore a cota com `GET /key-usage-info`.
* Mantenha a API oficial para escrita, se necessário.

## Recursos sem equivalente direto na API oficial

| Recurso                                                | Endpoint                                            |
| ------------------------------------------------------ | --------------------------------------------------- |
| Timeline sem teto de 3.200 publicações                 | `POST /user-tweets`                                 |
| Verificação de seguir em uma chamada                   | `POST /check-follow`                                |
| Verificação de repostagem em uma chamada               | `POST /check-retweet`                               |
| Verificação de comentário em uma chamada               | `GET /check-comment`                                |
| Verificação de citação/repostagem em uma chamada       | `POST /check-quoted`                                |
| Verificação de participação na comunidade              | `POST /check-community-member`                      |
| Membros e feed de comunidade                           | `POST /community-members`, `POST /community-tweets` |
| Busca em comunidade                                    | `POST /community-search-tweets`                     |
| Conteúdo completo de artigo do X                       | `POST /article`                                     |
| Filtro de seguidores verificados                       | `GET /verified-followers`                           |
| País e histórico de mudanças de nome                   | `GET /about`                                        |
| Pontuação de influência                                | `GET /score`, `GET /score-changes`                  |
| Principais seguidores e contas seguidas por influência | `GET /top-followers`, `GET /top-following`          |
| Seguidores por categoria                               | `GET /followers-stats`                              |

## Referências relacionadas

* [Autenticação](https://docs.sorsa.io/pt-BR/authentication)
* [URL base e versões](https://docs.sorsa.io/pt-BR/base-url-and-versioning)
* [Limites](https://docs.sorsa.io/pt-BR/rate-limits)
* [Paginação](https://docs.sorsa.io/pt-BR/pagination)
* [Erros](https://docs.sorsa.io/pt-BR/error-codes)
* [Formato de resposta](https://docs.sorsa.io/pt-BR/response-format)
* [Operadores](https://docs.sorsa.io/pt-BR/search-operators)
* [Otimização](https://docs.sorsa.io/pt-BR/optimizing-api-usage)
* [Referência da API](https://docs.sorsa.io/pt-BR/api-reference-guide)
