Key facts
| Chat endpoint | POST https://api.plugsky.com/v1/chat/completions |
| SDK | npm install openai — the official OpenAI Node SDK works unchanged |
| Runtimes | Node 18+; the docs also list browser, Bun, Deno and Cloudflare Workers |
| Base URL | baseURL: "https://api.plugsky.com/v1" |
| Auth | apiKey from PLUGSKY_API_KEY; the SDK sends the Bearer header |
| Live capabilities | Streaming, function calling, JSON mode, structured outputs and vision on supported models |
| Models | 30+ models; start with plugsky-lite and scale to plugsky-pro |
| Product status | Live; audio, images, moderation, files, batch, fine-tuning, assistants and responses are coming soon |
TL;DR
- Two fields change: baseURL and apiKey.
- TypeScript types cover requests, chunks and tool calls.
- Streaming is a for-await loop over async chunks.
- The same client runs on Node, Bun, Deno and Workers.
- Keep one client per process for connection pooling.
How it works, step by step
- Install the SDK: npm install openai (add zod if you validate structured output).
- Create one client with apiKey and baseURL pointing at https://api.plugsky.com/v1.
- Call chat.completions.create with model plugsky-pro and a typed messages array.
- Stream by setting stream: true and iterating chunks with for await.
- Define tools with JSON-schema parameters and handle tool_calls responses.
- Use response_format for JSON mode and validate the result with zod.
- Set maxRetries and timeout, then deploy to Node, Bun, Deno or an edge runtime.
Original data
Try it yourself
Open the OpenAI-compatible API tester →
Install and configure the client
The SDK is the official OpenAI package. Create one client per process and reuse it so the underlying fetch agent keeps connections warm:
npm install openaiimport OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.PLUGSKY_API_KEY,
baseURL: "https://api.plugsky.com/v1",
});Never import this client into browser bundles. In Next.js, call it from route handlers or server actions; on Cloudflare Workers, store the key as a secret binding.
Chat completions in TypeScript
The call shape is the OpenAI shape, so existing code reviews and tests carry over:
const completion = await client.chat.completions.create({
model: "plugsky-pro",
messages: [
{ role: "system", content: "You are a terse release-notes editor." },
{ role: "user", content: "Summarise this changelog in three bullets." },
],
temperature: 0.2,
});
console.log(completion.choices[0].message.content);completion.usage carries prompt and completion token counts when you need them for internal metrics. Model ids such as plugsky-micro, plugsky-lite and plugsky-pro are interchangeable in the same call.
Streaming to a client
Set stream: true and iterate the async iterable. Each chunk follows the OpenAI delta shape, which most UI helpers already understand:
const stream = await client.chat.completions.create({
model: "plugsky-lite",
messages: [{ role: "user", content: "Write a short product update." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}For long generations, pass an AbortSignal wired to the incoming HTTP request so a disconnected browser cancels the upstream stream instead of burning tokens.
Tools, JSON mode and structured output
Function calling uses the standard tools array with JSON-schema parameters. When the model returns tool_calls, execute each function, append a tool message with the matching tool_call_id, and call again. This is the foundation for agents and RAG assistants built with the API.
For machine-readable output, request JSON and validate it rather than trusting it:
import { z } from "zod";
const Ticket = z.object({
title: z.string(),
priority: z.enum(["low", "medium", "high"]),
});
const resp = await client.chat.completions.create({
model: "plugsky-pro",
messages: [{ role: "user", content: "Extract a ticket from: checkout API is down." }],
response_format: { type: "json_object" },
});
const ticket = Ticket.parse(JSON.parse(resp.choices[0].message.content ?? "{}"));On validation failure, retry once with the validation error included in the prompt before falling back to a human review path.
Production notes and edge runtimes
Two settings matter in production: timeout (per-request, in milliseconds) and maxRetries. The SDK retries 429 and 5xx responses with exponential backoff, and honors Retry-After when Plugsky returns it. Add an Idempotency-Key header for POSTs you may retry. The same client works on Node 18+, Bun, Deno and Cloudflare Workers because it is built on fetch; just ensure the key is a runtime secret, not a bundled constant. Endpoints such as files, batch, assistants and the responses API are coming soon, so design assistants around chat completions plus tools today.
Honest comparison
| Capability | Plugsky + openai npm | Raw fetch | Self-hosted runtime |
|---|---|---|---|
| Setup | npm install openai plus two fields | fetch and manual SSE parsing | Deploy a model server and gateway |
| TypeScript types | Typed requests, chunks and tool calls | You write every interface | Depends on the engine |
| Streaming | for await over typed chunks | Parse SSE frames yourself | Engine-dependent |
| Tools and JSON | tools, tool_choice and response_format | Hand-built JSON and validation | Varies by model |
| Runtimes | Node 18+, Bun, Deno, Workers | Any fetch runtime | Your infrastructure |
| Ops | Managed | Managed | GPUs, scaling and upgrades |
Frequently asked questions
Do I need a Plugsky-specific npm package?
No. Install the official OpenAI SDK and set baseURL to https://api.plugsky.com/v1; the Plugsky docs list the OpenAI SDK as the supported Node.js path.
Which Node version is required?
Node 18 or newer. The SDK also runs on Bun, Deno, browsers and Cloudflare Workers because it uses fetch.
How does streaming work?
Set stream: true and use for await over the returned async iterable, appending chunk.choices[0].delta.content.
Can I use tools and function calling?
Yes. Pass a tools array with JSON-schema parameters and handle tool_calls responses in a loop, appending tool results with matching ids.
Is structured output supported?
JSON mode works through response_format. Validate the output with a schema library such as zod and retry with the validation error on failure.
How are errors handled?
Errors follow the OpenAI schema. Catch APIError, check status 401, 403, 429 or 413, and let the SDK retry idempotent failures with backoff.
Can I run this at the edge?
Yes. The client works wherever fetch is available. Keep the API key in a runtime secret and never expose it to the browser.
What about the Responses API?
It is coming soon on Plugsky. Until then, use /v1/chat/completions, which covers streaming, tools, JSON mode and vision on supported models.