Documentation Index Fetch the complete documentation index at: https://docs.chatgrid.ai/llms.txt
Use this file to discover all available pages before exploring further.
What you’ll build
Instead of waiting for the full AI response, stream it token-by-token for a ChatGPT-like experience.
AI: The
AI: The capital
AI: The capital of
AI: The capital of France
AI: The capital of France is
AI: The capital of France is Paris.
[DONE]
How streaming works
When you set stream: true on the messages endpoint, the API returns a Server-Sent Events (SSE) stream instead of a JSON response.
The stream emits these events:
Event Description message.deltaA chunk of the AI’s response (partial text) message.completeThe full message with usage stats errorSomething went wrong
TypeScript example
const API_KEY = "YOUR_API_KEY" ;
const BOARD_ID = "your-board-id" ;
const CHAT_ID = "your-chat-id" ;
const res = await fetch (
`https://api.chatgrid.ai/v1/boards/ ${ BOARD_ID } /chats/ ${ CHAT_ID } /messages` ,
{
method: "POST" ,
headers: {
Authorization: `Bearer ${ API_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
content: "Explain quantum computing in simple terms" ,
stream: true ,
}),
}
);
const reader = res . body ! . getReader ();
const decoder = new TextDecoder ();
let buffer = "" ;
while ( true ) {
const { done , value } = await reader . read ();
if ( done ) break ;
buffer += decoder . decode ( value , { stream: true });
const lines = buffer . split ( " \n " );
buffer = lines . pop () ! ; // keep incomplete line in buffer
for ( const line of lines ) {
if ( line . startsWith ( "data: " )) {
const data = JSON . parse ( line . slice ( 6 ));
if ( data . event === "message.delta" ) {
process . stdout . write ( data . content );
}
if ( data . event === "message.complete" ) {
console . log ( " \n\n --- Complete ---" );
console . log ( "Tokens used:" , data . usage ?. total_tokens );
}
}
}
}
Run it:
Python example
import requests
import json
API_KEY = "YOUR_API_KEY"
BOARD_ID = "your-board-id"
CHAT_ID = "your-chat-id"
res = requests.post(
f "https://api.chatgrid.ai/v1/boards/ { BOARD_ID } /chats/ { CHAT_ID } /messages" ,
headers = {
"Authorization" : f "Bearer { API_KEY } " ,
"Content-Type" : "application/json" ,
},
json = { "content" : "Explain quantum computing simply" , "stream" : True },
stream = True ,
)
for line in res.iter_lines():
if line:
decoded = line.decode( "utf-8" )
if decoded.startswith( "data: " ):
data = json.loads(decoded[ 6 :])
if data.get( "event" ) == "message.delta" :
print (data[ "content" ], end = "" , flush = True )
if data.get( "event" ) == "message.complete" :
print ( f " \n\n Tokens: { data.get( 'usage' , {}).get( 'total_tokens' ) } " )
React hook example
Build a streaming chat component in React:
import { useState , useCallback } from "react" ;
export function useStreamingChat ( apiKey : string ) {
const [ content , setContent ] = useState ( "" );
const [ isStreaming , setIsStreaming ] = useState ( false );
const sendMessage = useCallback (
async ( boardId : string , chatId : string , message : string ) => {
setContent ( "" );
setIsStreaming ( true );
const res = await fetch (
`https://api.chatgrid.ai/v1/boards/ ${ boardId } /chats/ ${ chatId } /messages` ,
{
method: "POST" ,
headers: {
Authorization: `Bearer ${ apiKey } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ content: message , stream: true }),
}
);
const reader = res . body ! . getReader ();
const decoder = new TextDecoder ();
let buffer = "" ;
while ( true ) {
const { done , value } = await reader . read ();
if ( done ) break ;
buffer += decoder . decode ( value , { stream: true });
const lines = buffer . split ( " \n " );
buffer = lines . pop () ! ;
for ( const line of lines ) {
if ( line . startsWith ( "data: " )) {
const data = JSON . parse ( line . slice ( 6 ));
if ( data . event === "message.delta" ) {
setContent (( prev ) => prev + data . content );
}
}
}
}
setIsStreaming ( false );
},
[ apiKey ]
);
return { content , isStreaming , sendMessage };
}
Usage in a component:
function Chat () {
const { content , isStreaming , sendMessage } = useStreamingChat ( "YOUR_KEY" );
return (
< div >
< p > { content }{ isStreaming && "..." } </ p >
< button onClick = { () => sendMessage ( boardId , chatId , "Hello!" ) } >
Send
</ button >
</ div >
);
}
Tips
When should I use streaming?
Use streaming for user-facing chat interfaces where perceived speed matters. Use non-streaming (stream: false) for automated pipelines where you need the complete response before proceeding.
How do I handle errors in a stream?
Listen for the error event in the SSE stream. If the connection drops unexpectedly, retry the request. The message won’t be duplicated because the failed message isn’t saved.
First token typically arrives in 300-800ms depending on the model. Total streaming time depends on response length.