Skip to main content
POST
deep_search

Authorizations

X-API-Key
string
header
required

Headers

Idempotency-Key
string | null

Replaying a request with the same key returns the original job with 200, never a second job.

Maximum string length: 200

Path Parameters

workspace_id
string<uuid>
required

Workspace identifier.

Query Parameters

wait_seconds
integer
default:0

Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read status.

Required range: 0 <= x <= 300

Body

application/json

Body for POST /workspaces/{workspace_id}/deep-search — always the agent loop.

Deliberately no effort: the route IS the implementation choice, and the agent loop always gets its full step budget. The strict base rejects the removed field outright rather than silently accepting a knob that does nothing. include_answer is removed the same way: every run answers now, stating its reading of the query in the result's interpretation — the evidence-only mode is gone, and the strict base rejects the field rather than accepting a toggle with one legal value.

query
string
required
Required string length: 1 - 4096
allow_clarification
boolean
default:false

Let the agent finish the run with ONE clarifying question instead of an answer, when the query is genuinely ambiguous and the ambiguity materially changes the answer. The rejected result carries the question in clarification (with answer, interpretation and reasoning null and evidences empty); answer it by re-asking in the same thread via the result's session_id. Off — the default — means the agent always answers with its best reading, stated in interpretation.

context
string | null
Maximum string length: 20000
path_prefix
string | null
paths
string[] | null

Scope the run to exactly these uploaded files. Every retrieval tool the agent runs — search, listings, reads, table queries, the shell — sees only these files and the content ingested from them; everything else is invisible to the run. Each entry names an uploaded source file (never a folder — scope folders with path_prefix, which composes with this as an intersection). Unknown or inaccessible paths are refused up front.

Required array length: 1 - 64 elements
Required string length: 1 - 1024
session_id
string<uuid> | null

Continue a prior deep-search conversation: the id echoed on an earlier result's session_id. The agent resumes with that thread's full context and treats this request's query as the follow-up. Omit to start a new thread. Only the API key that started the thread may continue it; a thread whose turn is still running returns 409 session_busy.

tier
enum<string>
default:low

Quality and cost tier for the main deep-search agent. The service maps the tier to a catalogued model; supporting model calls keep their own defaults. The internal exact-model header overrides this selection when present.

Available options:
low,
medium,
high

Response

Successful Response

Every slow method returns one of these (spec 12 §1.4).

There is no /parse + /parse_async pair: every job-creating route returns 202 with a queued job and accepts ?wait_seconds=, returning 200 with a terminal job if the work finished inside the window. The caller's code path is the same either way — read status.

created_at
string<date-time>
required
job_id
string<uuid>
required
kind
enum<string>
required

What a job is doing. Open enum — a new member is additive.

Available options:
parse,
split,
classify,
categorize,
extract,
ground,
ingestion,
reconciliation,
kg_build,
file_upload,
file_replace,
upload_session_complete,
file_delete,
workspace_delete,
intelligent_search,
qa_file,
qa_tables,
filtered_search,
je_testing,
deep_search_v2
status
enum<string>
required

cancelled is a first-class terminal status, not a failed variant.

Conflating them makes error-rate metrics lie and forces every client to string-match an error code.

Available options:
queued,
running,
succeeded,
failed,
cancelled
deleted_at
string<date-time> | null

When the caller hid this run from listings, via delete_job. A soft delete: the job still reads by id and still counts toward GET /v1/usage — what it stops doing is appearing in GET /v1/jobs.

effort
string | null

Which implementation ran this job, for the one kind whose request carries an effort (intelligent_search): 'fast' is fact-search, 'deep' (or the legacy 'balanced') is deep-search and the console's QA chat — a deep-search run under another surface, not a fourth implementation, so this field cannot tell those two apart. Null for every other kind. Read from the stored request, so it rides the same retention path as query and result: null once result_state leaves available.

error
Error · object | null

Present only on failed.

finished_at
string<date-time> | null
force
boolean | null

The request's own force flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — result alone cannot, since it is absent on failure either way.

idempotency_key
string | null
name
string | null

Caller-chosen display name (the console's 'project'). Mutable via PATCH /v1/jobs/{job_id}.

payload_expires_at
string<date-time> | null
progress
JobProgress · object | null

Absent until running.

project_id
string<uuid> | null

Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.

query
string | null

The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as result: null once result_state leaves available. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as query_scope.

query_scope
WorkspaceQueryScope · object

The question ran against the whole workspace.

result
ParseResult · object

Present only on succeeded, and only while retained.

result_state
enum<string>
default:available

Why Job.result is null.

available with a null result means the job has not succeeded yet; expired means retention dropped it; not_retained means the client is provisioned zero_retention and already had its one chance to read it. A late poll returns the job with a state, never a 404 — "this expired" and "this never existed" are a scheduling problem and a bug respectively, and a 404 makes them identical.

Available options:
available,
expired,
not_retained
source
UploadSource · object

Bytes staged through POST /v1/uploads. Single-use, TTL-bound.

started_at
string<date-time> | null
units
integer
default:0
workspace_id
string<uuid> | null

The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.