Skypool Token
Token online
Sign up
DocsDeveloper Onboarding

Developer Onboarding

A Skypool Token onboarding guide for callers, covering Consumer API Keys, the OpenAI-compatible protocol, model selection, streaming responses, session-level caching, activity records, and common AI tool integrations.

Updated:

Who this page is for

Start here if you want to connect an application, script, AI coding tool, or OpenAI-compatible client to Skypool Token. After reading this guide, you should be able to create a Consumer API Key and complete your first model call through the unified OpenAI-compatible API.

The caller-side flow for Skypool Token is simple:

  • Use one unified baseURL
  • Use a Consumer API Key as the Bearer Token
  • Select a platform model with the request body's model field
  • Use the OpenAI-compatible /v1/chat/completions endpoint for regular chat, streaming output, tool calls, and multimodal input
  • Review usage, status, failure reasons, and billing records in the console

API entry point

For production, set your OpenAI-compatible client's baseURL to:

Text
https://a.skypool.xyz/v1

The full chat endpoint is:

Text
https://a.skypool.xyz/v1/chat/completions

All OpenAI-compatible requests should carry the key in the request headers:

Text
Authorization: Bearer <consumer_api_key>

Do not put the API Key in URLs, logs, public frontend code, or configuration files that users can download.

Step 1: Create a Consumer API Key

Log in to the Skypool Token console, open the Consumer-side API Key page, and click Create API Key. After creation succeeds, the page displays the full key. Consumer keys usually start with stc-.

We recommend splitting keys by application or environment, for example:

ScenarioRecommendation
Local developmentCreate a separate development key so it is easy to debug and delete at any time
Production serviceUse a production key that is deployed only on the server side
AI coding toolsCreate a separate key for each tool or team to make abnormal requests easier to troubleshoot
Temporary testingDelete the key after testing to avoid leaving long-lived credentials behind

Step 2: Choose a model

View currently available models on the Models page or in the usage examples in the console.

You can also read the model list through the OpenAI-compatible API:

URL
https://a.skypool.xyz/v1/models

Context length, pricing, tool-calling support, and multimodal capabilities may vary by model. Before connecting a production application, we recommend confirming the target model's response structure, latency, and failure semantics in the console or with a test script.

Step 3: Make your first request

The following is a minimal non-streaming request. Replace <consumer_api_key> with your Consumer API Key, and change model to the model you want to use.

For an even simpler test path, you can try it directly in Skypool Playground.

Bash
curl -X POST "https://a.skypool.xyz/v1/chat/completions" \  -H "Authorization: Bearer <consumer_api_key>" \  -H "Content-Type: application/json" \  --data-raw '{    "model": "qwen3.8:27b",    "messages": [      {        "role": "user",        "content": "Hello, introduce Skypool Token in one sentence."      }    ],    "max_tokens": 128,    "stream": false  }'

If the response contains choices[0].message.content, your key, endpoint, and model are working.

Step 4: Enable streaming output

For interactive scenarios such as chat, agents, and AI coding tools, streaming output is recommended. Use stream: true for streaming requests, and include stream_options.include_usage: true so the final frame can return real usage.

Bash
curl -N -X POST "https://a.skypool.xyz/v1/chat/completions" \  -H "Authorization: Bearer <consumer_api_key>" \  -H "Content-Type: application/json" \  --data-raw '{    "model": "qwen3.8:27b",    "messages": [      {        "role": "user",        "content": "Give me a minimal TypeScript HTTP client example."      }    ],    "max_tokens": 512,    "stream": true,    "stream_options": {      "include_usage": true    }  }'

Streaming responses follow the OpenAI-compatible SSE format: each event starts with data:, and a normal completion returns data: [DONE]. Clients should handle incremental delta.content, tool-call deltas, the final usage frame, and mid-stream error events.

Session-level caching

