Skip to main content
Attaching a partner to dataSources makes it available to the Exa Agent as a tool — it does not force the agent to call it. Whether a partner fires depends on your query and outputSchema: name the kind of result you want from each partner, and the Exa Agent reaches for the matching tool instead of guessing from a web page. You can attach up to five partners per run; the Exa Agent picks which to call for each step, with Exa web search available alongside them. Need more than five for a single run? Contact us to raise the limit.

Two partners in one run

List several partners together and the Exa Agent draws on each where it’s strongest. Two is just an example here — attach up to five partners to dataSources, and the same principle applies: ask for each one’s data explicitly. This investor-briefing run combines Financial Datasets for ticker news with Particle for podcast commentary. The query asks for each partner’s distinctive data and the schema splits the output into financialNews and podcastChatter, so the Exa Agent calls both partners in the same run.
from exa_py import Exa

exa = Exa()
run = exa.agent.runs.create(
    query=(
        "Give me an investor briefing on NVIDIA (NVDA): (1) the latest financial and "
        "earnings news, and (2) what podcast hosts and guests have recently been saying "
        "about NVIDIA, with speaker-attributed quotes and their stance."
    ),
    data_sources=[
        {"provider": "financial_datasets"},
        {"provider": "particle_news"},
    ],
    output_schema={
        "type": "object",
        "required": ["ticker", "financialNews", "podcastChatter"],
        "properties": {
            "ticker": {"type": "string"},
            "financialNews": {
                "type": "array",
                "maxItems": 6,
                "items": {
                    "type": "object",
                    "required": ["title", "source", "date", "theme"],
                    "properties": {
                        "title": {"type": "string"},
                        "source": {"type": "string"},
                        "date": {"type": "string"},
                        "theme": {"type": "string", "description": "earnings, guidance, analyst rating, product, or market"},
                    },
                },
            },
            "podcastChatter": {
                "type": "array",
                "maxItems": 6,
                "items": {
                    "type": "object",
                    "required": ["podcast", "speaker", "quote", "stance"],
                    "properties": {
                        "podcast": {"type": "string"},
                        "speaker": {"type": "string"},
                        "quote": {"type": "string"},
                        "stance": {"type": "string", "description": "bullish, bearish, or neutral"},
                    },
                },
            },
        },
    },
)
run = exa.agent.runs.poll_until_finished(run.id)
Make each partner’s data explicit in your query — name the kind of result you want from each one (here: ticker financial news vs. speaker-attributed podcast quotes). If the request is generic (“latest news”), the Exa Agent tends to fall back to web search instead of a partner. Mirroring those distinct asks in your outputSchema fields reinforces it.