Key facts
| Chat endpoint | POST https://api.plugsky.com/v1/chat/completions |
| SDK | pip install openai (Python 3.8+); a first-party Python SDK is also listed |
| Auth | OpenAI(api_key="sk-live-…", base_url="https://api.plugsky.com/v1") |
| Streaming | stream=True iterates chunks; the streaming helper exposes final usage |
| Tools and JSON | tools, tool_choice and response_format are supported |
| Embeddings | POST /v1/embeddings with plugsky-embed (2048 dimensions in the docs example) |
| Retries | SDK exponential backoff; 429 returns Retry-After; POSTs accept Idempotency-Key |
| Product status | Live; audio, images, batch and fine-tuning are coming soon |
TL;DR
- pip install openai and reach 30+ models with two constructor arguments.
- AsyncOpenAI mirrors the same API for asyncio services.
- Streaming supports both a raw iterator and a helper with final usage.
- Embeddings use model plugsky-embed through the same client.
- The SDK retries 429 and 5xx automatically with backoff.
How it works, step by step
- Install the SDK with pip install openai and export PLUGSKY_API_KEY.
- Create one OpenAI client with the Plugsky base_url and reuse it across requests.
- Run a chat completion with model plugsky-lite and print the first choice.
- Add streaming with stream=True or the streaming helper for live output.
- Define tools, handle tool_calls, and append tool results to the messages list.
- Generate embeddings with model plugsky-embed for search or RAG.
- Wrap calls with retries, timeouts and usage logging before production.
Original data
Try it yourself
Open the OpenAI-compatible API tester →
Install and configure
The fastest path is the official OpenAI SDK, which the Plugsky quickstart documents directly:
pip install openai
export PLUGSKY_API_KEY="sk-live-…"from openai import OpenAI
client = OpenAI(
api_key="sk-live-…",
base_url="https://api.plugsky.com/v1",
)
resp = client.chat.completions.create(
model="plugsky-pro",
messages=[{"role": "user", "content": "Summarise this changelog in three bullets."}],
temperature=0.2,
)
print(resp.choices[0].message.content)Construct the client once at module scope. Creating it per request rebuilds the HTTP connection pool and adds measurable overhead in busy services. For asyncio apps, use AsyncOpenAI with the same arguments.
Streaming and back-pressure
For chat interfaces, stream. The raw form gives you chunks as they arrive:
stream = client.chat.completions.create(
model="plugsky-micro",
messages=[{"role": "user", "content": "Count to ten."}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")The streaming helper gives you the same output plus the final completion, which is where usage lives:
with client.chat.completions.stream(
model="plugsky-pro",
messages=[{"role": "user", "content": "Write a 200-word update."}],
) as s:
for text in s.text_stream:
print(text, end="", flush=True)
print(s.get_final_completion().usage)Log that usage per request; it is the cheapest way to catch runaway prompts before they reach production budgets.
Tools, JSON mode and structured output
Function calling uses the standard tools parameter. The loop is: send tools, check message.tool_calls, execute each function, append {"role": "tool", "tool_call_id": …, "content": …}, and call again until the model answers. For extraction tasks, request JSON explicitly:
resp = client.chat.completions.create(
model="plugsky-pro",
messages=[{"role": "user", "content": "Extract title and priority as JSON."}],
response_format={"type": "json_object"},
)Parse with json.loads inside a try block and retry once with the error message if validation fails. Treat model output as untrusted input, exactly as you would user input.
Embeddings for retrieval
The same client, one method call:
resp = client.embeddings.create(
model="plugsky-embed",
input=["Refunds take five business days", "Support hours are 9-5 GST"],
)
print(len(resp.data[0].embedding), "dimensions")Store the vectors with the source text and metadata, then rank by cosine similarity. If you are switching from another provider, check the dimension count first — mixing vector spaces from different embedding models silently degrades retrieval, so re-index rather than reuse.
Production: retries, timeouts and observability
The SDK retries 429 and 5xx responses with exponential backoff and honors Retry-After. Set an explicit request timeout and a bounded max_retries so a slow upstream cannot pin your worker pool. Add an Idempotency-Key header to POSTs that may be retried; Plugsky caches the result for 24 hours and returns 409 if the same key is reused with a different body. Errors follow the OpenAI schema with message, type, code and param, which maps directly to structured logging. Endpoints such as batch, audio, images and fine-tuning are coming soon — check the docs before planning workloads that depend on them.
Honest comparison
| Capability | Plugsky + openai Python | requests or httpx directly | Self-hosted vLLM or TGI |
|---|---|---|---|
| Setup | pip install openai plus base_url | Hand-rolled client and auth | Deploy and serve the model |
| Streaming | Iterator over chunks; final usage | Parse SSE frames manually | Engine-dependent |
| Tools and JSON | Native tools and response_format | Manual JSON and validation | Varies by server |
| Embeddings | Same client with plugsky-embed | Separate HTTP code path | A second server to run |
| Async | AsyncOpenAI | httpx.AsyncClient | Your own stack |
| Ops | Managed API | Managed API | GPUs, scaling and patches |
Frequently asked questions
Which Python version is supported?
The Plugsky SDK reference lists Python 3.8+. Any currently supported Python release works with the OpenAI-compatible client.
How do I install and authenticate?
Run pip install openai, then OpenAI(api_key="sk-live-…", base_url="https://api.plugsky.com/v1"). Read the key from PLUGSKY_API_KEY rather than hard-coding it.
How do I stream responses?
Pass stream=True and iterate over chunks, or use client.chat.completions.stream() to get text plus the final completion with usage.
Does function calling work?
Yes. Define tools, check message.tool_calls, execute the functions and append tool messages with the matching tool_call_id before calling again.
Can I generate embeddings?
Yes. Call client.embeddings.create with model plugsky-embed. Dimensions differ from some other providers, so re-index when switching.
How are rate limits handled?
The SDK retries 429 and 5xx with exponential backoff and honors the Retry-After header. Bound your own retries to avoid amplifying load.
Is there a first-party Python SDK?
The Plugsky SDK reference lists an official Python SDK, but the OpenAI SDK with a base_url override is fully supported and is the quickest migration path.
What is on the roadmap?
Audio, images, moderation, files, batch, fine-tuning, assistants and the responses endpoint are coming soon. Chat, streaming, tools, JSON mode and embeddings are live.