chat_id. To put it into a person’s history, you materialize it.
Why API chats are hidden by default
When you callPOST /chat/completions, GC AI creates a chat to hold the exchange and returns its chat_id in the result envelope. Most API traffic is automated, though: batch contract reviews, a triage bot, a nightly job. If every one of those calls dropped a chat into someone’s sidebar, real users’ histories would fill up with machine-generated chats they never started.
So API chats start headless. The chat is saved and reachable by chat_id, but it stays out of every human-facing listing until a person explicitly claims it by materializing it.
What “hidden” means
An API chat that has not been materialized:- Does not appear in the web app. It never shows up in the chat sidebar or history.
- Does not appear in API chat search.
GET /chat/searchsearches the caller’s chat history, and the chat is not in it, so search will not return it. - Addressable only by
chat_id. Visibility is about listings, not access. The chat is still reachable directly by thechat_idfrom the completion response, but you have to hold that id yourself. Capture it (and the answer text) at the time of the call; an unmaterialized chat whosechat_idyou never kept is effectively lost.
Materialization is not a web-app-only flag. The same gate controls both the web sidebar and API chat search, so an unmaterialized chat is hidden in both. Materializing it makes the chat show up in both at once.
Materializing a chat
There are two ways to do it. If you already know at request time that a person is meant to open the chat, setmaterialize: true on the completion and skip the second call:
chat_url you can hand straight to a person. If chat_url is missing, materialization did not happen and the chat is still headless, so fall back to the endpoint below.
Otherwise call POST /chat/{id}/materialize with the chat_id from a completed POST /chat/completions response:
- Adds it to chat history, so it shows up in the GC AI web app and becomes findable through
GET /chat/search. - Sets who can use it. An organization key shares the chat with the whole organization. See Who can materialize what.
- Returns a shareable deep link (
chat_url) that opens the chat in the web app. - Is idempotent. Calling it again on an already-materialized chat returns the same link and changes nothing else.
materialize: true flag when every chat in a flow is meant for a person, for example one chat per matter that an attorney opens from your own system.
Filing a chat into a project with
project_id is not the same as materializing it. project_id grounds the completion in the project’s files and records the chat under that project, but the chat stays out of GET /projects/{id}/chats and out of the web app until it is materialized. If you file chats into projects for people to browse, materialize them too.Who can materialize what
Materialization claims a chat into a person’s or an organization’s history, so it is scoped to the key that created the chat:
When an organization key materializes a chat that another organization key created, the chat is shared with the whole organization. An organization key has no user identity, so the chat has no owner, and every member gets full access: they can open it from the shared link and keep chatting in it themselves.
A chat a personal key created keeps that user as its owner. Materializing it puts it in that user’s history. Teammates reach it only through the normal sharing rules, the same as a chat the user started in the web app. Use an organization key when you want the whole team to be able to pick up the conversation.
See API Keys for the difference between the two key types.
Materialization and chat search
GET /chat/search runs hybrid search over the caller’s chat history. Two things follow from how visibility works:
- Search needs a personal key. Chat history is per-user, so chat search rejects organization keys with
400. Use a personal key. - Search only finds materialized chats. An API chat is not in anyone’s history until it is materialized, so it cannot show up in search before then. If you want an integration’s chats to be searchable later, materialize the ones worth keeping.
Related
- Create a Chat Completion: creates the chat and returns its
chat_id. - Multi-turn Conversations: continue a chat across turns by passing its
chat_id. - Materialize an API Chat: surface a chat by
chat_idand get a deep link. - Search Chats: hybrid search over a user’s chat history.
- API Keys: personal vs. organization keys and what each can reach.