Stream with curl
Streaming is the default on POST /v1/chat/completions: leave out stream (or set it to true) and the reply arrives as server-sent events.
See the raw events
curl -N https://app.syntic.ai/v1/chat/completions \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Amara Quick",
"messages": [{"role": "user", "content": "List four uses for a paperclip, one per line."}]
}'-N turns off curl’s output buffer, so each event prints the moment it arrives. You will see lines like:
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hold"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":38,"completion_tokens":31,"total_tokens":69}}
data: [DONE]Print only the text
jq with --unbuffered reads each event as it comes and prints the text pieces without line breaks between them:
curl -sN https://app.syntic.ai/v1/chat/completions \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "Amara Quick", "messages": [{"role": "user", "content": "Write a haiku about tea."}]}' \
| sed -u -n 's/^data: //p' \
| grep --line-buffered -v '^\[DONE\]$' \
| jq --unbuffered -j '.choices[0].delta.content // empty, (if .error then "\n[stream error: \(.detail)]\n" else empty end)'
echoHow the pipeline works:
sed -u -n 's/^data: //p'keeps only event lines and strips thedata:prefix.grep -v '^\[DONE\]$'drops the end marker, which is not JSON.jq -jprints each text piece with no newline, and prints a notice if astream_errorevent arrives.
Show the headers too
Response headers come before the first event. -D - prints them:
curl -sN -D - https://app.syntic.ai/v1/chat/completions \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "Amara Quick", "messages": [{"role": "user", "content": "Hi"}]}' \
| grep -i -E '^(HTTP|x-syntic|content-type)'Look for content-type: text/event-stream, x-syntic-request-id and x-syntic-billing-source.
When it fails
Errors found before streaming starts (bad key, rate limit, exhausted quota) return a normal JSON body and a non-200 status, not events. Add -f to make curl exit non-zero on those, or -w '%{http_code}' to print the status.
Related
Was this page helpful?