- Add /shutdown endpoint for graceful server shutdown - Add 'aha ps' command to list running services - Add comprehensive API documentation for shutdown endpoint - Enhance CLI with --allow-remote-shutdown flag - Implement process management module with service discovery - Add graceful shutdown handling for Ctrl+C signals
12 KiB
API Reference
Complete reference for the AHA REST API.
Overview
AHA provides an OpenAI-compatible REST API for running AI model inference. All endpoints follow standard HTTP conventions and return JSON responses.
Base URL
By default, the API server runs on:
http://127.0.0.1:10100
You can customize this when starting the service:
aha cli -m qwen3-0.6b -a 0.0.0.0 -p 8080
Authentication
Currently, AHA does not require authentication. All endpoints are publicly accessible on the configured address/port.
Security Note: If you expose the API to external networks, consider implementing authentication through a reverse proxy (e.g., nginx, traefik).
Content Types
All requests should use:
Content-Type: application/json
Response Format
Success responses follow this structure:
{
"data": { ... },
"model": "model-name",
"usage": {
"total_tokens": 30
}
}
Error responses:
{
"error": {
"message": "Error description",
"type": "error_type",
"code": "error_code"
}
}
Endpoints
Health Check
Check the service health status. This endpoint is useful for container orchestration (Kubernetes), load balancers, and monitoring systems.
Endpoint
GET /health
Response
Healthy (HTTP 200):
{
"status": "ok"
}
Unhealthy (HTTP 503):
{
"status": "unhealthy",
"error": "model not initialized"
}
Example
curl http://127.0.0.1:10100/health
Models
Get information about the currently loaded model (OpenAI API compatible format).
Endpoint
GET /models
Response
Success (HTTP 200):
{
"object": "list",
"data": [
{
"id": "qwen3-0.6b",
"object": "model",
"created": null,
"owned_by": "Qwen"
}
]
}
Not Initialized (HTTP 503):
{
"error": "model not initialized"
}
Fields
| Field | Type | Description |
|---|---|---|
object |
string | Fixed value: "list" |
data |
array | Array of model objects (currently contains one loaded model) |
id |
string | Model identifier in kebab-case (e.g., "qwen3-0.6b") |
object |
string | Fixed value: "model" |
created |
integer|null | Unix timestamp (currently null) |
owned_by |
string | Model owner/organization name |
Example
curl http://127.0.0.1:10100/models
Chat Completions
Generate chat completions or text responses.
Endpoint
POST /chat/completions
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Model identifier (e.g., "qwen3-0.6b") |
messages |
array | Yes | Array of message objects |
temperature |
number | No | Sampling temperature (0-2, default: 1) |
top_p |
number | No | Nucleus sampling (0-1, default: 1) |
max_tokens |
integer | No | Maximum tokens to generate |
stream |
boolean | No | Enable streaming (default: false) |
Message Object
| Field | Type | Required | Description |
|---|---|---|---|
role |
string | Yes | "system", "user", or "assistant" |
content |
string/array | Yes | Message content (string or multimodal array) |
Multimodal Content
For vision/audio models, content can be an array:
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image", "image_url": {"url": "file:///path/to/image.jpg"}}
]
}
Supported content types:
text- Text contentimage_url- Image file (file://, base64://, https:// or http://)audio_url- Audio file (file://, base64://, https:// or http://)
Examples
Simple Chat:
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-0.6b",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
With System Message:
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-0.6b",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain Rust in one sentence."}
],
"max_tokens": 50,
"temperature": 0.7
}'
Vision Understanding:
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3vl-2b",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{"type": "image", "image_url": {"url": "file:///path/to/image.jpg"}}
]
}
]
}'
OCR (Text Extraction):
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-ocr",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Extract all text"},
{"type": "image", "image_url": {"url": "file:///path/to/document.png"}}
]
}
]
}'
ASR (Speech Recognition):
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "glm-asr-nano-2512",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this audio"},
{"type": "audio", "audio_url": {"url": "file:///path/to/audio.wav"}}
]
}
]
}'
Streaming Response:
curl http://127.0.0.1:10100/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-0.6b",
"messages": [
{"role": "user", "content": "Tell me a story"}
],
"stream": true
}'
Streaming responses are sent as Server-Sent Events (SSE):
data: {"id": "1", "choices": [{"delta": {"content": "Once"}}]}
data: {"id": "1", "choices": [{"delta": {"content": " upon"}}]}
data: [DONE]
Response
Non-streaming:
{
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677652288,
"model": "qwen3-0.6b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"total_tokens": 19
}
}
Supported Models
- Text:
qwen3-0.6b,minicpm4-0.5b - Vision:
qwen2.5vl-3b,qwen2.5vl-7b,qwen3vl-2b,qwen3vl-4b,qwen3vl-8b,qwen3vl-32b - OCR:
deepseek-ocr,hunyuan-ocr,paddleocr-vl - ASR:
glm-asr-nano-2512,fun-asr-nano-2512,qwen3asr-0.6b,qwen3asr-1.7b
Audio Speech
Generate speech from text (Text-to-Speech).
Endpoint
POST /audio/speech
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Model identifier (e.g., "voxcpm1.5") |
messages |
array | Yes | Array of message objects |
Example
curl http://127.0.0.1:10100/audio/speech \
-H "Content-Type: application/json" \
-d '{
"model": "voxcpm1.5",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Hello, this is AHA speaking."},
{"type": "audio", "audio_url": {"url": "https://package-release.coderbox.cn/aiway/test/other/%E5%93%AA%E5%90%92.wav"}}
]
}
]
}'
Response
Returns audio data in base64 WAV format.
Supported Models
voxcpm,voxcpm1.5
Images Remove Background
Remove background from images.
Endpoint
POST /images/remove_background
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Model identifier (e.g., "rmbg2.0") |
messages |
array | Yes | Array of message objects |
Example
From File:
curl http://127.0.0.1:10100/images/remove_background \
-H "Content-Type: application/json" \
-d '{
"model": "rmbg2.0",
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image_url": {"url": "file:///path/to/document.jpg"}}
]
}
]
}'
From Base64:
curl http://127.0.0.1:10100/images/remove_background \
-H "Content-Type: application/json" \
-d '{
"model": "rmbg2.0",
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image_url": {"url": "base64://$(base64 -w 0 photo.png)"}}
]
}
]
}'
Response
Returns the processed image in base64 PNG format.
Supported Models
rmbg2.0
Graceful Shutdown
Gracefully shut down the AHA server. This endpoint initiates a graceful shutdown process that:
- Stops accepting new connections
- Waits for existing requests to complete (up to 1 second)
- Cleans up PID files
- Exits the process
Endpoint
POST /shutdown
Request Body
None (empty request)
Response
Success (HTTP 200):
{
"message": "Shutting down..."
}
Forbidden (HTTP 403):
When remote shutdown is not allowed:
{
"error": "Remote shutdown not allowed. Use --allow-remote-shutdown flag to enable (not recommended)."
}
Security
By default, the shutdown endpoint only allows requests from localhost (127.0.0.1). To enable remote shutdown, start the server with the --allow-remote-shutdown flag:
aha serv -m qwen3-0.6b --allow-remote-shutdown
Warning: Enabling remote shutdown is not recommended for production use unless properly secured.
Example
curl -X POST http://127.0.0.1:10100/shutdown
Logging
All shutdown requests are logged to stderr with the format:
[SHUTDOWN] Shutdown requested (remote_allowed: false)
Error Handling
Error Codes
| Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters |
| 404 | Not Found - Model or endpoint not found |
| 500 | Internal Server Error - Model inference error |
| 503 | Service Unavailable - Model not loaded |
Error Response Format
{
"error": {
"message": "Model 'unknown-model' not found",
"type": "invalid_request_error",
"code": "model_not_found"
}
}
Rate Limiting
Currently, AHA does not implement rate limiting. The server can handle concurrent requests limited only by system resources.
File Upload Limits
- String data: 5 MB
- File uploads: 100 MB
OpenAI Compatibility
AHA's text generation API is designed to be compatible with OpenAI's API format. Multimodal APIs are derived from the text generation API with minimal changes:
Python Example
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:10100",
api_key="dummy" # Not used but required by library
)
response = client.chat.completions.create(
model="qwen3-0.6b",
messages=[
{"role": "user", "content": "Hello!"}
]
)
print(response.choices[0].message.content)
JavaScript Example
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://127.0.0.1:10100',
apiKey: 'dummy' // Not used but required
});
const response = await client.chat.completions.create({
model: 'qwen3-0.6b',
messages: [{ role: 'user', content: 'Hello!' }]
});
console.log(response.choices[0].message.content);
Best Practices
1. Use Streaming for Long Responses
For long text generation, use streaming to get responses incrementally:
curl ... -d '{"stream": true, ...}'
2. Set Appropriate Token Limits
Prevent excessively long responses:
{
"max_tokens": 500
}
3. Adjust Temperature
Control response creativity:
0.0-0.3: Deterministic, focused0.4-0.7: Balanced (default: 1.0)0.8-2.0: Creative, varied
4. Use System Messages
Set behavior with system messages:
{
"messages": [
{"role": "system", "content": "You are a technical writer."},
{"role": "user", "content": "..."}
]
}
See Also
- Getting Started - Quick start guide
- CLI Reference - Command-line usage
- Installation - Installation guide
- Development - Contributing guide