Skip to main content
search.deep runs an agent over a workspace and returns a Promise<Job>. The agent picks its own tools, authors evidence, and can take minutes. Files must already be ingested.
Deep search is not chat. Each call is one question. Continue a thread only with that turn’s session_id. After the search result, poll every id in result.grounding_job_ids — do not call Ground for those evidences.
There is no tier argument. effort is the quality and cost knob, here and on search.jeTesting. Filtered search is not wrapped in the TypeScript SDK.

Basic usage


Method signature

Parameters

Returns

A Job. Which result you get depends on scope: There is no exported isDeepSearchV2Result helper. Narrow with result_type and !(result instanceof UnknownResult). A follow-up stays on the thread’s original implementation even if this call adds or drops scope.

Effort

effort maps to thinking budget. The job echoes the level as job.effort.

Scope files

Omit both paths and path_prefix for a corpus-wide, source-level run. Pass paths to pin every tool to those files (unknown or inaccessible paths are refused before a job is created). Combine with path_prefix as an intersection.

Follow-up threads

Pass the previous result’s session_id. Only the API key that started the thread may continue it. A thread whose turn is still running returns 409 session_busy. Do not reuse one session across unrelated questions.

Clarifications

With allow_clarification: true, a genuinely ambiguous query can finish with clarification set, answer null, and empty evidences. Reply on the same session_id.

Context and surface

context is caller-supplied background, not a hidden system prompt replacement. surface only groups console history (qa, workbook). Omit it from SDK integrations. Follow-ups inherit the thread head.

Result structure

exhausted: true means the step budget ran out. The job still succeeded; the answer may rest on less evidence. That is not JobFailedError.

Unscoped: deep_search_v2

Search does not wait for quote locations. After the result, poll every id in grounding_job_ids. An empty list means nothing was planned. A missing field is a job from before this field existed — only then call client.documents.ground.

Complete example


Error handling


Best practices

Ingest first

Search reads derived representations. Upload plus ingest, then ask.

One question per turn

Start a new session for a new investigation. Follow-ups belong on that turn’s session_id.

Choose effort on purpose

Leave effort unset for lookups. Use high when the extra minutes are worth it.

Read exhaustion

exhausted: true is a successful, budget-capped answer — not a failed job.

See Search methods and the Search guide.

Next steps

Workspaces

Create a corpus, upload, and ingest before searching.

Job management

Wait, stream events, and cancel long-running jobs.

Journal-entry testing

Test a ledger package and read the SQL behind each figure.