API
Streaming
Stream tokens in real time via Server-Sent Events.
Add "stream": true to any chat request. Tokens are delivered as Server-Sent Events, ending with data: [DONE].
Examples
curl -X POST https://silkdock.ai/v1/chat/completions \-H "Authorization: Bearer $SILKDOCK_API_KEY" \-H "Content-Type: application/json" \--no-buffer \-d '{ "model": "gpt-4.1-mini", "stream": true, "messages": [{"role": "user", "content": "Write a short poem"}]}'curl -X POST https://silkdock.ai/v1/chat/completions ^-H "Authorization: Bearer %SILKDOCK_API_KEY%" ^-H "Content-Type: application/json" ^--no-buffer ^-d "{"model":"gpt-4.1-mini","stream":true,"messages":[{"role":"user","content":"Write a short poem"}]}"http --stream POST https://silkdock.ai/v1/chat/completions \Authorization:"Bearer $SILKDOCK_API_KEY" \model=gpt-4.1-mini \stream:=true \messages:='[{"role":"user","content":"Write a short poem"}]'wget --no-buffer -q -O - \--method=POST \--header="Authorization: Bearer $SILKDOCK_API_KEY" \--header="Content-Type: application/json" \--body-data='{"model":"gpt-4.1-mini","stream":true,"messages":[{"role":"user","content":"Write a short poem"}]}' \https://silkdock.ai/v1/chat/completions$headers = @{ "Authorization" = "Bearer $env:SILKDOCK_API_KEY" "Content-Type" = "application/json"}$body = '{"model":"gpt-4.1-mini","stream":true,"messages":[{"role":"user","content":"Write a short poem"}]}'$response = Invoke-RestMethod -Uri "https://silkdock.ai/v1/chat/completions" ` -Method POST ` -Headers $headers ` -Body $body ` -ResponseHeadersVariable respHeaders# For true streaming, use HttpClient directly$client = [System.Net.Http.HttpClient]::new()$client.DefaultRequestHeaders.Add("Authorization", "Bearer $env:SILKDOCK_API_KEY")$request = [System.Net.Http.HttpRequestMessage]::new("POST", "https://silkdock.ai/v1/chat/completions")$request.Content = [System.Net.Http.StringContent]::new($body, [System.Text.Encoding]::UTF8, "application/json")$responseMsg = $client.SendAsync($request, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).Result$stream = $responseMsg.Content.ReadAsStreamAsync().Result$reader = [System.IO.StreamReader]::new($stream)while (-not $reader.EndOfStream) { $line = $reader.ReadLine() if ($line.StartsWith("data: ") -and $line -ne "data: [DONE]") { Write-Host $line.Substring(6) }}const { OpenAI } = require("openai");const client = new OpenAI({apiKey: process.env.SILKDOCK_API_KEY,baseURL: "https://silkdock.ai/v1",});const stream = await client.chat.completions.create({model: "gpt-4.1-mini",messages: [{ role: "user", content: "Write a short poem" }],stream: true,});for await (const chunk of stream) {const content = chunk.choices[0]?.delta?.content || "";process.stdout.write(content);}const res = await fetch("https://silkdock.ai/v1/chat/completions", {method: "POST",headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }],}),});const reader = res.body.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) break;for (const line of decoder.decode(value).split("\n")) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const chunk = JSON.parse(line.slice(6)); process.stdout.write(chunk.choices[0]?.delta?.content ?? "");}}const axios = require("axios");const response = await axios.post("https://silkdock.ai/v1/chat/completions",{ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }],},{ headers: { Authorization: `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json", }, responseType: "stream",});response.data.on("data", (chunk) => {const lines = chunk.toString().split("\n");for (const line of lines) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const data = JSON.parse(line.slice(6)); process.stdout.write(data.choices[0]?.delta?.content ?? "");}});// jQuery does not natively support SSE streaming.// Use XHR directly or the EventSource API for true streaming.// The example below collects the full response on completion.$.ajax({url: "https://silkdock.ai/v1/chat/completions",type: "POST",contentType: "application/json",headers: { Authorization: `Bearer ${SILKDOCK_API_KEY}`,},data: JSON.stringify({ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }],}),xhrFields: { onprogress: function () { const raw = this.responseText; const lines = raw.split("\n"); for (const line of lines) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const chunk = JSON.parse(line.slice(6)); console.log(chunk.choices[0]?.delta?.content ?? ""); } },},});const xhr = new XMLHttpRequest();xhr.open("POST", "https://silkdock.ai/v1/chat/completions", true);xhr.setRequestHeader("Authorization", `Bearer ${SILKDOCK_API_KEY}`);xhr.setRequestHeader("Content-Type", "application/json");let cursor = 0;xhr.onprogress = function () {const newText = xhr.responseText.slice(cursor);cursor = xhr.responseText.length;for (const line of newText.split("\n")) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const chunk = JSON.parse(line.slice(6)); console.log(chunk.choices[0]?.delta?.content ?? "");}};xhr.send(JSON.stringify({model: "gpt-4.1-mini",action: "chat",stream: true,messages: [{ role: "user", content: "Write a short poem" }],}));// 'request' package – receives streamed chunks as they arriveconst request = require("request");request.post({url: "https://silkdock.ai/v1/chat/completions",headers: { Authorization: `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }],}),}).on("data", (chunk) => { const lines = chunk.toString().split("\n"); for (const line of lines) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const data = JSON.parse(line.slice(6)); process.stdout.write(data.choices[0]?.delta?.content ?? ""); }}).on("end", () => console.log("\n[done]"));const unirest = require("unirest");// unirest streams through the underlying 'request' moduleunirest.post("https://silkdock.ai/v1/chat/completions").header("Authorization", `Bearer ${process.env.SILKDOCK_API_KEY}`).header("Content-Type", "application/json").send( JSON.stringify({ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }], })).pipe( (() => { const { Writable } = require("stream"); return new Writable({ write(chunk, _enc, cb) { const lines = chunk.toString().split("\n"); for (const line of lines) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const data = JSON.parse(line.slice(6)); process.stdout.write(data.choices[0]?.delta?.content ?? ""); } cb(); }, }); })());import OpenAI from "openai";const client = new OpenAI({apiKey: process.env.SILKDOCK_API_KEY,baseURL: "https://silkdock.ai/v1",});const stream = await client.chat.completions.create({model: "gpt-4.1-mini",messages: [{ role: "user", content: "Write a short poem" }],stream: true,});for await (const chunk of stream) {const content = chunk.choices[0]?.delta?.content ?? "";process.stdout.write(content);}const res = await fetch("https://silkdock.ai/v1/chat/completions", {method: "POST",headers: { "Authorization": `Bearer ${process.env.SILKDOCK_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ model: "gpt-4.1-mini", action: "chat", stream: true, messages: [{ role: "user", content: "Write a short poem" }],}),});const reader = res.body!.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) break;for (const line of decoder.decode(value).split("\n")) { if (!line.startsWith("data: ") || line === "data: [DONE]") continue; const chunk = JSON.parse(line.slice(6)); process.stdout.write(chunk.choices[0]?.delta?.content ?? "");}}import requests, json, oswith requests.post( "https://silkdock.ai/v1/chat/completions", headers={"Authorization": f"Bearer {os.getenv('SILKDOCK_API_KEY')}"}, json={ "model": "gpt-4.1-mini", "stream": True, "messages": [{"role": "user", "content": "Write a short poem"}], }, stream=True,) as res: for line in res.iter_lines(): if not line or line == b"data: [DONE]": continue chunk = json.loads(line.removeprefix(b"data: ")) print(chunk["choices"][0]["delta"].get("content", ""), end="", flush=True)import osfrom openai import OpenAIclient = OpenAI( api_key=os.getenv("SILKDOCK_API_KEY"), base_url="https://silkdock.ai/v1")stream = client.chat.completions.create( model="gpt-4.1-mini", messages=[{"role": "user", "content": "Write a short poem"}], stream=True)for chunk in stream: delta = chunk.choices[0].delta if delta.content: print(delta.content, end="", flush=True)#include <stdio.h>#include <string.h>#include <curl/curl.h>static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) { size_t total = size * nmemb; /* ptr may contain multiple lines separated by \n */ char buf[8192]; memcpy(buf, ptr, total < sizeof(buf) - 1 ? total : sizeof(buf) - 1); buf[total < sizeof(buf) - 1 ? total : sizeof(buf) - 1] = '\0'; char *line = strtok(buf, "\n"); while (line) { if (strncmp(line, "data: ", 6) == 0 && strcmp(line, "data: [DONE]") != 0) { printf("%s\n", line + 6); fflush(stdout); } line = strtok(NULL, "\n"); } return total;}int main(void) { CURL *curl = curl_easy_init(); if (!curl) return 1; const char *api_key = getenv("SILKDOCK_API_KEY"); char auth_header[256]; snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", api_key ? api_key : ""); struct curl_slist *headers = NULL; headers = curl_slist_append(headers, auth_header); headers = curl_slist_append(headers, "Content-Type: application/json"); const char *body = "{\"model\":\"gpt-4.1-mini\",\"stream\":true," "\"messages\":[{\"role\":\"user\",\"content\":\"Write a short poem\"}]}"; curl_easy_setopt(curl, CURLOPT_URL, "https://silkdock.ai/v1/chat/completions"); curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 1L); /* minimize buffering */ curl_easy_perform(curl); curl_slist_free_all(headers); curl_easy_cleanup(curl); return 0;}#import <Foundation/Foundation.h>@interface StreamDelegate : NSObject <NSURLSessionDataDelegate>@property (nonatomic, strong) NSMutableData *buffer;@end@implementation StreamDelegate- (instancetype)init { self = [super init]; _buffer = [NSMutableData data]; return self;}- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { [self.buffer appendData:data]; // Process complete lines NSString *text = [[NSString alloc] initWithData:self.buffer encoding:NSUTF8StringEncoding]; NSArray<NSString *> *lines = [text componentsSeparatedByString:@"\n"]; NSMutableData *remainder = [NSMutableData data]; for (NSUInteger i = 0; i < lines.count; i++) { NSString *line = lines[i]; if (i == lines.count - 1) { // Last segment may be incomplete [remainder appendData:[line dataUsingEncoding:NSUTF8StringEncoding]]; break; } if ([line hasPrefix:@"data: "] && ![line isEqualToString:@"data: [DONE]"]) { NSString *json = [line substringFromIndex:6]; NSLog(@"%@", json); } } self.buffer = remainder;}- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError *)error { if (error) NSLog(@"Error: %@", error); CFRunLoopStop(CFRunLoopGetMain());}@endint main(int argc, const char *argv[]) { @autoreleasepool { NSURL *url = [NSURL URLWithString:@"https://silkdock.ai/v1/chat/completions"]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; req.HTTPMethod = @"POST"; NSString *apiKey = [NSProcessInfo.processInfo.environment objectForKey:@"SILKDOCK_API_KEY"]; [req setValue:[NSString stringWithFormat:@"Bearer %@", apiKey] forHTTPHeaderField:@"Authorization"]; [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; NSDictionary *bodyDict = @{ @"model": @"gpt-4.1-mini", @"stream": @YES, @"messages": @[@{@"role": @"user", @"content": @"Write a short poem"}], }; req.HTTPBody = [NSJSONSerialization dataWithJSONObject:bodyDict options:0 error:nil]; StreamDelegate *delegate = [[StreamDelegate alloc] init]; NSURLSession *session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration delegate:delegate delegateQueue:nil]; [[session dataTaskWithRequest:req] resume]; CFRunLoopRun(); } return 0;}import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.*;OpenAIClient client = OpenAIOkHttpClient.builder() .apiKey(System.getenv("SILKDOCK_API_KEY")) .baseURL("https://silkdock.ai/v1") .build();client.chat().completions().createStreaming( ChatCompletionCreateParams.builder() .model(ChatModel.GPT_4_1_MINI) .addUserMessage("Write a short poem") .build()).subscribe(chunk -> chunk.choices().stream() .map(c -> c.delta().content().orElse("")) .forEach(System.out::print));import java.net.http.*;import java.net.URI;import java.io.*;var req = HttpRequest.newBuilder() .uri(URI.create("https://silkdock.ai/v1/chat/completions")) .header("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString( """{"model":"gpt-4.1-mini","stream":true, "messages":[{"role":"user","content":"Write a short poem"}]}""")) .build();HttpClient.newHttpClient() .send(req, HttpResponse.BodyHandlers.ofLines()) .body() .filter(line -> line.startsWith("data: ") && !line.equals("data: [DONE]")) .map(line -> line.substring(6)) .forEach(System.out::println);import okhttp3.*;import java.io.*;OkHttpClient client = new OkHttpClient();String body = "{\"model\":\"gpt-4.1-mini\",\"stream\":true," + "\"messages\":[{\"role\":\"user\",\"content\":\"Write a short poem\"}]}";Request request = new Request.Builder() .url("https://silkdock.ai/v1/chat/completions") .addHeader("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .addHeader("Content-Type", "application/json") .post(RequestBody.create(body, MediaType.parse("application/json"))) .build();try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); BufferedReader reader = new BufferedReader(response.body().charStream()); String line; while ((line = reader.readLine()) != null) { if (line.startsWith("data: ") && !line.equals("data: [DONE]")) { System.out.println(line.substring(6)); } }}// Unirest does not natively support SSE streaming.// The example below collects the full response body on completion.import kong.unirest.*;HttpResponse<String> response = Unirest.post("https://silkdock.ai/v1/chat/completions") .header("Authorization", "Bearer " + System.getenv("SILKDOCK_API_KEY")) .header("Content-Type", "application/json") .body("{\"model\":\"gpt-4.1-mini\",\"stream\":true," + "\"messages\":[{\"role\":\"user\",\"content\":\"Write a short poem\"}]}") .asString();for (String line : response.getBody().split("\n")) { if (line.startsWith("data: ") && !line.equals("data: [DONE]")) { System.out.println(line.substring(6)); }}package mainimport ( "context" "fmt" "os" "github.com/openai/openai-go" "github.com/openai/openai-go/option")func main() { client := openai.NewClient( option.WithAPIKey(os.Getenv("SILKDOCK_API_KEY")), option.WithBaseURL("https://silkdock.ai/v1"), ) stream := client.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{ Model: openai.F(openai.ChatModelGPT4_1Mini), Messages: openai.F([]openai.ChatCompletionMessageParamUnion{ openai.UserMessage("Write a short poem"), }), }, ) for stream.Next() { chunk := stream.Current() if len(chunk.Choices) > 0 { fmt.Print(chunk.Choices[0].Delta.Content) } }}package mainimport ( "bufio" "bytes" "encoding/json" "fmt" "net/http" "os" "strings")func main() { body, _ := json.Marshal(map[string]any{ "model": "gpt-4.1-mini", "stream": true, "messages": []map[string]string{{"role": "user", "content": "Write a short poem"}}, }) req, _ := http.NewRequest("POST", "https://silkdock.ai/v1/chat/completions", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+os.Getenv("SILKDOCK_API_KEY")) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) for scanner.Scan() { line := scanner.Text() if !strings.HasPrefix(line, "data: ") || line == "data: [DONE]" { continue } var chunk map[string]any json.Unmarshal([]byte(line[6:]), &chunk) fmt.Print(chunk) }}<?php$ch = curl_init("https://silkdock.ai/v1/chat/completions");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => false, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "model" => "gpt-4.1-mini", "stream" => true, "messages" => [["role" => "user", "content" => "Write a short poem"]], ]), CURLOPT_WRITEFUNCTION => function($ch, $data) { echo $data; flush(); return strlen($data); },]);curl_exec($ch);<?php// HTTP_Request2 does not stream responses natively.// Install via: composer require pear/http_request2require_once "vendor/autoload.php";use HTTP_Request2;$request = new HTTP_Request2("https://silkdock.ai/v1/chat/completions", HTTP_Request2::METHOD_POST);$request->setHeader("Authorization", "Bearer " . getenv("SILKDOCK_API_KEY"));$request->setHeader("Content-Type", "application/json");$request->setBody(json_encode([ "model" => "gpt-4.1-mini", "stream" => true, "messages" => [["role" => "user", "content" => "Write a short poem"]],]));$response = $request->send();$body = $response->getBody();foreach (explode("\n", $body) as $line) { if (str_starts_with($line, "data: ") && $line !== "data: [DONE]") { echo substr($line, 6) . "\n"; flush(); }}<?php// Install via: composer require guzzlehttp/guzzlerequire_once "vendor/autoload.php";use GuzzleHttp\Client;$client = new Client();$response = $client->post("https://silkdock.ai/v1/chat/completions", [ "headers" => [ "Authorization" => "Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type" => "application/json", ], "json" => [ "model" => "gpt-4.1-mini", "stream" => true, "messages" => [["role" => "user", "content" => "Write a short poem"]], ], "stream" => true,]);$body = $response->getBody();$buffer = "";while (!$body->eof()) { $buffer .= $body->read(1024); $lines = explode("\n", $buffer); // Keep last (possibly incomplete) line in the buffer $buffer = array_pop($lines); foreach ($lines as $line) { if (str_starts_with($line, "data: ") && $line !== "data: [DONE]") { echo substr($line, 6) . "\n"; flush(); } }}<?php// Requires the pecl_http (http) extension: pecl install pecl_http$client = new http\Client();$request = new http\Client\Request( "POST", "https://silkdock.ai/v1/chat/completions", [ "Authorization" => "Bearer " . getenv("SILKDOCK_API_KEY"), "Content-Type" => "application/json", ], new http\Message\Body( fopen("data://text/plain," . urlencode(json_encode([ "model" => "gpt-4.1-mini", "stream" => true, "messages" => [["role" => "user", "content" => "Write a short poem"]], ])), "r") ));$client->enqueue($request)->send();$response = $client->getResponse();$body = $response->getBody();foreach (explode("\n", (string)$body) as $line) { if (str_starts_with($line, "data: ") && $line !== "data: [DONE]") { echo substr($line, 6) . "\n"; flush(); }}import OpenAIlet client = OpenAI(configuration: .init( token: ProcessInfo.processInfo.environment["SILKDOCK_API_KEY"]!, host: "silkdock.ai", scheme: "https"))let query = ChatQuery( messages: [.init(role: .user, content: "Write a short poem")], model: "gpt-4.1-mini")for try await result in client.chatsStream(query: query) { print(result.choices.first?.delta.content ?? "", terminator: "")}import Foundationvar req = URLRequest(url: URL(string: "https://silkdock.ai/v1/chat/completions")!)req.httpMethod = "POST"req.setValue("Bearer \(ProcessInfo.processInfo.environment["SILKDOCK_API_KEY"]!)", forHTTPHeaderField: "Authorization")req.setValue("application/json", forHTTPHeaderField: "Content-Type")req.httpBody = try! JSONSerialization.data(withJSONObject: [ "model": "gpt-4.1-mini", "stream": true, "messages": [["role": "user", "content": "Write a short poem"]],])let (stream, _) = try! await URLSession.shared.bytes(for: req)for try await line in stream.lines { guard line.hasPrefix("data: "), line != "data: [DONE]" else { continue } print(line.dropFirst(6))}using OpenAI;using OpenAI.Chat;var client = new ChatClient( model: "gpt-4.1-mini", credential: new System.ClientModel.ApiKeyCredential( Environment.GetEnvironmentVariable("SILKDOCK_API_KEY")!), options: new OpenAIClientOptions { Endpoint = new Uri("https://silkdock.ai/v1") });await foreach (var update in client.CompleteChatStreamingAsync( new UserChatMessage("Write a short poem"))){ foreach (var part in update.ContentUpdate) Console.Write(part.Text);}using System.Net.Http;using System.Net.Http.Json;var client = new HttpClient();client.DefaultRequestHeaders.Add("Authorization", $"Bearer {Environment.GetEnvironmentVariable("SILKDOCK_API_KEY")}");var res = await client.PostAsJsonAsync("https://silkdock.ai/v1/chat/completions", new { model = "gpt-4.1-mini", stream = true, messages = new[] { new { role = "user", content = "Write a short poem" } },});using var reader = new StreamReader(await res.Content.ReadAsStreamAsync());while (!reader.EndOfStream) { var line = await reader.ReadLineAsync(); if (line?.StartsWith("data: ") == true && line != "data: [DONE]") Console.WriteLine(line[6..]);}require "openai"client = OpenAI::Client.new(access_token: ENV["SILKDOCK_API_KEY"],uri_base: "https://silkdock.ai/v1")client.chat(parameters: { model: "gpt-4.1-mini", messages: [{ role: "user", content: "Write a short poem" }], stream: proc { |chunk, _bytesize| print chunk.dig("choices", 0, "delta", "content") }})require "net/http"require "json"uri = URI("https://silkdock.ai/v1/chat/completions")req = Net::HTTP::Post.new(uri)req["Authorization"] = "Bearer #{ENV['SILKDOCK_API_KEY']}"req["Content-Type"] = "application/json"req.body = {model: "gpt-4.1-mini", stream: true,messages: [{ role: "user", content: "Write a short poem" }]}.to_jsonNet::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|http.request(req) do |res| res.read_body do |chunk| chunk.each_line do |line| next unless line.start_with?("data: ") && line.strip != "data: [DONE]" puts line[6..] end endendendimport com.openai.client.OpenAIClientimport com.openai.client.okhttp.OpenAIOkHttpClientimport com.openai.models.*val client: OpenAIClient = OpenAIOkHttpClient.builder() .apiKey(System.getenv("SILKDOCK_API_KEY")) .baseURL("https://silkdock.ai/v1") .build()client.chat().completions().createStreaming( ChatCompletionCreateParams.builder() .model(ChatModel.GPT_4_1_MINI) .addUserMessage("Write a short poem") .build()).subscribe { chunk -> chunk.choices().forEach { choice -> print(choice.delta().content().orElse("")) }}import java.net.http.*import java.net.URIval req = HttpRequest.newBuilder() .uri(URI.create("https://silkdock.ai/v1/chat/completions")) .header("Authorization", "Bearer ${System.getenv("SILKDOCK_API_KEY")}") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString( """{"model":"gpt-4.1-mini","stream":true, "messages":[{"role":"user","content":"Write a short poem"}]}""")) .build()HttpClient.newHttpClient() .send(req, HttpResponse.BodyHandlers.ofLines()) .body() .filter { it.startsWith("data: ") && it != "data: [DONE]" } .forEach { println(it.substring(6)) }use reqwest::blocking::Client;use serde_json::json;use std::io::{BufRead, BufReader};fn main() -> Result<(), Box<dyn std::error::Error>> { let res = Client::new() .post("https://silkdock.ai/v1/chat/completions") .header("Authorization", format!("Bearer {}", std::env::var("SILKDOCK_API_KEY")?)) .json(&json!({ "model": "gpt-4.1-mini", "stream": true, "messages": [{"role": "user", "content": "Write a short poem"}] })) .send()?; for line in BufReader::new(res).lines().flatten() { if line.starts_with("data: ") && line != "data: [DONE]" { println!("{}", &line[6..]); } } Ok(())}POST /v1/chat/completions HTTP/1.1Host: silkdock.aiAuthorization: Bearer <YOUR_API_KEY>Content-Type: application/json{"model": "gpt-4.1-mini","stream": true,"messages": [{"role": "user", "content": "Write a short poem"}]}import 'dart:convert';import 'package:http/http.dart' as http;void main() async {final req = http.Request('POST', Uri.parse('https://silkdock.ai/v1/chat/completions')) ..headers['Authorization'] = 'Bearer ${const String.fromEnvironment("SILKDOCK_API_KEY")}' ..headers['Content-Type'] = 'application/json' ..body = jsonEncode({ 'model': 'gpt-4.1-mini', 'action': 'chat', 'stream': true, 'messages': [{'role': 'user', 'content': 'Write a short poem'}], });final res = await http.Client().send(req);await for (final chunk in res.stream.transform(utf8.decoder).transform(const LineSplitter())) { if (chunk.startsWith('data: ') && chunk != 'data: [DONE]') { print(chunk.substring(6)); }}}library(httr2)req <- request("https://silkdock.ai/v1/chat/completions") |>req_headers( Authorization = paste("Bearer", Sys.getenv("SILKDOCK_API_KEY")), "Content-Type" = "application/json") |>req_body_json(list( model = "gpt-4.1-mini", action = "chat", stream = TRUE, messages = list(list(role = "user", content = "Write a short poem"))))# Stream response line by lineresp <- req_perform_connection(req)while (!is.null(line <- readLines(resp, n = 1, warn = FALSE))) {if (startsWith(line, "data: ") && line != "data: [DONE]") cat(substring(line, 7), "\n")}(* requires cohttp-lwt-unix: opam install cohttp-lwt-unix *)open Cohttp_lwt_unixopen Cohttpopen Lwtlet () =let body = {|{"model":"gpt-4.1-mini","stream":true, "messages":[{"role":"user","content":"Write a short poem"}]}|}inlet headers = Header.of_list [ ("Authorization", "Bearer " ^ Sys.getenv "SILKDOCK_API_KEY") ; ("Content-Type", "application/json") ]inLwt_main.run ( Client.post ~headers ~body:(Cohttp_lwt.Body.of_string body) (Uri.of_string "https://silkdock.ai/v1/chat/completions") >>= fun (_, body) -> Cohttp_lwt.Body.to_string body >>= fun s -> String.split_on_char '\n' s |> List.iter (fun line -> if String.length line > 6 && String.sub line 0 6 = "data: " then print_string (String.sub line 6 (String.length line - 6))); return_unit )Chunk format
Each event is a data: line containing a JSON object:
{
"id": "chatcmpl-abc123",
"object": "chat.completion.chunk",
"model": "gpt-4.1-mini",
"choices": [
{
"index": 0,
"delta": { "content": "Roses" },
"finish_reason": null
}
]
}The final chunk has "finish_reason": "stop", followed by data: [DONE].
Last updated on