When to use Exa Agent
Use Exa Agent when a workflow needs more than a single search or extraction call:- Build lists from open-ended criteria, then enrich each result
- Research entities across many fields with citations
- Run multi-hop tasks like “find companies, then find their decision makers”
- Produce structured JSON from a long-running web research task
- Continue from a previous run with a follow-up request like “find 10 more results”
Quickstart
This example starts a run that builds a structured list of people matching your criteria. It returns JSON inoutput.structured.
1. Install the Exa SDK
2. Set your API key
- macOS/Linux
- Windows
3. Create a run
Accept: text/event-stream when creating a run to receive server-sent events as the run is queued, started, and completed. See Stream events for more details.
4. Poll for completion
If you do not stream events, save the returnedid and poll the run until it reaches a terminal status.
output.text: a natural-language answeroutput.structured: validated JSON when you provideoutputSchemaoutput.grounding: citations for text or structured fields, when emittedcostDollars: the run’s cost breakdown
Stream events
Streaming keeps the create request open and sends Server-Sent Events (SSE) until the run completes. See Event format for the event types and payloads. Setstream=True in Python, stream: true in TypeScript, or send Accept: text/event-stream over HTTP:
Event format
Each SSE frame contains an event ID, event name, and JSON payload:: keep-alive. SSE clients ignore comments automatically; custom parsers should do the same.
Event types
Events associated with the same research step include a
callId. It corresponds to item.call_id in tool progress events. Use it to group search traces, sources, and tool progress. Some search-trace descriptions are generated asynchronously and can arrive after the source or tool event they describe, so do not correlate them by arrival order alone.
Treat agent_run.source.added as a live preview rather than a complete citation list. The terminal run’s output.grounding is the authoritative grounding output.
Replay stored events
For non-ZDR runs,GET /agent/runs/{id}/events returns stored events as paginated JSON. Send Accept: text/event-stream to replay the stored events as SSE, and Last-Event-ID to skip events your client has already processed:
cURL
Return structured JSON
UseoutputSchema when you need /agent to return in specific format. When you specify an outputSchema, the returned object will contain an output matching your outputSchema in output.structured.
outputSchema supports the JSON Schema specification.
To request contact information, describe the desired contact fields in outputSchema. Use standard JSON Schema shapes such as { "type": "string", "format": "email" } for email addresses, { "type": "string", "format": "phone" } for phone numbers, and { "type": "string", "format": "uri" } for URLs. Bound list sizes with maxItems when possible so the maximum contact-enrichment cost is predictable.
Process input rows
Useinput.data when you have an existing set of data that you want to enrich. You can add more fields to each data entity, surface more entities based on the data you bring in, or both.
For complete row-enrichment examples, see Agent examples.
Process exclusions
Useinput.exclusion to exclude certain entries from being surfaced in the run. In the example below, we want to look for the top 10 cutest animals, but we exclude goats and pandas from the run because we already know how cute they are.
Connect data sources
UsedataSources to attach premium data partners to a run. Each entry selects a provider. When a property in your outputSchema references a specific source (e.g., “from Similarweb”), Exa Agent calls the matching provider tool instead of a generic web search.
Continue from a previous run
UsepreviousRunId to ask follow-ups to the run’s previous response. Each follow-up starts a new run with its own run ID — the previousRunId is only used to carry over context from the prior run, not reused as the new run’s ID.
Find a run ID
List recent runs and inspect their statuses:Pricing
Costs are usage-based and priced by component:Contact enrichment is separate from the core pricing components above: email contact enrichment is
$0.02 / email, and phone number contact enrichment is $0.07 / phone number.usage.agentComputeUnits measures model computation across the full run. More complex queries, or queries that contain a large input.data field will generally take more reasoning steps and make more tool calls, and will generally consumer more ACUs.
Your Agent concurrency limit is one fifth of your account QPS. For pay-as-you-go accounts with default QPS, this means two active Agent runs at a time.
Effort
Useeffort to set a cost and reasoning effort preference for a run. Supported values are minimal, low, medium, high, xhigh, and auto; the default is auto. If a fixed effort is set, each run is charged at the following request price:
Choosing an effort mode
Fixed effort modes are best when you want predictable per-request cost on standard research tasks. Useauto for variable-scope tasks, especially list building or workflows where the number of entities can vary significantly from request to request.
Use
medium as the default starting point for standard single-entity research tasks. Move down to low or minimal when cost and latency matter more than completeness. Move up to high or xhigh when the output schema is larger, fields require verification, or the task needs deeper reasoning. Use auto when the task scope is not known ahead of time, such as list building or workflows where one request may return many entities.
Runtime varies by query difficulty, schema complexity, and external source availability. Treat effort modes as quality/cost/runtime tradeoffs rather than strict latency guarantees.
Zero Data Retention
Exa Agent supports Zero Data Retention (ZDR). ZDR is enabled per team — contact us to enable it for your account. When ZDR is enabled for your team:- Runs must be created with streaming (
Accept: text/event-stream). Consume the run’s output from the live SSE stream — Exa does not retain your query, request, or output, so they cannot be retrieved after the run completes. See Stream events for SDK and cURL examples and the complete event contract. - The OpenAI-compatible Responses endpoints are not available. Use
/agent/runswithAccept: text/event-stream. previousRunIdis not available on ZDR runs.- Creating a run without streaming, or with Exa Connect
dataSourcesset, returns a400error when ZDR is enabled.