Skip to content

Answer a natural-language question by generating and executing scoped Cypher

POST
/api/v1/admin/kg/ask
curl --request POST \
--url http://localhost:11044/api/v1/admin/kg/ask \
--header 'Content-Type: application/json' \
--header 'X-Embabel-Api-Key: <X-Embabel-Api-Key>' \
--data '{ "question": "example" }'

scope names a declared scope (a focus) to answer WITHIN: generation and view selection see only that scope’s realms, plus the spine. Not a captured query scope. Omitted, the question’s own words decide what is shown; the whole world never is.

username
string

Optional, and never needed: the call always acts as the signed-in principal. Naming the principal changes nothing; naming anyone else is refused with 403.

scope
string

The ask scope to use, as GET /ask/scopes lists them. Omitted means the whole graph.

The natural-language question, in question: Cypher is generated for it (within scope when one is given), run scoped to the acting user, and answered with the rows, the Cypher that produced them and what it cost

Media typeapplication/json

A natural-language question: the body of /ask, and of the studio’s /generate.

object
question
required

The question in plain language. Cypher is written for it and, on /ask, run scoped to the acting user.

string

Example generated

{
"question": "example"
}

The answer, with the cypher that produced it and what it cost

Media typeapplication/json

The outcome of a virtual-cypher query: rows, the cypher that produced them, and what it cost.

object
answerBoundary

The rows are supporting context only, not a match for the original question.

object
kind
required

What the rows are instead of an answer. Only SUPPORTING_CONTEXT_ONLY exists.

string
Allowed values: SUPPORTING_CONTEXT_ONLY
unresolvedQuestion

The question the rows do not answer: the asked question on /ask, view:<name> on a view run. Null on /execute, which has no question.

string
apiCallLog
required

The actual calls as producer(keys), in order — fan-out is visible here.

Array<string>
apiCalls
required

External fetches the executor made. 0 means everything was cached or local.

integer format: int32
capturedScope

The scope this result set froze into — present only on a capturing execute.

object
capturedAt
required

When the membership froze, ISO-8601.

string
expiresAt

When the scope lapses, ISO-8601 — null means PINNED (kept until deleted).

string
members
required

How many members the capture froze. Membership is frozen; values stay live.

integer format: int64
name
required

The name the scope was captured under, unique per user; a later query binds it as (x:$name).

string
outputLabel
required

The node label later references bind with.

string
statement
required

The statement that produced the capture — the scope’s provenance.

string
columnSources

Each column -> the expression that computed it, traced back through WITH and UNWIND, e.g. {“total”: “sum(b.amount)”}; an unwound column reads “UNWIND ”. Where the origin cannot be traced with certainty, the column’s own RETURN expression is given unchanged. A column name is the query’s label for a value, not evidence of what it is.

object
key
additional properties
string
cypher
required

The cypher that actually ran, after scope rewriting.

string
dataContract

The pinned ODCS identity and invocation verdict, for a contracted named view only.

object
apiVersion
required

The ODCS apiVersion the contract declares, such as v3.1.0; v3.1.0 when the view was refused before it ran

string
available
required

False when the view could not run under its contract: the pinned contract or its object is missing, or its status forbids it. Then no rows are returned, whatever the mode

boolean
blocksRows
required
boolean
checkedAt
required

ISO-8601 instant the result was checked

string
checks
required

Each check made, in the order it was made

Array<object>

One check made when a view’s result was evaluated against its data contract

object
kind
required

schema, quality, freshness, status, binding or execution

string
message

What it found, in words, naming rows and fields but never their values; null when there is nothing to say

string
ruleId
required

The contract’s own id for a quality or freshness rule, or an embabel: id for a check the runtime makes itself, such as embabel:schema, embabel:binding or embabel:status

string
scope

invocation for the schema check, which covers this one result; null for every other check

string
verdict
required

PASS, WARN, FAIL, or UNKNOWN when the check could not be made

string
Allowed values: PASS WARN FAIL UNKNOWN
id
required

Id of the governing contract, as the view’s binding pins it

string
mode
required

observe or enforce, from the view’s binding

string
Allowed values: observe enforce
object
required

The contract object the rows were checked against, as the binding names it

string
status
required

The contract’s ODCS status, such as active, deprecated or retired; unavailable when the pinned contract is not in the world

string
verdict
required

The worst of the checks: FAIL if any failed, else UNKNOWN if any could not be made, else WARN if any warned, else PASS

string
Allowed values: PASS WARN FAIL UNKNOWN
version
required

The pinned contract version

string
durationMs
required

Total: bridge-resolve plus materialize plus read.

integer format: int64
error

Why the query failed, or null when it did not.

string
exposure

