> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sublay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ask content

> Ask a natural language question and stream a generated answer from project content

export const SpaceReputationParams = ({variant = "context", field = "path"}) => {
  const isUser = variant === "user";
  return <>
      <ParamField {...{
    [field]: "spaceReputation",
    type: "object"
  }}>
        Opt-in. Adds a <code>spaceReputation</code> number to each returned user,
        scoped to a single space. Requires the <code>reputation</code> bundle.
        The <code>reputation</code> total is always present regardless;{" "}
        <code>spaceReputation</code> is purely additive and only appears when you
        pass this object. <strong>This object is the primary form</strong> — it
        replaces the deprecated flat props below. See the{" "}
        <a href="/v8/data-models/reputation">Reputation data model</a> for the
        full contract.

        <Expandable title="spaceReputation">
          {isUser ? <ParamField name="spaceId" type="string | &quot;none&quot;" required>
              Which bucket to read. A space <strong><code>&lt;uuid&gt;</code></strong> reads that
              space's bucket; <strong><code>"none"</code></strong> reads the
              project-general (space-less) bucket.{" "}
              <strong><code>"context"</code> is rejected (400)</strong> on this
              endpoint — there is no space context to derive. The empty string
              and the legacy <code>general</code> / <code>null</code> aliases are
              also rejected. Missing buckets read as <code>0</code>.
            </ParamField> : <ParamField name="spaceId" type="string | &quot;none&quot; | &quot;context&quot;" required>
              Which bucket to read. One of: a space <strong><code>&lt;uuid&gt;</code></strong>{" "}
              (that space's bucket), <strong><code>"none"</code></strong> (the
              project-general, space-less bucket), or{" "}
              <strong><code>"context"</code></strong> (the space derived from the
              request context — resolved per-row on lists, or the single space on
              member/team/conversation surfaces). The empty string and the legacy{" "}
              <code>general</code> / <code>null</code> aliases are rejected (400).
              Missing buckets read as <code>0</code>.
            </ParamField>}
          <ParamField name="includeDescendants" type="boolean">
            Only honored when <code>spaceId</code> is an explicit space <code>&lt;uuid&gt;</code>.
            When <code>true</code>, <code>spaceReputation</code> is the{" "}
            <strong>subtree sum</strong> — the named space plus all of its
            descendant spaces (the root space's own bucket included). Ignored for{" "}
            <code>"none"</code>; not allowed with <code>"context"</code>.
          </ParamField>
        </Expandable>
      </ParamField>

      {isUser ? <ParamField {...{
    [field]: "spaceReputationId",
    type: "string",
    deprecated: true
  }}>
          <strong>Deprecated</strong> — use the <code>spaceReputation</code>{" "}
          object instead. The flat form of <code>spaceReputation.spaceId</code>.
          Still accepted (the object wins if both are passed); removal is a later
          major version. Accepts a space <code>&lt;uuid&gt;</code> or <code>"none"</code> only —{" "}
          <code>"context"</code> is rejected (400) on this endpoint.
        </ParamField> : <ParamField {...{
    [field]: "spaceReputationId",
    type: "string",
    deprecated: true
  }}>
          <strong>Deprecated</strong> — use the <code>spaceReputation</code>{" "}
          object instead. The flat form of <code>spaceReputation.spaceId</code>.
          Still accepted (the object wins if both are passed); removal is a later
          major version. Accepts a space <code>&lt;uuid&gt;</code>, <code>"none"</code>, or{" "}
          <code>"context"</code>.
        </ParamField>}

      <ParamField {...{
    [field]: "spaceReputationDescendants",
    type: "boolean",
    deprecated: true
  }}>
        <strong>Deprecated</strong> — use{" "}
        <code>spaceReputation.includeDescendants</code> instead. The flat form,
        only honored alongside an explicit <code>spaceReputationId</code> <code>&lt;uuid&gt;</code>.
      </ParamField>
    </>;
};

## Overview

Streams an AI-generated answer to a natural language question, grounded in your project's content. Uses SSE (Server-Sent Events) to deliver tokens incrementally. Returns source citations once the stream completes.

For integration guidance, see [Ask Content](/v8/sdk/search/ask).

## Usage Example

```tsx theme={null}
import { useAskContent } from "@sublay/react-js";

function AskUI() {
  const { answer, sources, streaming, loading, error, ask, reset } = useAskContent();

  return (
    <div>
      <button onClick={() => ask({ query: "How do I reset my password?" })} disabled={loading || streaming}>
        Ask
      </button>
      {answer && <p>{answer}{streaming && " ▋"}</p>}
      {sources.map((s) => <div key={s.record.id}>[{s.sourceType}] {s.record.id}</div>)}
    </div>
  );
}
```

## Parameters

Call `ask` with:

<ParamField path="query" type="string" required>
  The natural language question.
</ParamField>

<ParamField path="sourceTypes" type="(&#x22;entity&#x22; | &#x22;comment&#x22; | &#x22;message&#x22;)[]">
  Limit the content types searched for context.
</ParamField>

<ParamField path="spaceId" type="string">
  Scope context lookup to a specific space.
</ParamField>

<ParamField path="includeChildSpaces" type="boolean" default="false">
  Only applies with `spaceId`. When `true`, the context lookup also covers every space nested under it — children, grandchildren, the whole subtree at any depth — so you can ask across a community and all of its channels at once. Ignored without `spaceId`.
</ParamField>

<ParamField path="conversationId" type="string">
  Scope context lookup to a specific conversation.
</ParamField>

<ParamField path="limit" type="number">
  Maximum number of source records to use as context.
</ParamField>

<SpaceReputationParams variant="context" field="path" />

## Returns

<ResponseField name="answer" type="string">
  The AI-generated answer. Grows token by token while `streaming` is `true`.
</ResponseField>

<ResponseField name="sources" type="ContentSearchResult[]">
  Source records used as context. Populated after streaming ends. When `spaceReputation` is requested, each record's embedded author carries an added `spaceReputation` number. See [Reputation](/v8/data-models/reputation).
</ResponseField>

<ResponseField name="streaming" type="boolean">
  `true` while the SSE stream is open and tokens are arriving.
</ResponseField>

<ResponseField name="loading" type="boolean">
  `true` from `ask()` call until the first token arrives.
</ResponseField>

<ResponseField name="error" type="string | null">
  Error message if the request failed.
</ResponseField>

<ResponseField name="ask" type="(props) => void">
  Starts a new question. Aborts any in-flight stream first.
</ResponseField>

<ResponseField name="reset" type="() => void">
  Aborts in-flight stream and clears all state.
</ResponseField>

<Note>
  In React Native, SSE streaming requires polyfills for `fetch`, `ReadableStream`, and `TextDecoder`. Install `react-native-fetch-api`, `web-streams-polyfill@^3`, `react-native-polyfill-globals`, and `text-encoding`, then call the targeted sub-polyfills once at app startup, before using this hook:

  ```ts theme={null}
  import { polyfill as polyfillEncoding } from "react-native-polyfill-globals/src/encoding";
  import { polyfill as polyfillReadableStream } from "react-native-polyfill-globals/src/readable-stream";
  import { polyfill as polyfillFetch } from "react-native-polyfill-globals/src/fetch";

  polyfillEncoding();
  polyfillReadableStream();
  polyfillFetch(); // last, so it wins over the built-in fetch
  ```

  Prefer these targeted polyfills over the all-in-one `polyfillGlobals()`: that helper also pulls in `react-native-get-random-values`, a native module that forces a development-client rebuild. The three above are pure JavaScript, so a Metro reload is enough. Pin `web-streams-polyfill` to v3 — v4 removed the `ponyfill/es6` subpath that `react-native-polyfill-globals` requires.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.