We've written our own client libraries for PHP (>= 7.4) and Python (>= 3.10, sync and async) for the SiteHost AI service. Our API is OpenAI/Cohere compatible - existing clients keep working - but these give you a single, lightweight dependency for the whole API. They also work more or less the same against any vLLM backend, so you can point them at your own.
Install with composer for PHP (published as sitehostnz/sthai) or pip/uv for Python (published as sthai):
composer require sitehostnz/sthai
pip install sthai
The two libraries share an interface as closely as PHP and Python allow. Check the relevant README for implementation details and client-specific quirks:
API keys are created in the SiteHost Control Panel - see API keys. The client picks one up from the STHAI_KEY environment variable, or takes it explicitly.
Everything the platform serves (see the models page for the current line-up):
Qwen/Qwen3.6-27B - multimodal, thinking, 262K context): multi-turn conversations with stored history, one-off responses, thinking/reasoning, image inputs, and structured responses with server-enforced JSON schemas.Qwen/Qwen3-VL-Embedding-8B - multimodal, Matryoshka-trained, 4096 dimensions): single and batch, text and/or images, query-vs-document instructions for retrieval, and server-side dimension truncation.Qwen/Qwen3-VL-Reranker-8B - multimodal, instruction-trained): score documents against a query, sorted by relevance, with optional instruction steering and top-N.Plus health checks and a model list (which doubles as an auth check).
chat() calls record the conversation, and it's fully accessible - read it out, restore it into a fresh client, toggle recording, or sum the token usage that built it. Note that state is in-memory only: in per-request environments (like a PHP page request) persist the history yourself, or disable it and build full context into each call.usage() and output(); PHP adds toArray() for the full payload, and Python responses are typed msgspec structs throughout.AsyncClient mirrors Client method-for-method - ideal for fanning out embed() or rerank() calls with asyncio.gather.SthAI\Exception\SthAIException / sthai.SthaiError) covers everything the client can raise, with specific subtypes (input guards, transport, HTTP 4xx/5xx with parsed server errors, response/parse failures) when you want them.