Skip to main content
POST
fact_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. The key is kept with the job for replay and never cleared, so it must not contain personal data.

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}/fact-search — always the fixed pipeline.

Deliberately no session_id: a fact-search run is single-shot and keeps no conversation, so the strict base rejects the field outright instead of a bespoke validator explaining why it cannot be honored. No effort either — the fixed pipeline has no budget presets. And no allow_clarification: the pipeline has no agent who could ask back, so it always answers — the strict base rejects the field. include_answer is accepted and ignored only because published SDK releases still send it (see :data:RetiredIncludeAnswer).

query
string
required

What to answer, in the caller's own words. Stripped before its length is checked; a blank query is refused rather than run.

Required string length: 1 - 4096
context
string | null

Free-form background for the model — the engagement, the entity, what the caller already knows. It informs the answer; it does not widen or narrow which files the caller may see.

Maximum string length: 20000
include_answer
boolean | null
deprecated

Deprecated and ignored: every run answers. Accepted so clients released before it was retired keep working; omit it.

path_prefix
string | null

Put every uploaded file under one folder subtree, workspace-relative, in the run's scope; paths, where the body takes it, adds more files. Omit both for the whole workspace.

paths
string[] | null

Scope the run to exactly these uploaded files. Every retrieval leg and agent tool sees only these files and the content ingested from them, so nothing else can be read or cited. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up, so the run covers the folder's files plus these). No limit on how many. Unknown or inaccessible paths are refused up front.

Minimum array length: 1
Required string length: 1 - 1024
top_k
integer | null

How many evidences to return, best first. Omitted means 6. It is a cap on the answer's citation list, not on how much the pipeline reads: retrieval width is fixed, so a larger top_k returns more of what was already found rather than searching further. Raising it far above the default trades citation count for reliability — the whole list is one constrained generation, and the ceiling is 50.

Required range: 1 <= x <= 50

Response

Successful Response

created_at
string<date-time>
required

When the job row was created.

job_id
string<uuid>
required

Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.

status
enum<string>
required

Lifecycle: queued, running, succeeded, failed, or cancelled.

Available options:
queued,
running,
succeeded,
failed,
cancelled
cost
JobCost · object | null

Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing.

credit_schedule_version
integer | null

Version of the credit schedule credits were priced under. Null until usage_final is true.

credits
integer | null

Final credits billed for this job, priced once under credit_schedule_version. Null until usage_final is true. Never changes afterwards, including after payload expiry or deletion. For a job that failed or was cancelled, the credits for results already delivered before it ended (a progressive classify or extract publishes before it finishes); 0 when it delivered nothing. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.

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

How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. 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

Typed failure envelope when status is failed. Null on any other status.

finished_at
string<date-time> | null

When the job reached a terminal status.

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

Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.

kind
string
default:intelligent_search
Allowed value: "intelligent_search"
name
string | null

Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.

payload_expires_at
string<date-time> | null

When the job's inputs, outputs and processing files are removed. Once the job finishes this is no later than 48 hours after it on a paid account and 7 days after on a free one, or sooner if the workspace's job_ttl_days says so. Null while a job with no job_ttl_days bound is still running, or when the account keeps no job content (zero retention).

progress
JobProgress · object | null

Live progress while the job is running. Null while queued and after the job finishes.

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
IntelligentSearchResult · object | null

Present only on succeeded, and only while retained.

result_state
enum<string>
default:available

Why result may be null. available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a cancelled job is charged only for results delivered before the cancel).

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

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

started_at
string<date-time> | null

When execution began. Null while still queued.

surface
enum<string> | null

Which console history this deep-search job belongs to. deep_search is the public route and the Deep Search page; qa and workbook are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo deep_search. Read from the stored payload, so it rides the same retention path as query.

Available options:
deep_search,
qa,
workbook
units
integer
default:0

Billable units once the job finishes; 0 while queued or running. Kept for compatibility: credits is the authoritative billed amount.

usage
JobUsage · object | null

What credits were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until usage_final is true, and on jobs finalized before usage breakdowns were introduced.

usage_final
boolean
default:false

True once credits is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.

usage_finalized_at
string<date-time> | null

When credits became final. Null until usage_final is true.

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.