API Reference
The Deep Research Assistant exposes a REST API (FastAPI) for creating, inspecting, and managing research runs. The current implementation is strict about governance for API-driven runs: required approval gates pause execution, decisions are persisted, and interrupted runs resume from durable checkpoints.
Base URL
http://localhost:8080/v1 End-to-End Demo
The example below shows a complete curl-driven deep research run, including strict approval handling, progress inspection, file-backed run logs, and final export.
1. Start the API server with Exa enabled
export DEEP_RESEARCH_EXA_API_KEY="your-exa-key"
export DEEP_RESEARCH_APPROVALS__MODE="strict" 2. Create a deep research run
curl \
-X POST "http://localhost:8080/v1/research-runs" \
-H "Content-Type: application/json" \
-d '{
"objective": {
"title": "ADK tool governance deep research demo",
"primary_question": "How should a Google ADK-based research assistant govern tool usage safely in an enterprise environment?",
"decision_to_support": "Choose runtime guardrails for production rollout",
"intended_audience": ["platform engineering", "security architecture"],
"output_type": "technical_report",
"desired_depth": "deep"
},
"tenant_id": "demo",
"user_id": "architect-01",
"mode": "review_first"
}' Example response:
{
"run_id": "071521de",
"status": "queued"
} Save the run_id for the remaining calls:
RUN_ID=071521de 3. Poll current status
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID" In strict mode, the run may pause like this:
{
"run_id": "071521de",
"status": "awaiting_approval"
} 4. Inspect the pending gate
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/approvals" 5. Approve the gate and resume execution
Approve Gate A:
curl \
-X POST "http://localhost:8080/v1/research-runs/$RUN_ID/approvals/A" \
-H "Content-Type: application/json" \
-d '{
"decision": "approved",
"rationale": "Scope and risk framing look correct",
"approver_id": "architect-01"
}' If the run later pauses at Gate B, C, or D, use the same pattern with /approvals/B, /approvals/C, or /approvals/D.
6. Check progress, frontier, and research graph
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/progress"
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/frontier"
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/graph"
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/concept-map" 7. Retrieve file-backed logs for this run
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/logs" Or fetch only the most recent records:
curl \
"http://localhost:8080/v1/research-runs/$RUN_ID/logs?limit=50" The log records are filtered by run_id, so you can reconstruct what happened for one research run
without scanning unrelated server output.
8. Stream live workflow events
curl \
-N "http://localhost:8080/v1/research-runs/$RUN_ID/events" 9. Export the final report
curl \
-X POST "http://localhost:8080/v1/research-runs/$RUN_ID/exports?format=markdown" 10. Optional: submit an intervention mid-run
curl \
-X POST "http://localhost:8080/v1/research-runs/$RUN_ID/interventions" \
-H "Content-Type: application/json" \
-d '{
"type": "add_question",
"instruction": "What concrete guardrails should apply to tool calls that access external systems?"
}' Endpoints
Research Runs
Create Research Run
POST /v1/research-runs {
"objective": {
"title": "Secure agent runtime analysis",
"primary_question": "Which architectural controls are required for a secure enterprise agent runtime?",
"decision_to_support": "Define platform architecture"
},
"tenant_id": "acme",
"user_id": "architect-01",
"mode": "review_first",
"constraints": {
"minimum_primary_source_ratio": 0.6,
"maximum_cost": 50
}
} Inspect Research Run
GET /v1/research-runs/{run_id} Returns the full research run aggregate with all nested entities.
Current implementation returns summary status, objective/scope, counts, and a report preview,
plus runtime statuses such as queued, running, awaiting_approval, interrupted, completed,
and failed.
Get Research Graph
GET /v1/research-runs/{run_id}/graph Returns the concept map projection: topics, questions, claims, and their relationships.
Currently returns run metadata plus claims and sources. Use /concept-map for the projected topic graph.
Get Research Frontier
GET /v1/research-runs/{run_id}/frontier Returns open, resolved, and blocked questions with priorities and dependency edges. Currently returns the current question list and priority map.
Get Progress
GET /v1/research-runs/{run_id}/progress Returns current phase, budget consumption, and completion estimates.
When a required gate pauses execution, progress reflects the awaiting_approval phase until a
decision is submitted.
Stream Events
GET /v1/research-runs/{run_id}/events SSE stream of workflow events: run.started, perspective.created, claim.created, verification.passed, etc.
The event stream is operational/live UX state. The same governance-significant events are also
written into the durable audit log internally.
Get Run Logs
GET /v1/research-runs/{run_id}/logs Returns file-backed JSON log records filtered by run_id.
Use the optional limit query parameter to cap the number of returned records.
Interventions
Apply Intervention
POST /v1/research-runs/{run_id}/interventions {
"type": "challenge_claim",
"target_id": "C-104",
"instruction": "Find independent evidence that contradicts this claim."
} Supported intervention types:
add_questionโ add a new research questionchallenge_claimโ trigger counter-evidence searchadd_topic/remove_topicโ queue a scope changeadd_perspectiveโ queue a new perspectivechange_budgetโ queue a budget change
Approvals
Get Pending Approvals
GET /v1/research-runs/{run_id}/approvals Decide Approval
POST /v1/research-runs/{run_id}/approvals/{approval_id} {
"decision": "approved",
"rationale": "Scope and risk assessment look correct"
} Approval gates:
- Gate A โ Scope: triggered for high-risk or ambiguous requests
- Gate B โ Research Plan: perspectives, questions, budget
- Gate C โ Evidence & Outline: claims, contradictions, proposed structure
- Gate D โ Publication: required for external distribution
Behavior notes:
- API-created runs enforce approvals by default.
- In strict mode, a required gate moves the run into
awaiting_approval. - Submitting an approval decision persists the decision and requeues the run from the latest durable checkpoint.
- A development
auto_approvemode exists behind configuration for local/test workflows.
Export
POST /v1/research-runs/{run_id}/exports {
"format": "markdown"
} Current implementation returns the generated report body and echoes the requested format. Dedicated HTML/JSON/evidence-package rendering is not implemented yet.
Response Model
Most endpoints currently return plain JSON objects rather than a shared response envelope.
{
"run_id": "run-001",
"status": "awaiting_approval"
} Events
The SSE event stream emits typed events at each workflow stage:
| Event | Payload |
|---|---|
run.started | {run_id, objective_title} |
scope.proposed | {scope, risk_level} |
approval.requested | {gate, display_data} |
approval.decided | {approval_id, status, rationale} |
perspective.created | {perspective_count} |
question.created | {question_count} |
query.executed | {query, results_count} |
source.accepted | {sources, accepted, rejected} |
evidence.extracted | {fragments} |
claim.created | {claims_created} |
contradiction.detected | {contradictions} |
coverage.updated | {coverage_metrics} |
outline.proposed | {section_count} |
section.generated | {section_title} |
verification.passed | {findings} |
verification.failed | {blocking_findings} |
checkpoint.created | {checkpoint_id, node} |
checkpoint.restored | {checkpoint_id, node_name} |
run.resumed | {checkpoint_id} |
run.completed | {report_length} |