Streaming delivers incremental content before generation finishes; it does not make the model itself faster. It can reduce perceived waiting time, but requires careful handling of SSE parsing, proxy buffering, connection interruption and usage statistics and related issues.
Protocol and billing checks for Link streaming
Parse Link GPT, Claude and Gemini streams according to the endpoint in use. Chat Completions chunks cannot simply be passed to a Messages or Responses parser. Save raw event types and completion events before attributing a failure to the network or parser.
A disconnected stream does not imply zero usage. Check the Link usage log for failed and retried requests, and whether wallet fallback applies after the daily allowance runs out. Avoid unlimited retries of long outputs.
Review Link funding and monthly-plan rules
Is the SSE stream complete? Check the endpoint, not the model brand
HTTP 200, the first text fragment and connection closure are distinct signals; none alone proves task completion. Identify the final request path before using this table. A GPT, Claude or Gemini name does not identify the protocol. Gemini via Chat Completions follows that protocol; native endpoints are outside this table's scope.
| Request endpoint | Terminal evidence to record | What still needs checking |
|---|---|---|
| /v1/chat/completions | data: [DONE] and each choice's finish_reason | stop ends generation; length reaches an output limit; tool_calls requires further tool handling, not a completed business task |
| /v1/responses | response.completed, response.failed or response.incomplete | response.output_text.done ends one text part; failed and incomplete must not be recorded as complete success |
| /v1/messages | message_stop and the stop_reason in message_delta | content_block_stop ends one block; tool_use needs a tool result, and in-stream errors require separate handling |
These criteria were checked against the official protocol references below on November 4, 2026. They are not a claim that every Link model has passed testing. A completed response does not by itself prove correct tool execution, file contents or an entire agent task.
Two endings that are easy to misclassify
These simplified teaching excerpts are not live Link request logs. The first reaches an output limit despite receiving [DONE]. The second reports an incomplete response. Receiving a text delta alone does not establish success.
data: {"choices":[{"index":0,"delta":{},"finish_reason":"length"}]}
data: [DONE]
event: response.incomplete
data: {"type":"response.incomplete","response":{"status":"incomplete","incomplete_details":{"reason":"max_output_tokens"}}}
If the connection closes before any terminal event, record an interruption or unknown outcome, then inspect client cancellation, timeouts and server logs. Do not fabricate a stop or [DONE] marker to complete a broken stream, or automatically replay a tool that may already have run.
Check before you start
Complete three confirmations first:
- Use non-streaming requests to verify that the API Key, model ID, and underlying API are working properly.
- Confirm that the target model and API support streaming output.
- Verify that clients, reverse proxies, and CDNs do not cache or merge event streams.
If non-streaming requests also fail, first check for 401, model not found or API paths. Do not start debugging directly from SSE.
Configuration steps
1. Use curl to view the original event stream
curl -N --include --connect-timeout 10 --max-time 120 https://www.aifast.link/v1/chat/completions \
-H "Authorization: Bearer ${AIFAST_API_KEY:?Set AIFAST_API_KEY locally before running}" \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_MODEL_ID",
"stream": true,
"messages": [
{"role": "user", "content": "Explain SSE in three points."}
]
}'
-N Will turn off curl's output buffering. Under normal circumstances, the terminal will have multiple consecutive data: chunks of data instead of waiting for the entire content to be generated and displayed at once.
This command sends a real request to Link and may incur charges. The 120-second limit is a demonstration deadline, not a service SLA. Curl aborts when it is reached; that alone does not establish an upstream failure. Remove keys, cookies, user input and sensitive response content before sharing logs.
2. Python SDK streaming reading
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AIFAST_API_KEY"],
base_url="https://www.aifast.link/v1",
)
stream = client.chat.completions.create(
model="YOUR_MODEL_ID",
stream=True,
messages=[
{"role": "user", "content": "List three API pre-launch checks."}
],
)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
Don't assume that every chunk of data has text. Tool calls, role information, end reasons or compatibility layer events may appear in different fields. The formal code needs to first determine whether the fields exist.
3. Node.js SDK streaming reading
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AIFAST_API_KEY,
baseURL: "https://www.aifast.link/v1",
});
const stream = await client.chat.completions.create({
model: "YOUR_MODEL_ID",
stream: true,
messages: [
{ role: "user", content: "Explain two common streaming failures." },
],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
4. Record completeness rather than just display text
The production environment records at least:
| Field | Purpose |
|---|---|
| Request start time | Calculate total time |
| First response byte timestamp | Measure TTFB; the first bytes may only contain headers or a heartbeat |
| First non-empty text delta timestamp | Measure client-observed time to first text; exclude role-only and empty deltas |
| Last event or stop reason | Check whether the response ended completely |
| Request ID | Locate requests when contacting support |
| Accumulated content length | Identify interruptions |
| Usage and final charges | Record client statistics and billing separately; missing statistics do not mean zero usage |
How do I get streaming usage in Chat Completions?
Where the endpoint supports it, add stream_options: {"include_usage": true} to a stream: true request. The official protocol sends a statistics chunk before [DONE], with choices: []. Read usage before skipping empty choices. The minimal SDK examples above display text only; they do not collect billing data.
Do not copy this option into Responses or Messages requests. If a compatible endpoint rejects it, verify that endpoint's support rather than ignoring the error or inventing usage. When final statistics are missing after an interruption, check Link usage logs.
FAQ
The server is streaming, but the web page is still displayed at once
First, use curl -N to check the origin server. If chunks appear in the terminal, inspect your backend framework, reverse proxy and frontend reader. Check response buffering and whether the client reads incrementally from response.body.
The output suddenly stops halfway
Record the last event, stop reason and request ID. Possible causes include read timeouts, network interruptions, proxy idle timeouts, browser cancellation and upstream generation failures. Do not store partial content as a successful result.
Why there is no usage for streaming requests
Some protocols only return full usage in the last data block. If the connection is interrupted early, the client may not get the final statistics. The accounting reconciliation is based on the console and server records, and cannot only rely on the data blocks received by the front end.
Next step
Test short text, long text, Chinese, multi-byte characters, active cancellation, network disconnection and proxy timeout respectively. Before going online, the maximum task duration, disconnection status, and user-visible retry entry should also be set for streaming requests.
For an existing disconnection, use the 502 and stream-disconnection decision table to choose the next check. Once the endpoint passes, use the API Cost Calculator to budget for actual usage and billed retries. No key is required, and demonstration values are not Link prices.