For multi-turn conversations, Skypool Token automatically recognizes requests belonging to the same conversation and prefers the Provider node that last handled it successfully. This gives the inference runtime an opportunity to reuse previously computed context (KV cache), reducing repeated input processing and time to first token. You do not need to supply a session_id, custom session header, or prompt_cache_key to enable this automatic routing.

There are two parts: the platform tries to reuse a node, and the inference runtime on that node manages the actual cache. Reusing a node does not guarantee a cache hit or mean that the platform returns an earlier answer directly; each request still runs inference.

Keep a conversation consistent

For /v1/chat/completions, as used on this page, the platform identifies a conversation from the account, Consumer API Key, model, and the leading consecutive system / developer messages plus the first user message in messages. Appending messages after the first user does not change this identity.

  • Continue using the same API Key and model for subsequent turns.
  • Send the full conversation history each time. Preserve the initial system instructions and first user message, then append the actual model replies, tool results, and new questions in order. Automatic routing does not store or fill in message history for the client.
  • Keep existing message contents and order stable. In particular, avoid repeatedly injecting changing timestamps or random values into the opening system instructions. Changing the opening messages, Key, or model changes the conversation identity.
  • Under the same account, Key, and model, two conversations with identical openings share a node preference even if they are in different chat windows. This identity must therefore not be used as an application session ID or a data isolation mechanism.

For example, send this first turn:

JSON
{  "model": "qwen3.8:27b",  "messages": [    { "role": "system", "content": "You are a TypeScript assistant. Answer concisely." },    { "role": "user", "content": "How do I set a timeout for an HTTP request?" }  ],  "max_tokens": 256,  "stream": false}

After receiving the reply, keep the original messages and append the next turn. The assistant.content below is illustrative; use the actual message returned by the first request in your application:

JSON
{  "model": "qwen3.8:27b",  "messages": [    { "role": "system", "content": "You are a TypeScript assistant. Answer concisely." },    { "role": "user", "content": "How do I set a timeout for an HTTP request?" },    { "role": "assistant", "content": "Use AbortSignal.timeout to set a timeout for fetch." },    { "role": "user", "content": "Please also show how to handle timeout errors." }  ],  "max_tokens": 512,  "stream": true,  "stream_options": { "include_usage": true }}

A successfully completed first turn establishes a node preference, which the second turn attempts to reuse. Within one conversation, wait for the previous turn to finish before sending the next. Keep system instructions, tool definitions, and history stable to improve the opportunity for context prefix reuse.

Expiration and node changes

The node preference expires after 15 minutes by default and is refreshed after each successfully completed request. The actual duration depends on platform configuration. This does not promise that the runtime will retain its KV cache for 15 minutes.

If the original node is offline, busy, lacks sufficient context capacity, or cannot satisfy the request's capabilities, the platform selects another available node through its normal routing rules. An expired preference also triggers a fresh selection. Node restarts, model reloads, runtime cache eviction, or input prefix changes can all cause a cache miss. Continue sending the full history after a node change so the cache can be rebuilt.

Confirm a cache hit

Use the cache token count actually reported by the inference runtime. The same node or a faster response alone is insufficient evidence. Cache-read usage fields differ by protocol, and their availability depends on the node runtime and its protocol support:

EndpointCache-read field in the response
/v1/chat/completionsusage.prompt_tokens_details.cached_tokens
/v1/responsesusage.input_tokens_details.cached_tokens
/v1/messagesusage.cache_read_input_tokens

For the Chat Completions streaming requests used on this page, include stream_options.include_usage: true and read the usage frame before the stream ends. For other protocols, read usage from their native responses or stream events. For example:

JSON
{  "usage": {    "prompt_tokens": 1024,    "prompt_tokens_details": { "cached_tokens": 768 },    "completion_tokens": 128,    "total_tokens": 1152  }}

Here, 768 of the 1024 input tokens were read from cache. Cached tokens are already included in the input total and must not be added again. A value greater than 0 reports a cache hit; 0 reports no hit. An absent field means no observable cache data was provided and must not be treated as 0.

