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

# AG2 Twitter API Search Guide for Python Agents

> Give AG2 agents typed tweet search through Xquik with XquikSearchToolkit, runtime Variables, cursor pagination, and delegated multi-agent research workflows.

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

[AG2](https://github.com/ag2ai/ag2) is an open-source Python framework for multi-agent systems. AG2 1.0.0 and later ship `XquikSearchToolkit` in `ag2.extensions.tools.search`, so Xquik tweet search reaches AG2 agents without a community adapter. AG2 documents the toolkit in its [Xquik Tweet Search reference](https://docs.ag2.ai/docs/user-guide/extensions/tools/search/xquik/). Preserve every tweet ID and cursor the API returns.

## Why Use AG2 With the Xquik Twitter API?

AG2 binds search parameters when a tool is constructed, not when the model calls it. The agent chooses the query. You choose the window, the ordering, and the result limit.

| Boundary          | AG2 control               | Benefit                                                                |
| ----------------- | ------------------------- | ---------------------------------------------------------------------- |
| Tool construction | `XquikSearchToolkit(...)` | Fix `query_type`, `limit`, and time windows outside model control      |
| Model surface     | Single `query` argument   | The model cannot widen the search window or result limit               |
| Runtime scope     | `Variable`                | Resolve per-user or per-tenant values at execution time                |
| Delegation        | `Agent.as_tool()`         | Keep the searcher's tool-call history out of the coordinator's context |
| Transport         | `base_url`, `timeout`     | Point at a proxy or tighten deadlines per deployment                   |

This suits research, monitoring, and reporting agents. Use direct REST for deterministic jobs that need no model decisions.

## AG2 Twitter API Prerequisites

* Python 3.10 or later
* An [Xquik API key](/x-api-quickstart) beginning with `xq_`
* An LLM provider key supported by AG2

Public X reads need no X Developer credentials. Authenticate with Xquik.

## Install AG2

```bash theme={null}
python -m pip install "ag2>=1.0.0"
```

`XquikSearchToolkit` calls the Xquik REST API over `httpx`, which AG2 already depends on. No extra package is required. Install your model provider extra as well.

```bash theme={null}
python -m pip install "ag2[anthropic]>=1.0.0"
```

Store secrets outside source control.

```bash .env theme={null}
XQUIK_API_KEY=xq_YOUR_KEY_HERE
ANTHROPIC_API_KEY=YOUR_ANTHROPIC_KEY
```

```text .gitignore theme={null}
.env
```

## Register the Xquik Tweet Search Tool

Passing the toolkit to an agent registers one tool, `xquik_tweet_search`. It takes a single `query` argument holding an X search string.

```python theme={null}
import asyncio
import os

from ag2 import Agent
from ag2.config import AnthropicConfig
from ag2.extensions.tools.search import XquikSearchToolkit
from dotenv import load_dotenv

load_dotenv()
config = AnthropicConfig(model="claude-sonnet-4-6")

agent = Agent(
    "x-researcher",
    prompt=(
        "Search X for evidence before answering. "
        "Quote tweet text verbatim and keep every tweet ID you receive."
    ),
    config=config,
    tools=[XquikSearchToolkit(api_key=os.environ["XQUIK_API_KEY"])],
)


async def main() -> None:
    reply = await agent.ask("What are developers saying about the Xquik API this week?")
    print(reply.body)


asyncio.run(main())
```

`api_key` is required. The toolkit raises `ValueError` when it is empty, so a missing key fails at construction rather than on the first search.

## Bind the Search Window Outside Model Control

Search defaults belong on the constructor. The model then cannot widen the window or raise the result limit.

```python theme={null}
toolkit = XquikSearchToolkit(
    api_key=os.environ["XQUIK_API_KEY"],
    query_type="Latest",              # "Latest" or "Top"
    limit=50,
    since_time="2026-01-01T00:00:00Z",
    until_time="2026-02-01T00:00:00Z",
)
```

| Parameter    | Type                  | Purpose                                         |
| ------------ | --------------------- | ----------------------------------------------- |
| `query_type` | `"Latest"` \| `"Top"` | Result ordering                                 |
| `limit`      | `int`                 | Upper bound on returned results                 |
| `since_time` | `str`                 | Start of the time window                        |
| `until_time` | `str`                 | End of the time window                          |
| `cursor`     | `str`                 | Resume from a prior page                        |
| `base_url`   | `str`                 | Defaults to `https://xquik.com`                 |
| `timeout`    | `float`               | Request deadline in seconds, defaults to `60.0` |

The same parameters are available on the `search()` factory method when you want several differently scoped tools from one toolkit.

```python theme={null}
toolkit = XquikSearchToolkit(api_key=os.environ["XQUIK_API_KEY"])

latest = toolkit.search(
    query_type="Latest",
    limit=50,
    name="search_latest_posts",
    description="Search the newest public X posts.",
)

top = toolkit.search(
    query_type="Top",
    limit=20,
    name="search_top_posts",
    description="Search the highest-engagement public X posts.",
)

agent = Agent("analyst", config=config, tools=[latest, top])
```

## Read the Structured Result

`xquik_tweet_search` returns a typed response rather than a raw payload.

| Field           | Type         | Meaning                                      |
| --------------- | ------------ | -------------------------------------------- |
| `query`         | `str`        | The query that was searched                  |
| `tweets`        | `list[dict]` | Tweet records exactly as returned by the API |
| `has_next_page` | `bool`       | Whether another page exists                  |
| `next_cursor`   | `str`        | Cursor for the next page, empty when absent  |

Tweet records pass through unmodified, so every tweet ID, profile ID, and timestamp survives the hop into the agent. Feed `next_cursor` back through the `cursor` parameter to continue pagination.

## Resolve Values at Runtime With Variables

Every runtime parameter accepts an AG2 `Variable`. AG2 resolves it from the run context when the tool executes, so one tool instance serves many users or tenants.

```python theme={null}
from ag2.annotations import Variable

toolkit = XquikSearchToolkit(
    api_key=os.environ["XQUIK_API_KEY"],
    since_time=Variable("window_start"),
    until_time=Variable("window_end"),
    limit=Variable("page_size"),
)
```

## Delegate Search in a Multi-Agent Team

`Agent.as_tool()` exposes an agent as a tool for another agent. Each delegated task runs on its own stream with its own history. The coordinator receives the delegate's final answer, not its internal tool-call history.

```python theme={null}
searcher = Agent(
    "searcher",
    prompt="Search X and return tweet text with IDs. Do not summarise.",
    config=config,
    tools=[XquikSearchToolkit(api_key=os.environ["XQUIK_API_KEY"], query_type="Latest", limit=50)],
)

analyst = Agent(
    "analyst",
    prompt="Turn tweet records into a factual brief. Keep every tweet ID.",
    config=config,
)

coordinator = Agent(
    "coordinator",
    prompt="Delegate the search, then pass the tweets to the analyst.",
    config=config,
    tools=[
        searcher.as_tool(description="Search public X posts and return raw tweet records."),
        analyst.as_tool(description="Analyse tweet records. Pass them in the context parameter."),
    ],
)

reply = await coordinator.ask("Brief me on this week's discussion of X API pricing.")
print(reply.body)
```

## Handle Failures

The tool raises on non-success HTTP status codes through `httpx`. Read [Error Handling](/guides/error-handling) for status semantics and [Rate Limits](/guides/rate-limits) for retry guidance. Wrap the toolkit with AG2 tool middleware when you need retries, approval gates, or audit logging around every search.

## Related Guides

* [AG2 Xquik Tweet Search reference](https://docs.ag2.ai/docs/user-guide/extensions/tools/search/xquik/)
