Quickstart
1. Create an account
Open the Console and sign in with email or GitHub OAuth. Your account is created automatically on first login.
2. Get an API key
Open the API Keys page, click New API Key, and copy the string that starts with sk-. The key is shown in full only once at creation; after you close the dialog you will only see a masked version, so save it somewhere safe right away.
TIP
Put the key in an environment variable, for example export SAKRYLLE_API_KEY=sk-xxxxxxxxxxxxxxxx, to avoid committing it by mistake.
3. First request
The example below calls /v1/chat/completions with gpt-5.6-sol:
curl https://api.sakrylle.com/v1/chat/completions \
-H "Authorization: Bearer $SAKRYLLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"messages": [
{"role": "user", "content": "Introduce yourself."}
]
}'# pip install openai
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.sakrylle.com/v1",
api_key=os.environ["SAKRYLLE_API_KEY"],
)
resp = client.chat.completions.create(
model="gpt-5.6-sol",
messages=[{"role": "user", "content": "Introduce yourself."}],
)
print(resp.choices[0].message.content)// npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.sakrylle.com/v1",
apiKey: process.env.SAKRYLLE_API_KEY,
});
const resp = await client.chat.completions.create({
model: "gpt-5.6-sol",
messages: [{ role: "user", content: "Introduce yourself." }],
});
console.log(resp.choices[0].message.content);// go get github.com/openai/openai-go
package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
func main() {
client := openai.NewClient(
option.WithBaseURL("https://api.sakrylle.com/v1"),
option.WithAPIKey(os.Getenv("SAKRYLLE_API_KEY")),
)
resp, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: openai.F("gpt-5.6-sol"),
Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Introduce yourself."),
}),
})
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
}// cargo add reqwest --features json,rustls-tls
// cargo add tokio --features full
// cargo add serde_json
use reqwest::Client;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = std::env::var("SAKRYLLE_API_KEY")?;
let body = json!({
"model": "gpt-5.6-sol",
"messages": [{"role": "user", "content": "Introduce yourself."}]
});
let resp: serde_json::Value = Client::new()
.post("https://api.sakrylle.com/v1/chat/completions")
.bearer_auth(key)
.json(&body)
.send().await?
.json().await?;
println!("{}", resp["choices"][0]["message"]["content"]);
Ok(())
}// Standard library java.net.http; JDK 11+
import java.net.URI;
import java.net.http.*;
public class Quickstart {
public static void main(String[] args) throws Exception {
String key = System.getenv("SAKRYLLE_API_KEY");
String body = """
{"model":"gpt-5.6-sol",
"messages":[{"role":"user","content":"Introduce yourself."}]}
""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.sakrylle.com/v1/chat/completions"))
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}// dotnet add package System.Net.Http.Json
using System.Net.Http.Headers;
using System.Net.Http.Json;
var key = Environment.GetEnvironmentVariable("SAKRYLLE_API_KEY");
using var http = new HttpClient { BaseAddress = new Uri("https://api.sakrylle.com/v1/") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key);
var resp = await http.PostAsJsonAsync("chat/completions", new {
model = "gpt-5.6-sol",
messages = new[] { new { role = "user", content = "Introduce yourself." } }
});
Console.WriteLine(await resp.Content.ReadAsStringAsync());4. Streaming responses
Set stream to true and the server pushes incremental tokens over SSE (text/event-stream).
curl https://api.sakrylle.com/v1/chat/completions \
-H "Authorization: Bearer $SAKRYLLE_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "gpt-5.6-sol",
"stream": true,
"messages": [{"role": "user", "content": "Tell a short story about cherry blossoms."}]
}'from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.sakrylle.com/v1",
api_key=os.environ["SAKRYLLE_API_KEY"],
)
stream = client.chat.completions.create(
model="gpt-5.6-sol",
stream=True,
messages=[{"role": "user", "content": "Tell a short story about cherry blossoms."}],
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.sakrylle.com/v1",
apiKey: process.env.SAKRYLLE_API_KEY,
});
const stream = await client.chat.completions.create({
model: "gpt-5.6-sol",
stream: true,
messages: [{ role: "user", content: "Tell a short story about cherry blossoms." }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}package main
import (
"context"
"fmt"
"io"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
func main() {
client := openai.NewClient(
option.WithBaseURL("https://api.sakrylle.com/v1"),
option.WithAPIKey(os.Getenv("SAKRYLLE_API_KEY")),
)
stream := client.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{
Model: openai.F("gpt-5.6-sol"),
Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Tell a short story about cherry blossoms."),
}),
})
for stream.Next() {
chunk := stream.Current()
if len(chunk.Choices) > 0 {
fmt.Print(chunk.Choices[0].Delta.Content)
}
}
if err := stream.Err(); err != nil && err != io.EOF {
panic(err)
}
}use futures_util::StreamExt;
use reqwest::Client;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = std::env::var("SAKRYLLE_API_KEY")?;
let body = json!({
"model": "gpt-5.6-sol",
"stream": true,
"messages": [{"role": "user", "content": "Tell a short story about cherry blossoms."}]
});
let mut stream = Client::new()
.post("https://api.sakrylle.com/v1/chat/completions")
.bearer_auth(key)
.json(&body)
.send().await?
.bytes_stream();
while let Some(chunk) = stream.next().await {
print!("{}", String::from_utf8_lossy(&chunk?));
}
Ok(())
}import java.net.URI;
import java.net.http.*;
public class Stream {
public static void main(String[] args) throws Exception {
String key = System.getenv("SAKRYLLE_API_KEY");
String body = """
{"model":"gpt-5.6-sol","stream":true,
"messages":[{"role":"user","content":"Tell a short story about cherry blossoms."}]}
""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.sakrylle.com/v1/chat/completions"))
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofLines())
.body()
.forEach(System.out::println);
}
}using System.Net.Http.Headers;
var key = Environment.GetEnvironmentVariable("SAKRYLLE_API_KEY");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key);
var content = new StringContent("""
{"model":"gpt-5.6-sol","stream":true,
"messages":[{"role":"user","content":"Tell a short story about cherry blossoms."}]}
""", System.Text.Encoding.UTF8, "application/json");
using var resp = await http.PostAsync(
"https://api.sakrylle.com/v1/chat/completions", content,
HttpCompletionOption.ResponseHeadersRead);
using var stream = await resp.Content.ReadAsStreamAsync();
using var reader = new StreamReader(stream);
string? line;
while ((line = await reader.ReadLineAsync()) != null) {
Console.WriteLine(line);
}5. Anthropic native
Change the endpoint to /v1/messages, the model to claude-haiku-4-5-20251001, and follow the Anthropic message schema:
curl https://api.sakrylle.com/v1/messages \
-H "Authorization: Bearer $SAKRYLLE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5-20251001",
"max_tokens": 256,
"messages": [
{"role": "user", "content": "Introduce yourself."}
]
}'# pip install anthropic
from anthropic import Anthropic
import os
client = Anthropic(
base_url="https://api.sakrylle.com",
api_key=os.environ["SAKRYLLE_API_KEY"],
)
resp = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=256,
messages=[{"role": "user", "content": "Introduce yourself."}],
)
print(resp.content[0].text)// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.sakrylle.com",
apiKey: process.env.SAKRYLLE_API_KEY,
});
const resp = await client.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 256,
messages: [{ role: "user", content: "Introduce yourself." }],
});
console.log(resp.content[0].text);TIP
The official Anthropic SDK reads ANTHROPIC_API_KEY by default. We pass api_key=SAKRYLLE_API_KEY explicitly because the same Sakrylle key is used. The base_url does not need a /v1 suffix — the SDK appends it.
Next steps
- API reference — full request and response fields for every endpoint
- SDK examples — full clients for Python, Node, Go, Rust, Java, and C#
- Models and pricing — how the actual price comes from the upstream rate times the discount multiplier
- Errors — how to debug 4xx and 5xx responses
