SDKs
The AIOZ AI SDKs are generated client libraries that wrap the HTTP API with idiomatic types and call signatures for each supported language. They handle authentication and request serialization for you, so most of your code can stay focused on what to do with model outputs rather than on the wire protocol.
This page covers what's available, how to install and configure each SDK, how the call shape works across languages, and how to handle errors and versioning. For the contract behind each individual call, see the API Reference.
For full version, please visit https://github.com/AIOZNetwork/aioz-ai-developer (opens in a new tab).
Available SDKs
There are three official SDKs today, one each for Python, Node.js / TypeScript, and Go. All three expose the same set of resources. The underlying concepts transfer across languages; you only translate naming conventions (snake_case ↔ camelCase ↔ PascalCase) and service-group names.
| Language | Package | Minimum runtime | Source |
|---|---|---|---|
| Python | aiozai-sdk (PyPI) | Python 3.9+ | https://pypi.org/project/aiozai-sdk/ (opens in a new tab) |
| Node / TS | @aiozai/nodejs-client (npm) | Node.js 18+ | https://www.npmjs.com/package/@aiozai/nodejs-client (opens in a new tab) |
| Go | github.com/AIOZNetwork/aioz-ai-go-client | Go 1.21+ | https://pkg.go.dev/github.com/AIOZNetwork/aioz-ai-go-client (opens in a new tab) |
If you'd prefer not to use an SDK (for languages we don't yet support, or because you need finer control over transport), every endpoint is also callable directly over HTTP. See the API Reference for the raw contracts.
Install
npm install @aiozai/nodejs-clientCreate a client
A client is the entry point to every call. Construct one with your API key; the same client instance is reusable across many calls, and is safe to share across an application's request handlers.
import { createAiozAIClient, type AiozAIClient } from "@aiozai/nodejs-client";
const { rawClient } = createAiozAIClient({
apiKey: process.env.AIOZ_AI_API_KEY,
});
// the bare hey-api `Client` type isn't exported; derive it when you need to annotate
type Client = AiozAIClient["rawClient"];
const client: Client = rawClient;
// every call takes { client, ... }Configuration options
The constructor accepts optional settings beyond the API key:
timeout(Python, seconds) /timeout(Node, milliseconds) /WithTimeout(Go): request timeout. Defaults are sensible for most workloads; raise this if you call long-running model endpoints.WithHTTPClient(Go only): provide a custom*http.Client, e.g. one that wraps a corporate proxy or adds custom transport-level instrumentation.
Pass timeout in milliseconds:
const { rawClient: client } = createAiozAIClient({
apiKey: process.env.AIOZ_AI_API_KEY,
timeout: 60_000,
});The resource map
The SDKs organize methods into service groups. Each service exposes the methods corresponding to that resource's HTTP endpoints.
Account / balance
| Node / TS | Python | Go |
|---|---|---|
services.core.getBalance({client}) | client.core.core.get_balance() | c.Core().Core.GetBalance(params, nil) |
Tasks
Every task operation, including create, lives on the tasks service group in all three languages.
| Operation | Node / TS | Python | Go |
|---|---|---|---|
| Create task | services.tasks.postModelByIdTask({client, path:{id}, body}) | client.tasks.task.post_model_by_id_task(id=, input={}) | c.Tasks().Task.PostModelByIDTask(params, nil) |
| Task detail | services.tasks.getTaskByIdDetail({client, path:{id}}) | client.tasks.task.get_task_by_id_detail(id=) | c.Tasks().Task.GetTaskByIDDetail(params, nil) |
| Task histories | services.tasks.getTaskHistories({client, query:{limit, offset}}) | client.tasks.task.get_task_histories(limit=, offset=) | c.Tasks().Task.GetTaskHistories(params, nil) |
| Cancel task | services.tasks.deleteTaskByIdCancel({client, path:{id}}) | client.tasks.task.delete_task_by_id_cancel(id=) | c.Tasks().Task.DeleteTaskByIDCancel(params, nil) |
Models
| Operation | Node / TS | Python | Go |
|---|---|---|---|
| List models | services.models.postModelList({client, body}) | client.models.model.post_model_list(RequestGetModelListRequest()) | c.Models().Model.PostModelList(params, nil) |
| Get model | services.models.getModelById({client, path:{id}}) | client.models.model.get_model_by_id(id=) | c.Models().Model.GetModelByID(params, nil) |
| Task cost | services.models.getModelByIdTaskCost({client, path:{id}}) | client.models.model.get_model_by_id_task_cost(id=) | c.Models().Model.GetModelByIDTaskCost(params, nil) |
| Serving status | services.models.getModelByIdServing({client, path:{id}}) | client.models.model.get_model_by_id_serving(id=) | c.Models().Model.GetModelByIDServing(params, nil) |
Python list call:
RequestGetModelListRequest()is a typed request object whose fields mirror the API body parameters (limit,offset,filter_by,sort, etc.). Construct it with keyword arguments to apply filters:RequestGetModelListRequest(limit=20, offset=0).
Storage
| Operation | Node / TS | Python | Go |
|---|---|---|---|
| Create presigned URL | services.storage.postStorageUploadCreatePresignedUrl({client, body:{folder, mime, name, size}}) | client.storage.storage.post_storage_upload_create_presigned_url(RequestCreatePresignedUrlRequest()) | c.Storage().Storage.PostStorageUploadCreatePresignedURL(params, nil) |
| Upload statistics | services.storage.getStorageUploadStatistics({client}) | client.storage.storage.get_storage_upload_statistics() | c.Storage().Storage.GetStorageUploadStatistics(params, nil) |
| List by folder | services.storage.getStorageUploadByFolder({client, path:{folder}, query:{page, pageSize, type}}) | client.storage.storage.get_storage_upload_by_folder(folder=, page=, page_size=) | c.Storage().Storage.GetStorageUploadByFolder(params, nil) |
| Delete file | services.storage.deleteStorageW3sUrl({client, body:{url}}) | client.storage.storage.delete_storage_w3s_url(RequestDeleteUrlRequest(url=)) | c.Storage().Storage.DeleteStorageW3sURL(params, nil) |
What the SDKs do for you
Compared to calling the HTTP endpoints directly with curl or a generic HTTP library, the SDKs take care of a few mechanical things so you don't have to:
-
Authentication. The
x-api-keyheader is added to every request automatically once you've passed the key to the constructor. -
Envelope passthrough with manual unwrap. The raw HTTP responses are wrapped in
{ "status": ..., "message": ..., "data": ... }. The SDKs do not strip this wrapper automatically. You unwrap the payload yourself, and the access path differs by language: in Node,resp.datais the envelope andresp.data.datais the payload; in Python,respis the envelope (resp.status,resp.message) andresp.datais the payload; in Go, readresp.Payload.Data. Task create nests the id one level deeper than other endpoints:resp.data.data.datain Node,resp.data.datain Python,resp.Payload.Data.Datain Go.resp = client.core.core.get_balance() print(resp.data) # the unwrapped balance payload -
Typed responses. Responses are deserialized into typed objects in each language's idiomatic style: dataclasses in Python, typed objects in TypeScript, structs in Go.
-
Typed errors. Failed requests raise a typed error (see Errors) carrying the HTTP status code and the server's message.
Errors
Every endpoint can fail, whether for network reasons, validation errors, or server-side issues. The SDKs surface failures as a single typed error per language, carrying the HTTP status code and the server's message verbatim.
Throws AiozApiError (imported from @aiozai/nodejs-client).
import { createAiozAIClient, services, AiozApiError } from "@aiozai/nodejs-client";
const { rawClient: client } = createAiozAIClient({ apiKey: process.env.AIOZ_AI_API_KEY });
try {
const resp = await services.tasks.getTaskByIdDetail({ client, path: { id: "does-not-exist" } });
} catch (e) {
if (e instanceof AiozApiError) {
console.log(e.statusCode, e.errorCode, e.message);
}
}For the meaning of HTTP status codes, retry guidance, and rate-limit-specific errors, see Errors, Rate Limits & Quotas.
Versioning and stability
All three SDKs are published, usable, and good enough to build against. Some refinements to the public interface may still happen as we work through real-world usage, so when you ship to production:
- Pin to an exact version in your dependency file (
requirements.txt/pyproject.toml,package.json,go.mod) rather than tracking the latest. That way you opt into upgrades when you're ready, not the day a release goes out.
The HTTP API itself is more conservative: breaking changes to endpoint paths, request bodies, or response shapes don't happen casually. If you've built directly against the HTTP layer, you generally don't have to pin or track changes as closely.
When to use the SDK vs the HTTP API
For most use cases, the SDK is the right choice: it removes mechanical work, gives you typed responses, and keeps your integration close to the official conventions. Reach for the raw HTTP API in a few situations:
- Your language isn't supported. If you're building in Ruby, Rust, Java, or anything else without an SDK, call the API directly. The contracts are stable enough to wrap yourself if you want.
- You need finer control over the transport. Custom retry logic, request-level instrumentation, response streaming, and integration with a specific HTTP framework are all easier on the raw API.
- You're scripting in a shell. A one-off
curlis faster to write and easier to share than a small script in Python or Node.
Even when using the raw HTTP API, the SDK source code is a useful reference for the conventions; see the source links above.