Use Activity records to review the platform's recorded cached input and actual charges. Cached input is billed using the model pricing applied to that request. Conversation continuity or node reuse alone does not imply free input, a fixed discount, or a cache hit. Except for the temporary LM Studio billing rule below, input without reported cache usage is billed at the regular input price.

Temporary LM Studio billing rule: Because cache reporting for LM Studio's /v1/chat/completions protocol is incomplete, non-cached input is temporarily billed at the cached input price. This is a billing rule and does not indicate an actual cache hit. It applies only to LM Studio's /v1/chat/completions, not to /v1/responses, /v1/messages, or other runtimes.

Control Qwen3.8 reasoning consistently

Backend Relay provides reasoning parameter compatibility for qwen3.8:27b requests sent to /v1/chat/completions, /v1/responses, and /v1/messages. Each protocol uses its own native fields, so configure reasoning according to the selected protocol.

A platform-side rollout switch controls this layer: the off state does not parse or rewrite requests, the observe state only records the resolution, and the enforce state validates and converts parameters. This section describes enforce behavior for qwen3.8:27b. Consumer P2P direct requests must still follow the target runtime's own parameter conventions.

Chat Completions reasoning parameters

For /v1/chat/completions, use only the top-level reasoning_effort field in each request:

GoalRecommended parameter
Disable reasoning"reasoning_effort": "none"
Enable low-effort reasoning"reasoning_effort": "low"
Enable medium-effort reasoning"reasoning_effort": "medium"
Enable maximum-effort reasoning"reasoning_effort": "xhigh"

For example, this request explicitly enables maximum-effort reasoning:

JSON
{  "model": "qwen3.8:27b",  "messages": [    {      "role": "user",      "content": "Analyze the main risks in this proposal."    }  ],  "reasoning_effort": "xhigh",  "stream": true,  "stream_options": {    "include_usage": true  }}

For Chat Completions, the platform also recognizes these compatible forms:

Compatible formSupported switch fields
Top-level fieldsthink, enable_thinking, reasoning, thinking, reasoning_effort
reasoning objectenabled, enable_thinking, effort, reasoning_effort, type, mode, status
thinking objectenabled, enable_thinking, type, mode, status
Template argumentschat_template_kwargs.enable_thinking, chat_template_kwargs.reasoning_effort

The Chat Completions compatibility layer converts an explicit enable or disable intent into a consistent runtime parameter bundle. Keep these rules in mind:

  • If the same request contains both enable and disable signals, disable wins to prevent unintended reasoning output.
  • Both reasoning_effort: "high" and "max" are mapped to the Qwen3.8-supported "xhigh". Prefer low, medium, xhigh, or none directly; high and max remain available as compatibility aliases for maximum-effort reasoning.
  • If no explicit switch is provided, the compatibility layer does not inject reasoning parameters; the model and runtime defaults determine the final behavior.
  • include_reasoning, preserve_thinking, reasoning-content format fields, and reasoning budget fields are not generation switches and cannot enable or disable reasoning by themselves.

Responses reasoning parameters

/v1/responses uses the nested reasoning.effort field: low, medium, and xhigh select reasoning effort levels, while none disables reasoning. high / max are normalized to xhigh, and off is normalized to none.

JSON
{  "model": "qwen3.8:27b",  "input": "Analyze the main risks in this proposal.",  "reasoning": { "effort": "xhigh" },  "max_output_tokens": 1024,  "store": false,  "stream": true}

The platform normalizes only reasoning.effort, preserving other native fields such as reasoning.summary. It does not inject Chat Completions fields such as reasoning_effort, think, or template parameters. Without reasoning.effort, the request remains unchanged; setting only reasoning.summary does not trigger the platform's reasoning-switch conversion.

Messages reasoning parameters

/v1/messages uses output_config.effort to specify reasoning effort. Prefer low, medium, or xhigh; high / max are normalized to xhigh. The native thinking configuration still expresses whether reasoning should be enabled or disabled, with support determined by the target runtime.

