DeepSeek, Kimi, MiniMax and Zhipu GLM
Access Chinese and global models with platform credentials and Credits. Confirm publication, access and protocol support before calling a model. A family integration does not make every model, parameter or plan available.
Protocol coverage
| Model family | Chat Completions | Messages | Responses |
|---|---|---|---|
| DeepSeek | Compatibility path implemented | Compatibility path implemented | Compatibility path implemented |
| Kimi | Compatibility path implemented | Compatibility path implemented | Compatibility path implemented |
| MiniMax | Compatibility path implemented | Compatibility path implemented | Compatibility path implemented |
| Zhipu GLM | Compatibility path implemented | Compatibility path implemented | Not implemented |
This table describes integration coverage. Use each model's protocols, streaming flag and your entitlements in the public catalog. Chat maps to openai_chat_completions, Messages to anthropic_messages, and Responses to openai_responses. Do not call Responses for GLM or infer embeddings, image/video generation, native Gemini or token counting from a family name.
Credentials, base URL and discovery
- Use a platform API key on trusted servers and Embedded short-lived tokens on devices. Third-party keys, Coding Plan and subscription credentials are not platform API keys. Subscription authorization integration is not publicly available.
GET /api/v1/public/modelsreturns a{ code: 0, data: ... }envelope with protocols, capabilities and rates, without authentication. SDK 0.3.0listPublicModels()unwraps a typed catalog without reading or sending a token.- Authenticated
GET /v1/modelsorlistModels()returns available model IDs and does not return protocol details. Intersect the two catalogs by exact ID and check the required protocol. - Official SDKs use the API root without
/v1; the OpenAI SDK uses a Base URL ending in/v1. Pass the complete published ID or alias inmodel. Do not construct IDs from brand names.
Catalogs and entitlements can change; authorization, limits and model status are checked at request time.
Runnable HTTP example
Use Node.js 20+ and set API_BASE_URL (API root), AICREDITS_API_KEY and a catalog-listed MODEL. The example checks access and protocol support before sending a buffered Chat request. It does not hardcode production model names.
// Run on a trusted Node.js 20+ server.
const baseUrl = process.env.API_BASE_URL?.replace(/\/+$/, '')
const apiKey = process.env.AICREDITS_API_KEY
const model = process.env.MODEL
if (!baseUrl || !apiKey || !model) throw new Error('Set API_BASE_URL, AICREDITS_API_KEY and MODEL')
async function request(path, authenticated = false, body) {
const response = await fetch(baseUrl + path, {
method: body ? 'POST' : 'GET',
credentials: 'omit',
signal: AbortSignal.timeout(60_000),
headers: {
accept: 'application/json',
...(authenticated ? { authorization: `Bearer ${apiKey}` } : {}),
...(body ? { 'content-type': 'application/json' } : {}),
},
...(body ? { body: JSON.stringify(body) } : {}),
})
if (!response.ok) throw new Error(`HTTP ${response.status}`)
return response.json()
}
const envelope = await request('/api/v1/public/models')
if (envelope.code !== 0 || !Array.isArray(envelope.data?.items)) {
throw new Error('Invalid public catalog')
}
const allowed = await request('/v1/models', true)
const published = envelope.data.items.find(item => item.id === model)
if (!allowed.data?.some(item => item.id === model) ||
!published?.protocols?.includes('openai_chat_completions')) {
throw new Error('Choose an authorized model with Chat support')
}
const messages = [{ role: 'user', content: 'Hello' }]
const result = await request('/v1/chat/completions', true, { model, messages })
const assistant = result.choices?.[0]?.message
if (!assistant) throw new Error('Missing assistant message')
messages.push(assistant) // Retain reasoning_content, tool_calls and unknown fields.
// Render assistant.content in your application; do not log the full response.Official SDK 0.3.0
Run this TypeScript example on a trusted Node.js server. Follow source integration; packages have not been published to public registries.
import { GatewayClient, type ChatMessage } from '@ai-credits/platform-sdk'
const gateway = new GatewayClient({
baseUrl: process.env.API_BASE_URL!,
tokenProvider: { getToken: () => process.env.AICREDITS_API_KEY! },
})
const catalog = await gateway.listPublicModels()
const allowed = await gateway.listModels()
const model = process.env.MODEL!
if (!allowed.data.some(item => item.id === model) ||
!catalog.items.some(item => item.id === model &&
item.protocols.includes('openai_chat_completions'))) {
throw new Error('Select an authorized Chat model from the catalog')
}
const messages: ChatMessage[] = [{ role: 'user', content: 'Describe your capabilities' }]
const result = await gateway.createChatCompletion({ model, messages })
const assistant = result.choices[0]?.message
if (assistant) messages.push(assistant) // Keep reasoning_content, tool_calls and extensions.Swift and Kotlin expose the same discovery method. Choose modelID after validating it against both catalogs above. Supply your own keychainTokenStore / tokenStore; devices store only short-lived tokens.
let gateway = CreditPlatformGatewayClient(baseURL: baseURL, tokenStore: keychainTokenStore)
let catalog = try await gateway.listPublicModels()
let models = try await gateway.listModels()
let request = try JSONSerialization.data(withJSONObject: [
"model": modelID,
"messages": [["role": "user", "content": "Hello"]]
])
let result = try await gateway.createChatCompletion(request: request)
// Raw Data: preserve the complete assistant message for the next turn.val gateway = CreditPlatformGatewayClient(baseUrl, tokenStore)
val catalog = gateway.listPublicModels()
val models = gateway.listModels()
val request = mapper.valueToTree<com.fasterxml.jackson.databind.JsonNode>(
mapOf("model" to modelID, "messages" to listOf(
mapOf("role" to "user", "content" to "Hello")
))
)
val result = gateway.createChatCompletion(request)
// JsonNode: preserve the complete assistant message for the next turn.All three SDKs preserve model IDs, reasoning and tool fields. Catalog rates remain decimal strings.
Reasoning and multi-turn tools
Support and values for thinking and reasoning_effort vary by model. Start with default parameters, then enable reasoning according to the selected model's capabilities.
Chat reasoning_content and final content are separate fields; tool calls can have null content. Retain the complete assistant message, including reasoning, tool_calls and unknown extensions. Return tool results with matching tool_call_id and send the full context on the next turn. Your application validates and executes tools; the SDK does not execute tool code. Responses also requires explicit context; previous_response_id is unsupported.
Streaming and troubleshooting
TypeScript streamChatCompletion preserves raw SSE data. Accumulate delta.reasoning_content and delta.content separately. Assemble tool IDs, names and argument fragments by tool index; parse argument JSON only when complete. Handle in-stream errors and [DONE]; a disconnected network is not a successful completion. Swift and Kotlin currently support buffered calls only. See streaming.
- Unavailable model: check the public catalog,
/v1/modelsand entitlements again; do not guess or silently replace aliases. - Protocol or parameter errors: verify
protocols; use Chat or Messages for GLM and remove unsupported reasoning options. - 429: reduce request rate and concurrency following the rate-limit guide.
- Share only HTTP status, safe error codes and request IDs with support, without full payloads or credentials.
Next: protocols · OpenAI SDK migration · official SDKs