Skip to main content
Every chat completion you create through the API is saved as a chat, but that chat is headless by default. It does not appear in anyone’s chat history, not in the GC AI web app and not in the API’s own chat search. It exists only as a record you can reach by its chat_id. To put it into a person’s history, you materialize it.

Why API chats are hidden by default

When you call POST /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/search searches 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 the chat_id from 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 whose chat_id you 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

Call POST /chat/{id}/materialize with the chat_id from a completed POST /chat/completions response:
curl -X POST https://app.gc.ai/api/external/v1/chat/a1b2c3d4-e5f6-7890-abcd-ef1234567890/materialize \
  -H "Authorization: gcai_your_api_key_here"
Materializing a chat does three things:
  • Adds it to chat history, so it shows up in the GC AI web app and becomes findable through GET /chat/search.
  • 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.
A common pattern is to run completions fire-and-forget and then materialize only the chats a person actually needs to see, such as the ones a review flagged, rather than every chat the integration creates.

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:
Key typeCan materialize
Personal (u:gcai_…)Only chats it created.
Organization (gcai_…)Only chats created by other organization-scoped keys.
When an organization key materializes a chat that another organization key created, the chat becomes visible to all members of the organization, so anyone on the team can open it from the shared link. See API Keys for the difference between the two key types. 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.