Skip to main content
This tutorial builds a question-answering helper on Grounded Responses, POST /ai/v1/grounded/responses. Gloo finds relevant passages in your uploaded content and adds them to the model’s context before it answers: Retrieval-Augmented Generation (RAG), in the same request and response shape as the Responses API. You’ll scope retrieval to your publisher, check whether an answer was actually grounded, handle questions your content doesn’t cover, and show readers the sources behind an answer. Want the concepts first? Read the Grounded Responses guide. For every parameter and response field, see the Grounded Responses API reference.
Grounding never fails the request. When nothing relevant is found, the model still answers, from its own knowledge, and the response reports sources_returned: false. That flag is the one signal that separates an answer from your content from one that isn’t. This tutorial checks it on every call.

Prerequisites

You need:

What You’ll Build

A helper, answer(question), that returns one of four results your interface can show safely: You’ll build it in five steps, add streaming in Step 6, then put it together in Complete Code.

Step 1: Your First Grounded Request

A grounded request is a Responses request plus grounding parameters. Set rag_publisher to your publisher name.

Understanding the Response

The response is standard Responses output, a typed output[] array plus usage, with one addition: a top-level sources_returned boolean.
Notice the input tokens: the retrieved passages are part of the prompt, so grounded requests carry larger prompts than ungrounded ones. Grounded Responses is billed per token at the model’s published rate, with nothing added for retrieval. See Pricing.

Step 2: Scope Retrieval to Your Content

Three parameters decide which content reaches the model: For an assistant that should speak only from your material, always set rag_publisher.
Start with the defaults and tune against real questions from your users. If good questions come back with sources_returned: false, a threshold that’s too high is a likely cause; if answers drift off topic, raise it or lower sources_limit.

Step 3: Tell the Model How to Use the Sources

The grounded endpoint adds the passages; your instructions decide how the model treats them. Encode a few rules from The Prompt Contract:
Add "instructions": INSTRUCTIONS to every request. The quotation rule matters for Step 5: it means anything in quotation marks claims to be verbatim, so your code can check it.
Instructions shift behavior a great deal, but they’re best-effort: they reduce how often a check has to catch something, not replace it.

Step 4: Handle Questions Your Content Doesn’t Cover

When retrieval finds nothing, because the publisher has no matching content or no passage clears certainty_threshold, the model is told no publisher sources were retrieved and still answers. The answer can be fluent and confident, and it isn’t from your content. Check sources_returned before anything else, and give the user an honest message instead of the ungrounded answer:
Whether you decline or show a labeled answer is a product decision; what matters is that an ungrounded answer never looks like a grounded one. Count how often it happens with real traffic: a narrow library fielding broad questions will see it often, and that’s a signal about your content, not an error.
sources_returned: true tells you sources reached the model, not that the answer reflects them. A model can still produce a quotation or a title no source contains, a hallucination. Step 5 adds that check.

Step 5: Show Sources and Verify Quotations

Citations build trust only if they’re real. Grounded Responses returns sources_returned but not the passages themselves, so fetch them from the Search API with the same question, against the same publisher. Use the results two ways:
  • Show them as “Sources from our library”: each result has properties.item_title and the passage text in properties.snippet.
  • Verify against them: every quotation in the answer should appear in one of the passages.
Citations and Verification in AI 103 explains the ideas behind this step, including what to show when no sources come back.
Search uses your publisher’s tenant name, which has spaces removed (Example Publisher becomes ExamplePublisher). The surest way to get it is GET /ai/v1/data/tenant/names. The collection is always GlooProd.
Each quotation is checked against one passage at a time, so a “quote” stitched together from two different documents doesn’t pass. The Search results may not be exactly the passages the grounded call used, so treat a quotation that fails as unconfirmed, not proven false, and handle it the safe way: widen retrieval once and regenerate, then decline or drop the quotation if it still doesn’t verify. Verification Checks covers the same check for titles of works, and when to paraphrase, withhold or decline. When rendering sources, show the title and a short excerpt, and link to properties.item_url when it isn’t empty.
Need the exact passages the model saw? Grounded Completions returns citation metadata (include_citations) on the Chat Completions shape.

Step 6: Stream a Grounded Answer

Set "stream": true to receive the same Server-Sent Events as the Responses API. The grounding outcome is known before the first token, so it arrives as the X-Sources-Returned response header instead of a body field. Read it before you render anything:
Compare the header without regard to case. This example buffers the text instead of streaming each delta to the screen: a quotation shown live is on screen before it can be checked. For quote-heavy or high-stakes answers, buffer and verify; see Verify Before You Stream. If a stream breaks partway through, see Handling Streaming Failures.

Complete Code

The answer() helper from What You’ll Build: check grounding first, verify quotations against passages from Search, widen both once, and decline rather than show a quotation that couldn’t be confirmed. An answer with no quotations, with a quotation too short to check (under 12 characters, such as a single quoted word), or with an unclosed quotation comes back as unverified: show it with its sources, but don’t label it as checked. An answer with quotations but no Search passages to check them against comes back as unsupported. It uses output_text, INSTRUCTIONS, grounded, search_passages, quoted_spans, balanced_quotes and unverified_quotes from Steps 1 to 5; put them in one file with this code.
Putting It Together shows the same pattern with title checks added, and Evaluate Before You Ship shows how to measure it on your own questions.

Troubleshooting

sources_returned is always false : Check that rag_publisher matches your publisher name exactly, as shown in Manage Publishers, and that your uploads have finished processing. Then try a question your documents clearly answer. If you set certainty_threshold, remove it to fall back to the platform default. Answers draw on content that isn’t yours : rag_publisher is missing, so the request grounded in the default GlooGrounded dataset. Set it on every request. Follow-up questions like “tell me more” come back ungrounded : Retrieval keys on the latest user message, and a short follow-up has little to search on. Carry the original question’s terms into the follow-up, or reuse the sources from the earlier turn. See Multi-Turn Conversations. Search returns 400 or 403 : tenant must be the normalized tenant name with spaces removed, which you can get from GET /ai/v1/data/tenant/names, and collection must be GlooProd. You can only search your own publisher’s tenant. A correct quotation is flagged as unconfirmed : The Search results may not include the passage the model quoted. Raise the Search limit, or move to Grounded Completions to check against the citation snippets the model was given. Every streamed answer is treated as ungrounded : Compare X-Sources-Returned without regard to case (true / True), and read it from the response headers, not the event stream. Prompts are large and costly : Retrieved passages count as input tokens. Lower sources_limit; it’s your main lever over the cost of each grounded request.

Next Steps

Grounded Responses guide

Parameters, streaming, reasoning and how it compares to Grounded Completions

Grounded Responses API reference

Every request parameter and response field

Building Trustworthy Grounded Applications

Verification, prompt contracts, multi-turn handling and evaluation

Handling Streaming Failures

Retry ceilings, continuation and partial-output UX

Upload Files tutorial

Get more of your content into your publisher

Build with Direct Responses

The same request shape, without retrieval