Docs

Researcher Docs

Create paid research runs, watch progress, retrieve the final report, and keep iterating against the same source corpus.

Updated May 30, 2026 ยท Base URL https://researcher.now

Quick start

Bearer auth is required for authenticated /v1/* routes.

Base URL: https://researcher.now. Use Authorization: Bearer $RESEARCHER_TOKEN or a customer rk_... key. If a customer has no key yet, send them to https://researcher.now/account/?setup=agent.

export RESEARCHER_BASE_URL="https://researcher.now"
export RESEARCHER_TOKEN="${RESEARCHER_TOKEN:-$RESEARCHER_API_KEY}"

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-123" \
  -d '{
    "source": {"type": "topic", "topic": "recent advances in battery recycling"},
    "instructions": "Return the main technical bottlenecks, best sources, and open questions.",
    "limits": {"maxCostUsd": 10}
  }'

MCP

Hosted Model Context Protocol access for customer agents.

Endpoint: https://researcher.now/mcp. The MCP server uses Streamable HTTP JSON-RPC and accepts customer bearer keys only. Admin/operator tokens are rejected.

export RESEARCHER_TOKEN="rk_..."
codex mcp add researcher-now --url https://researcher.now/mcp --bearer-token-env-var RESEARCHER_TOKEN

Current tools: analyze_article, analyze_video, deep_research, research_status, and recall_research. analyze_article and analyze_video return formatted markdown or a full transcript plus the finished structured analysis and a viewerUrl agents must share with the user; deep_research returns a cited, synthesized research report plus watchUrl/viewerUrl agents must share with the user, and takes a topic argument only in this production version.

Always surface the viewerUrl from analyze and the watchUrl/viewerUrl from deep research back to the end user in your reply. These are durable, shareable research artifacts the user expects to open, share, and revisit. Do not swallow these links.

Run Analyst chat, direct URL/feed/video run ingestion, source mutation, destructive controls, account-key creation, webhooks, entities, and admin/operator paths are intentionally left on REST or deferred until their billing and URL-safety invariants are complete.

Guides

Use these patterns to pick the right endpoint and avoid duplicate work.

Auth and billing

Customer agents should use an environment token when present, or direct the customer to account setup. A run budget is a maximum session deposit; the billed amount is metered usage. If funding is missing, Researcher returns 402 Payment Required with a funding URL when available.

curl -sS "$RESEARCHER_BASE_URL/v1/me" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN"

Create a research run

Use POST /v1/runs for every new run. Set source.type to topic, url, feed, or video, and include an Idempotency-Key.

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: run-123" \
  -d '{
    "requestedBy": "customer-agent",
    "source": {"type": "topic", "topic": "GLP-1 impact on food markets"},
    "mode": "collection",
    "depth": "standard",
    "limits": {"maxCostUsd": 10}
  }'

YouTube, website, and feed analysis

Use the same run endpoint for direct source analysis. Video sources fetch transcripts and create a media report; URL sources ingest one URL or a same-domain corpus without broad web search; feed sources ingest current RSS, Atom, or JSON Feed items.

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: video-123" \
  -d '{"source": {"type": "video", "url": "https://www.youtube.com/watch?v=VIDEO_ID"}, "limits": {"maxCostUsd": 3}}'

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: url-123" \
  -d '{"source": {"type": "url", "url": "https://example.com", "scope": "domain"}, "limits": {"maxCostUsd": 5}}'

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: feed-123" \
  -d '{"source": {"type": "feed", "url": "https://example.com/feed.xml", "limit": 50}, "limits": {"maxCostUsd": 10}}'

Watch progress

Run creation returns a watchUrl for humans and a viewerUrl for durable sharing plus a streamUrl for agents. Share the watch URL and viewer URL immediately. Use SSE snapshots or /job for concise status updates.

curl -N "$STREAM_URL"

curl -sS "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/job" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN"

Read the results

Fetch markdown for a simple report, /results for an agent-friendly bundle, and ?include=all when you need sources, artifacts, usage, events, media, and extraction records.

curl -sS "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/markdown" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN"

curl -sS "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/results" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN"

Ask the run

/chat and chat sessions are scoped to one completed run. They answer from the curated corpus, preserve source citations, and return a sessionId for follow-up turns.

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/chat" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "What are the strongest claims and weakest evidence?"}'

Iterate without losing context

Use /iterate with action to continue the same run, deepen evidence, focus on gaps, fork a review version, evaluate output, or regenerate a report after source edits.

ContinueUse when the same run should keep working with inherited context.
DeepenUse when the answer is directionally right but needs broader evidence.
FocusUse when specific gaps, subtopics, or counterarguments need attention.
SteerUse when an operator wants to add constraints or priorities before more work.
ForkUse when a separate version should exist for customer feedback or review.
curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/iterate" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fork-123" \
  -d '{"action": "fork", "requestedBy": "customer-agent"}'

curl -sS -X POST "$RESEARCHER_BASE_URL/v1/runs/$RUN_ID/iterate" \
  -H "Authorization: Bearer $RESEARCHER_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: focus-123" \
  -d '{"action": "focus", "focus": ["contrarian evidence", "company-level winners and losers"]}'

API reference

Grouped by workflow surface, not implementation order.

Setup and auth

GET/health

Service liveness.

POST/auth/device

Start the customer API-key device flow.

POST/auth/device/confirm

Confirm a device code with a Privy bearer token.

POST/auth/device/token

Poll for the one-time raw customer key.

GET/v1/me

Return token role, account, and scopes.

Public viewer

GET/public/research-runs/by-slug/:code

Read-only status payload for short customer URLs.

GET/public/research-runs/by-slug/:code/stream

Public SSE stream for viewer-safe snapshots.

GET/public/research-runs/by-slug/:code/sources/:sourceId

Stored source copy. Add ?format=md for markdown.

Run creation

POST/v1/runs

Canonical creation for topic, URL, feed, and video sources. Add preflightPlan:true to preview before spending.

Run reads

GET/v1/runs/:id

Run state. Add ?include=all or field-specific includes.

GET/v1/runs/:id/job

Durable job status and current lifecycle fields.

GET/v1/runs/:id/results

Agent-optimized report, findings, sources, and next actions.

GET/v1/runs/:id/markdown

Final report markdown.

GET/v1/runs/:id/usage

Provider usage, raw cost, billable totals, and stage breakdown.

GET/v1/runs/:id/stream

Authenticated SSE stream with live snapshots.

GET/v1/runs/:id/transcript

Typed transcript segments for video runs.

GET/v1/runs/:id/events

Planning, acquisition, extraction, merge, synthesis, and completion events.

GET/v1/runs/:id/artifacts

Structured artifacts and markdown outputs.

Sources and extraction records

GET/v1/runs/:id/sources

Stored source rows and captured markdown.

GET/v1/runs/:id/sources/:sourceId

One stored source as HTML or markdown with ?format=md.

POST/v1/runs/:id/sources

Add one or more sources to a run.

PATCH/v1/runs/:id/sources/:sourceId

Add, update, or clear a source comment.

DELETE/v1/runs/:id/sources

Remove multiple sources from the corpus.

DELETE/v1/runs/:id/sources/:sourceId

Remove one source from the corpus.

GET/v1/runs/:id/extractions

Source-level extractions and synthesis-facing source-grounded records.

GET/v1/runs/:id/extractions/:sourceId

One processed source record.

POST/v1/runs/:id/sources/:sourceId/redo

Re-analyze a weak source with optional instructions.

Run controls

POST/v1/runs/:id/iterate

Canonical wrapper for start, pause, continue, deepen, focus, steer, report, fork, evaluate, cancel, and stop.

DELETE/v1/runs/:id

Delete a run after access is verified.

Run Analyst and chat

POST/v1/runs/:id/chat

Run-scoped chat turn grounded in one corpus.

GET/v1/runs/:id/chat/sessions

List run chat sessions.

POST/v1/runs/:id/chat/sessions

Create a run chat session.

GET/v1/runs/:id/chat/sessions/:sessionId

Read one run chat session.

PATCH/v1/runs/:id/chat/sessions/:sessionId

Rename one run chat session.

DELETE/v1/runs/:id/chat/sessions/:sessionId

Delete one run chat session.

POST/v1/runs/:id/chat/sessions/:sessionId/messages

Add a chat message.

GET/v1/runs/:id/chat/turns/:turnId/stream

Stream an analyst turn.

DELETE/v1/runs/:id/chat/turns/:turnId

Cancel an analyst turn.

GET/v1/runs/:id/chat/index

Read retrieval-index status.

POST/v1/runs/:id/chat/index/rebuild

Rebuild the run retrieval index.

Entity chat

POST/v1/entities/:id/chat

Entity-scoped chat turn grounded in the active entity index.

GET/v1/entities/:id/chat/sessions

List durable entity chat sessions.

POST/v1/entities/:id/chat/sessions

Create an entity chat session.

GET/v1/entities/:id/chat/sessions/:sessionId

Read one entity chat session.

PATCH/v1/entities/:id/chat/sessions/:sessionId

Rename one entity chat session.

DELETE/v1/entities/:id/chat/sessions/:sessionId

Delete one entity chat session.

POST/v1/entities/:id/chat/sessions/:sessionId/messages

Add an entity chat message.

GET/v1/entities/:id/chat/turns/:turnId/events

Read persisted entity chat turn events.

Library, organization, and exports

GET/v1/library

Archived completed runs with search and filters.

GET/v1/library/sources

Reusable source rows across completed runs.

GET/v1/library/evidence

Extracted evidence across completed runs.

GET/v1/library/search

Semantic claim/library search.

GET/v1/library/recall

Related runs, sources, and evidence for a topic.

GET/v1/runs/:id/diff

Compare parent and child run outputs.

GET/v1/runs/:id/tags

List run tags.

POST/v1/runs/:id/tags

Add tags to a run.

DELETE/v1/runs/:id/tags

Remove multiple tags or clear all tags.

POST/v1/runs/:id/export

Build a one-off export payload.

GET/v1/collections

List run collections.

POST/v1/collections

Create a collection.

POST/v1/collections/:id/runs

Add a run to a collection.

DELETE/v1/collections/:id/runs/:runId

Remove a run from a collection.

GET/v1/webhooks

List terminal-run webhook subscriptions.

POST/v1/webhooks

Create an account-scoped terminal webhook. Use event:"run.complete" for succeeded, failed, and cancelled runs.

DELETE/v1/webhooks/:id

Disable a webhook subscription.

Account and billing

GET/v1/account/balance

Authenticated account, customer, and wallet status.

GET/v1/runs

Recent customer runs with budget, billed, cost, and watch URL.

GET/v1/account/chats

Global run/start chat session listing.

GET/v1/account/keys

List active customer API keys.

POST/v1/account/keys

Create a raw rk_... key once.

PATCH/v1/account/keys/:id

Rename a customer API key.

DELETE/v1/account/keys/:id

Revoke a customer API key.

GET/v1/account/deposit-addresses

List wallet deposit addresses.

POST/v1/account/deposit-addresses

Create a deposit address.

Run lifecycle

What to show customers while work is active.

  1. Formulating plan. The worker turns the prompt into a structured plan and contract.
  2. Acquiring sources. Search, direct URLs, YouTube transcripts, and library recall populate candidates.
  3. Extracting evidence. Source-level LLM records capture claims, caveats, metrics, and diagnostics.
  4. Analyzing corpus. Records are merged into claims, comparisons, gaps, and source coverage.
  5. Writing report. The report follows the customer output contract and stores artifacts.
  6. Completing or continuing. If budget is reached after usable evidence exists, Researcher writes the best budget-limited report and leaves continuation as the next paid action.

Outputs and artifacts

Fetch markdown for reading; fetch artifacts when agents need structure.

research_report_markdown_v1

Customer-facing report.

agent_brief_markdown_v1

Agent reasoning handoff.

corpus_analysis_v1

Claims, clusters, comparisons, gaps, and best sources.

research_quality_review_v1

Coverage gate and remaining issues.

source_extraction_v1

Per-source claims, facts, caveats, and diagnostics.

source_analysis_record_v1

Durable synthesis-facing evidence records.

claim_evidence_map_v1

Grounded claims with confidence and source IDs.

record_index_v1

Compact source-to-claim pointers.

For downstream saving, fetch the report, sources, and extraction records. Strip raw YouTube transcript blobs before sending data into another LLM; use /transcript for typed transcript segments instead.