Beta: The Research API is available to everyone while in beta. Contact support if you encounter any bugs.
Endpoints
All endpoints use
https://agent.tinyfish.ai and require the X-API-Key header.
Research must be enabled for the API key’s account.
POST /v1/automation/run-research returns 403 when it is not.Modes
An omitted mode selects
deep. Both modes research with search and static fetches.
Request Body
Do not combine
recency_minutes with date filters. Date and recency filters are unavailable for research_paper.
session_id and prior_run_id are mutually exclusive.Event Stream
Accepted requests returntext/event-stream, including when stream is omitted or false. Invalid input and other
pre-run failures return the standard JSON error body.
Ordered
synthesis_delta values reconstruct their matching summary or final result. Discard a provisional partial
checkpoint after synthesis_discarded. Heartbeats keep long-running connections open.
Run Statuses
COMPLETED, FAILED, CANCELLED, and TIMED_OUT are terminal.
List Saved Runs
GET /v1/research-run supports status, query, created_after, and created_before. Pagination uses limit from
1–100, sort_direction=asc|desc, and the returned next_cursor. Reuse a cursor only with the same sort direction.
quick_result holds answers from runs made before standard mode was removed; deep_result holds the report. Both are objects: read the
report from deep_result.result, not from deep_result itself. quick_result_summary is the one plain string.
run_ids lists the Agent runs a Max run started. Fields that do not apply to the run are null.
Retrieve One Run
GET /v1/research-run/{research_run_id} returns the list fields plus the working state kept for the run.
A run that does not exist returns HTTP
404. A run owned by another API key returns HTTP 403.
Cancel a Run
CallPOST /v1/research-run/{research_run_id}/cancel to cancel a running research run. The response reports whether
this request changed the run to CANCELLED and includes its current status.
200 with cancelled: false and its current
status. A missing run, or a run owned by another API key, returns HTTP 404.
Limits
Research is limited by concurrent runs (5 per account by default) and by a daily free allowance of runs (5 per day by default) that resets at 00:00 UTC. A run counts against the allowance when it completes; runs that fail, time out, or are cancelled do not count. Contact support if you need higher limits. Starting a run beyond the concurrent limit returns HTTP429 with error.code set to RATE_LIMIT_EXCEEDED.
While Research is in beta it does not charge your wallet: once the day’s allowance is used, starts return HTTP 402
with error.code set to FREE_ALLOWANCE_EXHAUSTED until the allowance resets. When Research charges the wallet, runs
beyond the allowance need a positive wallet balance instead; with a balance of zero or below, starts return HTTP 402
with INSUFFICIENT_CREDITS until you add funds or the allowance resets.
503 with error.code set to SERVICE_BUSY; retry
after a short pause. If the billing check itself does not answer in time, the run starts.
Start asynchronously
UsePOST /v1/automation/run-research-async to enqueue research and return immediately:
200 with:
GET /v1/research-run/{id}returns current state and saved partial/final results.GET /v1/research-run/{id}/eventsstreams progress; reconnect withLast-Event-ID.POST /v1/research-run/{id}/cancelexplicitly cancels work.
QUEUED, RUNNING, COMPLETED, FAILED, CANCELLED, and TIMED_OUT. The last four are terminal; stop
polling when one is returned. Partial results can exist on unsuccessful runs, so inspect status before treating a
report as complete. Disconnecting an event stream does not cancel the job. Retained progress events expire; polling
remains the durable source for saved results.
For a single-request stream, keep using POST /v1/automation/run-research. The request field stream controls
synthesis text deltas, not async versus SSE delivery. Both start endpoints accept the same research parameters and
limits.
Polling responses also include error: null for queued, running, or completed runs, otherwise {code, message} with
TASK_FAILED, CANCELLED, or TIMEOUT. These describe the persisted terminal outcome, not a
detailed provider failure. Existing result fields remain available, including partial reports.
Async starts are not idempotent. Retrying a POST after a timeout can create a
second run and incur additional usage. Keep the returned research_run_id and
poll or reconnect to that run. If no ID was received, the run may still have been
accepted; check your run list before starting another.
Incompatible optional fields in older saved runs return null and are logged;
other valid report fields remain readable.