> ## 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`. 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/). Keep every tweet ID and cursor the API returns.

## Why use AG2 with the Xquik Twitter API?

AG2 binds search parameters when you construct a tool, 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 input | 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 |

Use AG2 for 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. You need no extra package. 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. A missing key fails at construction, not on the first search.

## Bind the search window outside model control

Set search defaults 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 `search()` factory method takes the same parameters 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, not a raw payload.

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

The toolkit passes tweet records through unmodified. The agent receives every tweet ID, profile ID, and timestamp. 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. 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/)


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