The following example uses Playground's native request format, requesting reasoning with thinking.type: "adaptive" and specifying the effort:

JSON
{  "model": "qwen3.8:27b",  "messages": [    { "role": "user", "content": "Analyze the main risks in this proposal." }  ],  "thinking": { "type": "adaptive" },  "output_config": { "effort": "xhigh" },  "max_tokens": 1024,  "stream": true}

The platform normalizes only output_config.effort, preserving thinking.type, thinking.budget_tokens, output formats, and other native fields. It does not apply the Chat Completions rule that disable wins. To disable reasoning, use a native setting supported by the target runtime, such as "thinking": { "type": "disabled" }, and remove the enabling output_config.effort to avoid sending conflicting intent.

The platform does not interpret output_config.effort: "none" / "off" as a disable switch. Unrecognized native effort values in Responses and Messages are forwarded unchanged for the runtime to handle; do not assume these values work across runtimes.

Use the OpenAI SDK

Any OpenAI SDK or compatible client that supports a custom baseURL can connect directly to Skypool Token.

The example below supports switching between TypeScript and Python in the same code block and copying the code for the current language:

import OpenAI from "openai"; const client = new OpenAI({  apiKey: process.env.SKYPOOL_API_KEY,  baseURL: "https://a.skypool.xyz/v1",}); const completion = await client.chat.completions.create({  model: "qwen3.8:27b",  messages: [    {      role: "user",      content: "Explain the benefit of an OpenAI-compatible API in one sentence.",    },  ],  max_tokens: 128,}); console.log(completion.choices[0]?.message?.content);

Connect AI coding tools

When connecting an AI coding tool, choose a protocol supported by the tool, then configure the API Key, endpoint, and model. All three protocols use Skypool Token Consumer API Keys and platform model names:

Configuration itemValue
API KeyConsumer API Key, for example stc-...
Base URL (OpenAI-style tools)https://a.skypool.xyz/v1
ModelPlatform model name, for example qwen3.8:27b

Choose a protocol and endpoint

ProtocolFull endpoint (POST)Protocol option in the tool
OpenAI-compatible protocol (Chat Completions)https://a.skypool.xyz/v1/chat/completionsOpenAI Compatible / Chat Completions
OpenAI Responses protocolhttps://a.skypool.xyz/v1/responsesOpenAI Responses / Responses API
Claude protocol (Messages)https://a.skypool.xyz/v1/messagesAnthropic / Claude / Messages API

Endpoint field names and path joining vary by tool. Ensure the final request URL matches the table above:

  • If an OpenAI-style tool appends /chat/completions or /responses to baseURL, Base URL, or OpenAI API Base, enter https://a.skypool.xyz/v1.
  • If an Anthropic / Claude-style tool appends /v1/messages, set its Base URL to https://a.skypool.xyz. If it appends only /messages, use https://a.skypool.xyz/v1. Avoid a duplicated /v1/v1 in the final URL.
  • If the tool requires a full endpoint, API Endpoint, or API URL, enter the selected protocol's complete endpoint from the table and configure the tool to use that protocol's request and response formats.

The protocol name describes the wire format; model selects the actual platform model. The target model needs an available node that supports the selected protocol. You can first select the same protocol in Skypool Playground to verify it before configuring the tool.

OpenAI-compatible protocol: /v1/chat/completions

Chat Completions sends conversations through messages and authenticates with Authorization: Bearer <consumer_api_key>. Use these request parameter recommendations:

ParameterRecommendation
modelUse a model ID from the platform Models page or the /v1/models response
messagesFollow the OpenAI-compatible message structure, and use the tool role for tool results
streamSet to true for chat, agent, and long-output scenarios
stream_options.include_usageSet to true for streaming requests so usage and billing are easier to verify
reasoning_effortFor Qwen3.8, use low, medium, or xhigh to enable reasoning and none to disable it
max_tokensSet an explicit output limit to avoid uncontrolled usage on long tasks
temperatureFor production tasks, start with a lower value and tune it for your business case
toolsUse the OpenAI-compatible tools structure when function calling is needed

