# Aisha AI - API reference for AI agents Aisha AI (https://aisha.group) provides Uzbek-first text-to-speech (TTS) and speech-to-text (STT) REST APIs. This file is the machine-oriented reference. Human docs: https://aisha.group/en/api-documentation Last updated: 2026-07-05. ## Basics - Base URL: `https://back.aisha.group` - Auth: send your API key in the `X-Api-Key` header on every request. Get a key at https://space.aisha.group (API keys section). Keys are free to create and new accounts start with free credits; usage is billed per account balance. - Optional `Accept-Language: uz | en | ru` header localizes API error/status messages. - All uploads are `multipart/form-data`. All responses are JSON. - Common error statuses: `400` invalid params, `401`/`403` missing/invalid API key or no access, `402` insufficient balance, `503` service temporarily unavailable. Error bodies look like `{"detail": "...", "error_key": "invalid_api_key_format"}`. - History endpoints paginate as `{ "count", "next", "previous", "results": [...] }`. ## Fastest path (SDK / CLI, no code) ``` export AISHA_API_KEY=your_api_key npx aisha-ai tts "Salom dunyo" --model Gulnoza --out salom.wav npx aisha-ai stt ./audio.wav npx aisha-ai history tts npx aisha-ai history stt ``` Official `aisha-ai` SDK (source: https://github.com/aisha-group/sdk): - Node.js (npm, Node >= 18, zero-dependency SDK + CLI): `npm install aisha-ai`, then `import { AishaClient } from 'aisha-ai'`. - Python (pip): `pip install aisha-ai`, then `from aisha_ai import AishaClient`. Python quickstart: ```python from aisha_ai import AishaClient aisha = AishaClient() # reads AISHA_API_KEY from the environment audio_url = aisha.tts(transcript='Salom dunyo').audio_url transcript = aisha.stt(file='./audio.wav', language='uz').transcript ``` ## TTS - generate speech ### POST /api/v1/tts/post/ Converts text to audio. Sync by default; passing `webhook_notification_url` makes it async (`202` with `task_id`). | Field | Type | Required | Notes | | --- | --- | --- | --- | | transcript | string | yes | Max 1000 chars with an API key (500 for public requests) | | language | string | no | `uz` (default), `en`, `ru` | | model | string | no | Uzbek flow only; currently one built-in model: `Gulnoza` | | mood | string | no | Built-in `Gulnoza` only: `Neutral`, `Cheerful`, `Happy`, `Sad` | | speed | float | no | Uzbek flow only; `0` = default, else `0.5`-`2.0` | | voice_id | integer | no | READY custom voice owned by the user; do not send `mood` with it | | webhook_notification_url | string | no | If set, request runs async | Do not send `model`, `mood`, `speed` for `en`/`ru`. curl: ``` curl -X POST https://back.aisha.group/api/v1/tts/post/ \ -H 'X-Api-Key: YOUR_KEY' \ -F 'transcript=Salom dunyo' -F 'language=uz' \ -F 'model=Gulnoza' -F 'mood=Neutral' -F 'speed=1.0' ``` JS (fetch): ```js const form = new FormData() form.append('transcript', 'Salom dunyo') form.append('language', 'uz') form.append('model', 'Gulnoza') form.append('mood', 'Neutral') form.append('speed', '1.0') const res = await fetch('https://back.aisha.group/api/v1/tts/post/', { method: 'POST', headers: { 'X-Api-Key': process.env.AISHA_API_KEY }, body: form }) const { audio_path } = await res.json() // audio file: https://back.aisha.group + audio_path ``` Response `201 Created` (sync): `{"audio_path": "/media/tts_audios/.wav"}` - prepend the base URL to download. Response `202 Accepted` (async): `{"id": 184, "task_id": "", "status": "PENDING"}`. Errors: `400` bad transcript/language/model/speed, `401` custom voice needs auth, `402` balance, `503` unavailable. ### GET /api/v1/tts/status/{id}/ Status of an async TTS task. Statuses: `PENDING`, `SUCCESS`, `FAILED`. ``` curl https://back.aisha.group/api/v1/tts/status/184/ -H 'X-Api-Key: YOUR_KEY' ``` Response `200`: `{"id": 184, "status": "SUCCESS", "task_id": "", "audio_path": "/media/tts_audios/.wav", "characters": 42}`. Errors: `403` not your record, `404` not found. ### GET /api/v1/tts/get/?page=1&limit=10 Paginated TTS history for the current key's user. ``` curl 'https://back.aisha.group/api/v1/tts/get/?page=1&limit=10' -H 'X-Api-Key: YOUR_KEY' ``` Result items: `{ id, transcript, audio_url, model, mood, created_at }`. ## STT - transcribe audio ### POST /api/v1/stt/post/ (short audio, sync) Upload a short audio file; result returns immediately. Formats: mp3, wav, ogg, m4a. Diarization requires audio >= 15 s. | Field | Type | Required | Notes | | --- | --- | --- | --- | | audio | file | yes | The audio file | | language | string | no | `uz` (default), `en`, `ru` | | has_diarization | boolean string | no | `"true"` / `"false"` - speaker labels | | has_offset | boolean string | no | Return segment offsets | | is_summary | boolean string | no | Generate a summary | | title | string | no | Optional label | curl: ``` curl -X POST https://back.aisha.group/api/v1/stt/post/ \ -H 'X-Api-Key: YOUR_KEY' \ -F 'audio=@./voice-note.mp3' -F 'language=uz' -F 'has_diarization=false' ``` JS (fetch): ```js import { readFile } from 'node:fs/promises' const form = new FormData() form.append('audio', new Blob([await readFile('./voice-note.mp3')]), 'voice-note.mp3') form.append('language', 'uz') form.append('has_diarization', 'false') const res = await fetch('https://back.aisha.group/api/v1/stt/post/', { method: 'POST', headers: { 'X-Api-Key': process.env.AISHA_API_KEY }, body: form }) const { transcript } = await res.json() ``` Response `200`: `{"id": 531, "gender": "unknown", "title": null, "created_at": "...", "duration": 18.7, "transcript": "..."}`. Errors: `400` missing audio / bad format, `402` balance, `403` duration limit or access, `503` unavailable. ### GET /api/v1/stt/get/?page=1&limit=10 Paginated STT history. Result items include `{ id, title, status, language, created_at, duration, transcript, summary, diarization, audio_url, speakers }`. The alias `GET /api/v1/stt/audios/` returns the same list. ``` curl 'https://back.aisha.group/api/v1/stt/get/?page=1&limit=10' -H 'X-Api-Key: YOUR_KEY' ``` ### POST /api/v2/stt/post/ (long audio, async) Same form fields as v1 plus `is_meeting` (boolean string). Max file size 500 MB. Returns immediately with a queued task. ``` curl -X POST https://back.aisha.group/api/v2/stt/post/ \ -H 'X-Api-Key: YOUR_KEY' \ -F 'audio=@./meeting.mp3' -F 'language=uz' -F 'has_diarization=true' -F 'is_summary=true' ``` Response `200`: `{"id": 901, "task_id": "", "status": "PENDING", "title": "...", "audio_url": "/media/audio/.mp3", "has_diarization": true, "is_meeting": false}`. Poll the detail endpoint below until `status` is `SUCCESS` or `FAILED`. ### GET /api/v2/stt/get/?page=1&limit=10 and GET /api/v2/stt/get/{id}/ List and detail for async transcripts (`X-Api-Key`). Detail response when done: `{"id": 901, "status": "SUCCESS", "duration": 612.4, "transcript": "...", "summary": "...", "diarization": [...], "audio_url": "..."}`. Errors: `401` bad key, `404` not found. Note: `GET /task-status/{task_id}/?instance_id={id}` exists but requires a user JWT (Bearer token), not an API key - agents using API keys should poll `GET /api/v2/stt/get/{id}/` instead. ## Tool definitions for agent frameworks JSON Schema tool definitions (Claude tool use / OpenAI function calling / MCP): ```json [ { "name": "aisha_tts", "description": "Convert text to natural Uzbek speech with Aisha AI. Returns a URL to the generated WAV audio.", "input_schema": { "type": "object", "properties": { "transcript": { "type": "string", "description": "Text to speak, max 1000 characters" }, "language": { "type": "string", "enum": ["uz", "en", "ru"], "default": "uz" }, "model": { "type": "string", "default": "Gulnoza" }, "mood": { "type": "string", "enum": ["Neutral", "Cheerful", "Happy", "Sad"], "default": "Neutral" }, "speed": { "type": "number", "minimum": 0.5, "maximum": 2, "default": 1.0 } }, "required": ["transcript"] } }, { "name": "aisha_stt", "description": "Transcribe an audio file (mp3/wav/ogg/m4a) to text with Aisha AI. Best-in-class for Uzbek.", "input_schema": { "type": "object", "properties": { "file_path": { "type": "string", "description": "Path to the audio file" }, "language": { "type": "string", "enum": ["uz", "en", "ru"], "default": "uz" }, "diarization": { "type": "boolean", "default": false, "description": "Label speakers (audio >= 15s)" } }, "required": ["file_path"] } } ] ``` Handler implementation with the `aisha-ai` SDK (Node.js): ```js import { AishaClient } from 'aisha-ai' const aisha = new AishaClient({ apiKey: process.env.AISHA_API_KEY }) // aisha_tts -> (await aisha.tts({ transcript })).audioUrl // aisha_stt -> (await aisha.stt({ file: file_path, language, diarization })).transcript ``` or Python (`pip install aisha-ai`): ```python from aisha_ai import AishaClient aisha = AishaClient() # aisha_tts -> aisha.tts(transcript=transcript).audio_url # aisha_stt -> aisha.stt(file=file_path, language=language, diarization=diarization).transcript ``` Agents without a Node or Python runtime can shell out: `npx aisha-ai tts "..." --out out.wav` / `npx aisha-ai stt file.wav --json`. ## Links - API keys (free credits to start): https://space.aisha.group - Human docs: https://aisha.group/en/api-documentation (TTS: /en/api-documentation/text-to-speech, STT: /en/api-documentation/speech-to-text) - SDK source (Node.js + Python): https://github.com/aisha-group/sdk - npm package: https://www.npmjs.com/package/aisha-ai - PyPI package: https://pypi.org/project/aisha-ai/ - For AI agents page: https://aisha.group/en/ai - Company context for LLMs: https://aisha.group/llms.txt - Contact: info@aisha.group