Stream (SSE)
Server-Sent Events stream for real-time generation status
Endpoint
GET /v1/image/generations/{id}/streamOpens a text/event-stream connection that delivers real-time status updates for an in-progress generation.
Behaviour
- Each
data:frame is a full result object (same shape as the poll endpoint) - A
: heartbeatcomment is sent every 15 seconds to keep the connection alive - The stream closes on any terminal status:
completed,failed,cancelled,timeout - The final
completedframe carries the signedimagesarray
Example stream
data: {"id":"550e8400-...","status":"processing","model":"gpt-image-2","prompt":"...","images":[],"cost_credits":0}
: heartbeat
data: {"id":"550e8400-...","status":"completed","model":"gpt-image-2","prompt":"...","images":[{"url":"https://...signed...","width":1024,"height":1024}],"cost_credits":0.1,"completed_at":"2026-06-22T10:00:18Z"}Usage
# Open a stream after submitting a generation
ID=$(curl -s -X POST https://api.goodtake.ai/v1/image/generate \
-H "Authorization: Bearer $GOODTAKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model_identifier":"gpt-image-2","prompt":"a red fox in snow"}' \
| jq -r .id)
curl -N "https://api.goodtake.ai/v1/image/generations/$ID/stream" \
-H "Authorization: Bearer $GOODTAKE_API_KEY"JavaScript (EventSource)
const es = new EventSource(
`https://api.goodtake.ai/v1/image/generations/${id}/stream`,
{ headers: { Authorization: `Bearer ${process.env.GOODTAKE_API_KEY}` } }
);
es.onmessage = (event) => {
const result = JSON.parse(event.data);
if (result.status === "completed") {
console.log("Images:", result.images);
es.close();
} else if (result.status === "failed") {
console.error("Error:", result.error_message);
es.close();
}
};Python (sseclient)
import sseclient, requests, json, os
url = f"https://api.goodtake.ai/v1/image/generations/{generation_id}/stream"
resp = requests.get(url, headers={"Authorization": f"Bearer {os.environ['GOODTAKE_API_KEY']}"}, stream=True)
client = sseclient.SSEClient(resp)
for event in client.events():
if event.data:
result = json.loads(event.data)
if result["status"] in ("completed", "failed", "cancelled", "timeout"):
print(result)
breakTimeout recovery
Some MCP clients (e.g. Claude.ai) have a 30-second HTTP timeout. If the connection drops mid-poll, store the id from the original job and resume with:
curl -s "https://api.goodtake.ai/v1/image/generations/$ID" \
-H "Authorization: Bearer $GOODTAKE_API_KEY" | jq .