Read non-streaming text from choices[0].message.content. For streaming, read choices[].delta, handle the final usage frame and error events, and recognize data: [DONE] as normal completion. See Control Qwen3.8 reasoning consistently for detailed reasoning parameter rules.

OpenAI Responses protocol: /v1/responses

/v1/responses accepts text or a message array in input, uses max_output_tokens for the output limit, and authenticates with Authorization: Bearer <consumer_api_key>. A minimal request is:

Bash
curl -X POST "https://a.skypool.xyz/v1/responses" \  -H "Authorization: Bearer <consumer_api_key>" \  -H "Content-Type: application/json" \  --data-raw '{    "model": "qwen3.8:27b",    "input": "Give me a TypeScript HTTP request example.",    "max_output_tokens": 512,    "store": false,    "stream": false  }'

Responses use the native output array, with text in the content of message output items. Streaming uses events such as response.output_text.delta and response.completed. Tools should parse the Responses format and handle response.failed, response.incomplete, and error events.

The platform currently uses stateless forwarding: include conversation history explicitly in input for subsequent turns. Continuation through previous_response_id or conversation, as well as store: true and background: true, is unsupported. Disable these features if the tool enables them automatically.

Claude protocol: /v1/messages

/v1/messages uses a messages array and requires a positive integer max_tokens. Put system instructions in the top-level system field. The platform supports x-api-key: <consumer_api_key> authentication and also accepts Authorization: Bearer <consumer_api_key>. Use the tool's native Anthropic headers and include anthropic-version, for example:

Bash
curl -X POST "https://a.skypool.xyz/v1/messages" \  -H "x-api-key: <consumer_api_key>" \  -H "anthropic-version: 2023-06-01" \  -H "Content-Type: application/json" \  --data-raw '{    "model": "qwen3.8:27b",    "system": "You are a TypeScript assistant. Answer concisely.",    "messages": [      { "role": "user", "content": "Give me an HTTP request example." }    ],    "max_tokens": 512,    "stream": false  }'

Responses use native content blocks and stop_reason. Streaming uses events such as content_block_delta, message_delta, and message_stop, and may return an error event. Tool calls and results use native Messages tool_use / tool_result content blocks.

Both examples support streaming by setting stream: true (add -N when using curl). Read completion events and usage according to the selected protocol. Responses and Messages do not require the Chat Completions stream_options.include_usage field, and clients must not wait only for data: [DONE] to detect completion.

Common tool integrations

Review activity records

After a request completes, return to the Activity page in the Consumer console. You can review request time, model, status, Token usage, failure reason, and billing information there.

If you are debugging a third-party tool, first use curl or Skypool Playground to verify the same key and model, then migrate the same parameters into the tool configuration. This helps you quickly tell whether the issue is on the platform call path or in the tool-side configuration.

Common errors

SymptomCheck first
401 or authentication failureWhether the API Key was copied completely, and whether the request uses the Authorization: Bearer header
402 or insufficient balanceWhether the account has enough credits
404 or model not foundWhether model comes from the current platform model list
429 or rate limitingWhether concurrency is too high, and whether you need to lower concurrency or split requests across keys
5xx or node unavailableRetry later, and check the failure semantics in activity records
Tool keeps waitingWhether the streaming client correctly handles data: [DONE] and error events

Minimum onboarding checklist

  1. Log in to the console and create a Consumer API Key
  2. Choose a model ID from the Models page or /v1/models
  3. Set your OpenAI-compatible client's baseURL to https://a.skypool.xyz/v1
  4. Carry the API Key as a Bearer Token
  5. Verify the basic call with a non-streaming curl request first
  6. Then enable streaming output and tool calls
  7. Check status, usage, and failure reasons in activity records