What the models behind an /ask answer were shown: resolved schema groups and prompt sizes.

object
generationPromptChars

Characters in the Cypher-generation prompt. Absent when no query was generated.

integer format: int32
groups
required

The schema groups rendered in full for generation, and whose views view selection was offered.

Array<string>
indexed
required

Groups named to the generator by one index line only — no labels, properties or examples.

Array<string>
matched

Each named group -> the words that named it, tier first: name:, label:, weak: or keyword:.

object
key
additional properties
Array<string>
resolvedBy
required

How the groups were chosen: WHOLE (nothing to narrow), SCOPE, QUESTION, UNRESOLVED or SELECTOR.

string
spineOnly
required

True when the always-on core was cut to the spine anchors (the user, Person, Organization).

boolean
viewSelectPromptChars

Characters in the view-selection prompt. Absent when no view selection ran.

integer format: int32
viewsInWorld

Saved views in the world.

integer format: int32
viewsOffered

Saved views offered to view selection, of viewsInWorld.

integer format: int32
fetchedRecords

Source records fetched before query-side filtering, cache-served included. Absent when none.

integer format: int32
hint

What to try instead. Accompanies an empty result only.

string
llmCallLog
required

The actual LLM calls (kg-ask and agg-*), in order.

Array<string>
llmCalls
required

LLM calls: the generation plus any aggregate reductions. Reasoning only — a semantic anchor’s embedding is on semanticCalls.

integer format: int32
materializedNodes

Graph nodes materialized from fetched records in this execution. Absent when none.

integer format: int32
question

The question asked, echoed back. Present only for /ask.

string
reason

Typed outcome when this was not a clean answer — UNBOUNDED, NOT_IN_GRAPH, MISSING_ATTRIBUTE, FETCHED_NOT_MATCHED, PARTIAL_NOT_MATCHED, UNPUSHED_FILTER, DISCONNECTED or INTERNAL_ERROR. May accompany rows when a source failed, a read was refused, or a filter was not applied; absent on a clean answer, including a genuine zero.

string
rowCount
required

How many rows rows holds.

integer format: int32
rows
required

One map per row, keyed by RETURN column. Empty and meaningless while run is present — the run has not finished, which is not the same as no data. From a synchronous /execute, a node is its properties plus __type, __labels and __elementId; a relationship its properties plus __type (the relationship type), __elementId, __startElementId and __endElementId (the __elementIds of the nodes it joins); a path its nodes and relationships in traversal order. Elsewhere a node carries __type and __labels and a relationship its properties alone.

Array<object>
object
key
additional properties
run

Present only when /execute with waitSeconds gave up waiting: the run is still going (or parked), and this is how to follow it. Absent on every answer that finished in the call.

object
answer

Where to send the owner’s pick for a parked run. Absent while running.

string
choices

The {kind, question, options, context} payload when parked.

object
key
additional properties
kill

Where to stop the run. Absent when parked — nothing is executing to kill.

string
poll
required

Where to poll for state and, once settled, the result.

string
runId
required

The run’s id, for /runs/{runId}, /kill/{runId} and /runs/{runId}/answer.

string
state
required

RUNNING (materializing now) or WAITING_INPUT (parked on choices).

string
semanticCallLog
required

The actual searches as producer: mode search on index (k=…), in order.

Array<string>
semanticCalls
required

Relevance searches behind a semantic anchor: one embedding plus one similarity scan per anchor. The third call axis — a search of an index is neither a producer fetch nor a reduction, and a semantic query spends here and nowhere else.

integer format: int32
warnings
required

Caveats on this result that do not make it an error — a producer that failed, rows that are partial or supporting context, an aggregate over mixed units. Absent when there are none.

Array<string>

Example

{
"answerBoundary": {
"kind": "SUPPORTING_CONTEXT_ONLY"
},
"dataContract": {
"checks": [
{
"verdict": "PASS"
}
],
"mode": "observe",
"verdict": "PASS"
}
}

No authenticated principal

Media typeapplication/json

A refusal carrying only a human-readable reason.

object
error
required

What went wrong, in the terms the caller can act on.

string

Example generated

{
"error": "example"
}

username names someone other than the signed-in principal

Media typeapplication/json

A refusal carrying only a human-readable reason.

object
error
required

What went wrong, in the terms the caller can act on.

string

Example generated

{
"error": "example"
}

Unknown scope; the declared names travel with the refusal

Media typeapplication/json

The named scope does not exist in the acting user’s world; the ones that do travel with the refusal.

object
available
required

The scope names this world declares (its focuses).

Array<string>
error
required

Names the scope that was not found.

string

Example generated

{
"available": [
"example"
],
"error": "example"
}