Aisha AI
by voicelab

STT API

Speech-to-Text endpointlari. Server integratsiya uchun har bir so'rovda X-Api-Key header yuboring.

API key olish Jamoa bilan bog‘lanish Base URL https://back.aisha.group
API v1 API v2 Realtime STT

Overview #

  1. 1 Qisqa audio uchun POST /api/v1/stt/post/ (sync).
  2. 2 Uzun audio uchun POST /api/v2/stt/post/ (async, task_id qaytadi).
  3. 3 Realtime audio uchun wss://back.aisha.group/api/v1/stt/realtime WebSocket ishlating.
  4. 4 WebSocket bitta connection ichida davomli session uchun ishlatiladi; tugatish uchun {"event":"end"} yuboring.
  5. 5 Server streaming integratsiyasi uchun back.aisha.group:443 gRPC endpoint mavjud, lekin har Transcribe chaqiruvi bitta audio oqimi uchun.

CLI qulayroqmi? aisha-ai npm paketi shu endpointlarni o‘rab beradi: npx aisha-ai tts / npx aisha-ai stt. npm’dagi aisha-ai

API Key #

  • API Key

    X-Api-Key: <api_key>

    Server-to-server integratsiya uchun tavsiya qilinadi.

  • Streaming token

    ?token=<token>

    Realtime WebSocket uchun token query parametrida yuboriladi.

Qisqa audio transkripsiya #

POST https://back.aisha.group/api/v1/stt/post/

Qisqa audio faylni yuborasiz va natija darhol qaytadi (sync).

Autentifikatsiya: X-Api-Key yuboring. Public so‘rovlar reCAPTCHA talab qilishi mumkin.

  • Audio formatlar: mp3, wav, ogg, m4a (server tomonda tekshiriladi).
  • Diarization yoqilsa audio kamida 15 soniya bo‘lishi kerak.

So‘rov maydonlari #

audio majburiy

file

Audio fayl.

Misol: voice-note.mp3

language

string

Supported: uz, en, ru. Default: uz.

Misol: uz

has_diarization

boolean string

Speaker diarization flagi.

Misol: false

has_offset

boolean string

Offset segmentlar qaytishi uchun.

Misol: false

is_summary

boolean string

Summary yaratish flagi.

Misol: false

title

string

Ixtiyoriy nom.

Misol: meeting-voice-note

Misollar #

v1 POST

curl --request POST \
  --url https://back.aisha.group/api/v1/stt/post/ \
  --header 'X-Api-Key: your_api_key' \
  --header 'Accept-Language: uz' \
  --form 'audio=@/path/to/voice-note.mp3' \
  --form 'language=uz' \
  --form 'has_diarization=false'

CLI (aisha-ai)

export AISHA_API_KEY=your_api_key
npx aisha-ai stt ./audio.wav

Javoblar #

200 OK

Success

{
  "id": 531,
  "gender": "unknown",
  "title": null,
  "created_at": "2026-05-04T10:12:43.212Z",
  "duration": 18.7,
  "transcript": "Assalomu alaykum, bu qisqa audio transkripsiyasi."
}

Status kodlari #

200

Natija qaytdi.

400

Audio yo'q yoki format noto'g'ri.

402

Balans yetarli emas.

403

Duration limiti yoki access muammosi.

503

STT servis vaqtincha unavailable.

v1 history ro'yxati #

GET https://back.aisha.group/api/v1/stt/get/?page=1&limit=10

Userga tegishli transkriptlar ro‘yxatini paginatsiya bilan qaytaradi.

Autentifikatsiya: X-Api-Key talab qilinadi.

  • /api/v1/stt/audios/ alias endpointi ham mavjud.

Misollar #

v1 GET history

curl --request GET \
  --url 'https://back.aisha.group/api/v1/stt/get/?page=1&limit=10' \
  --header 'X-Api-Key: your_api_key'

Javoblar #

200 OK

Paginated success

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 531,
      "title": null,
      "gender": "unknown",
      "status": "SUCCESS",
      "language": "uz",
      "created_at": "2026-05-04T10:12:43.212Z",
      "duration": 18.7,
      "transcript": "Assalomu alaykum, bu qisqa audio transkripsiyasi.",
      "summary": "",
      "diarization": [],
      "audio_url": "/media/audio/f35f6c3a.wav",
      "speakers": []
    }
  ]
}

Status kodlari #

200

History qaytdi.

403

API key noto'g'ri yoki yuborilmagan.

Uzun audio async transkripsiya #

POST https://back.aisha.group/api/v2/stt/post/

Uzun audio fayl yuborasiz. Javobda task_id va PENDING status qaytadi.

Autentifikatsiya: X-Api-Key talab qilinadi.

  • Max file size: 500MB.

So‘rov maydonlari #

audio majburiy

file

Audio fayl.

Misol: meeting-record.mp3

language

string

Default: uz.

Misol: uz

has_diarization

boolean string

Speaker diarization flagi.

Misol: true

has_offset

boolean string

Offset flagi.

Misol: false

is_summary

boolean string

Summary flagi.

Misol: true

is_meeting

boolean string

Meeting mode flagi.

Misol: false

title

string

Ixtiyoriy nom.

Misol: sales-call

Misollar #

v2 POST

curl --request POST \
  --url https://back.aisha.group/api/v2/stt/post/ \
  --header 'X-Api-Key: your_api_key' \
  --form 'audio=@/path/to/meeting-record.mp3' \
  --form 'language=uz' \
  --form 'has_diarization=true' \
  --form 'is_summary=true'

Javoblar #

200 OK

Queued

{
  "id": 901,
  "has_diarization": true,
  "is_meeting": false,
  "task_id": "66e92db4-95cf-4bb9-acbc-49462039d19f",
  "status": "PENDING",
  "title": "sales-call-13-aprel",
  "audio_url": "/media/audio/273bc5f8-1f91-4573-b3df-3c38c44294d0.mp3"
}

Status kodlari #

200

Task yaratildi.

400

Audio yo'q yoki file juda katta.

401

API key yuborilmagan yoki noto'g'ri.

403

Balans yoki access xatosi.

500

Ichki xato.

Realtime WebSocket transkripsiya #

WS wss://back.aisha.group/api/v1/stt/realtime?format=webm&token=YOUR_API_KEY

Mikrofon yoki audio stream chunklarini WebSocket orqali yuborasiz. Server session_started, transcription va error JSON xabarlarini qaytaradi.

Autentifikatsiya: token query parametrida yuboriladi. Ulanishdan oldin balans tekshiriladi.

  • format=webm: browser MediaRecorder yuboradigan audio/webm;codecs=opus chunklari uchun.
  • format=pcm: raw PCM stream uchun. Format aniq: 16 kHz, mono, signed 16-bit little-endian (s16le).
  • Raw Opus frame yubormang; browser uchun Opus WebM konteyner ichida yuboriladi.
  • Bitta WebSocket connectionni bir nechta audio chunk va bir nechta speech segment uchun ochiq ushlab turish mumkin.
  • Stream tugaganda text message sifatida {"event":"end"} yuboring.

So‘rov maydonlari #

token majburiy

string

API key.

Misol: YOUR_API_KEY

format

string

Supported: webm, pcm. Default: webm.

Misol: webm

binary chunks majburiy

bytes

WebSocket orqali yuboriladigan audio bytes.

Misol: audio/webm chunk

Misollar #

Browser WebM/Opus stream

const token = 'your_api_key'
const ws = new WebSocket(
  `wss://back.aisha.group/api/v1/stt/realtime?format=webm&token=${encodeURIComponent(token)}`
)

ws.onmessage = event => {
  const message = JSON.parse(event.data)
  if (message.type === 'transcription') {
    console.log(message.text, message.partial, message.consumed_audio_seconds)
  }
}

const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm;codecs=opus' })

recorder.ondataavailable = async event => {
  if (event.data.size > 0 && ws.readyState === WebSocket.OPEN) {
    ws.send(await event.data.arrayBuffer())
  }
}

// Bitta connection ichida audio chunk'larni uzluksiz yuborish mumkin.
// Har session oxirida faqat bir marta end event yuboring.
recorder.start(250)

// Stop when the user finishes speaking.
// recorder.stop()
// ws.send(JSON.stringify({ event: 'end' }))

Raw PCM stream

import asyncio
import websockets

TOKEN = "your_api_key"
URL = f"wss://back.aisha.group/api/v1/stt/realtime?format=pcm&token={TOKEN}"

async def stream_pcm():
    async with websockets.connect(URL, max_size=None) as ws:
        async def reader():
            async for message in ws:
                print(message)

        reader_task = asyncio.create_task(reader())
        with open("audio.s16le", "rb") as audio:
            while chunk := audio.read(3200):
                await ws.send(chunk)
                await asyncio.sleep(0.1)

        await ws.send('{"event":"end"}')
        await reader_task

asyncio.run(stream_pcm())

Javoblar #

message

Session started

{
  "type": "session_started",
  "session_id": "7ab6d67a-9a29-4ad9-90b7-d2f5b2fc08fb",
  "user_id": "42",
  "allowed_audio_seconds": 1280,
  "format": "webm"
}
message

Transcript

{
  "type": "transcription",
  "session_id": "7ab6d67a-9a29-4ad9-90b7-d2f5b2fc08fb",
  "text": "Assalomu alaykum, buyurtmam holatini tekshirib bering.",
  "partial": false,
  "segment_event": "end",
  "consumed_audio_seconds": 4.32
}
message

Error

{
  "type": "error",
  "code": "insufficient_balance",
  "message": "Balance limit reached",
  "session_id": "7ab6d67a-9a29-4ad9-90b7-d2f5b2fc08fb"
}

Status kodlari #

1000

Stream normal yopildi.

1008

Token, balans yoki format xatosi.

1011

Server streamni qayta ishlay olmadi.

gRPC streaming transkripsiya #

gRPC back.aisha.group:443/aisha.stt.RealtimeSTT/Transcribe

Backend servislar audio bytes streamini gRPC orqali yuborib, yakunda transcript, segmentlar va timing natijasini oladi.

Autentifikatsiya: Gateway orqali berilgan token/API access bilan ishlatiladi.

  • Audio bytes odatiy audio fayl formatida yuboriladi: wav, mp3, m4a, ogg yoki webm.
  • Birinchi chunkda first=true va language yuboring. Keyingi chunklarda faqat audio_chunk yetarli.
  • Bitta gRPC channelni qayta ishlatish mumkin, lekin har transcribe uchun yangi Transcribe RPC boshlanadi.
  • Response ichida userga kerakli maydonlar: text, language, duration, audio_bytes, segments, timings.

So‘rov maydonlari #

audio_chunk majburiy

bytes

Audio stream bo‘lagi.

Misol: 32000 bytes

language

string

Supported: uz, ru, en. Birinchi chunkda yuboriladi.

Misol: uz

first

boolean

Birinchi chunkni belgilaydi.

Misol: true

Misollar #

Python gRPC stream

import grpc
import stt_pb2
import stt_pb2_grpc

channel = grpc.secure_channel("back.aisha.group:443", grpc.ssl_channel_credentials())
client = stt_pb2_grpc.RealtimeSTTStub(channel)

def chunks(path):
    with open(path, "rb") as audio:
        first = True
        while data := audio.read(32000):
            yield stt_pb2.TranscribeChunk(
                audio_chunk=data,
                language="uz" if first else "",
                first=first,
            )
            first = False

def transcribe(path):
    response = client.Transcribe(chunks(path))
    print(response.text)
    for segment in response.segments:
        print(segment.start, segment.end, segment.text)

# Channel reuse mumkin, lekin har audio/utterance uchun alohida Transcribe RPC ochiladi.
transcribe("audio.wav")
transcribe("another.wav")

Javoblar #

OK

Transcript

{
  "text": "Assalomu alaykum, buyurtmam holatini tekshirib bering.",
  "language": "uz",
  "duration": 4.32,
  "audio_bytes": 138240,
  "segments": [
    {
      "start": 0.0,
      "end": 4.32,
      "text": "Assalomu alaykum, buyurtmam holatini tekshirib bering."
    }
  ],
  "timings": {
    "transcribe_sec": 0.74,
    "total_sec": 0.82
  }
}

Status kodlari #

OK

Transcript qaytdi.

INVALID_ARGUMENT

Audio stream bo‘sh yoki noto‘g‘ri.

UNAUTHENTICATED

Token/API access qabul qilinmadi.

v2 history ro'yxati #

GET https://back.aisha.group/api/v2/stt/get/

Async transkriptlarni paginatsiya bilan history ro‘yxati.

Autentifikatsiya: X-Api-Key talab qilinadi.

  • Detail uchun alohida endpoint: GET /api/v2/stt/get/{id}/.

Misollar #

v2 history

curl --request GET \
  --url 'https://back.aisha.group/api/v2/stt/get/?page=1&limit=10' \
  --header 'X-Api-Key: your_api_key'

Javoblar #

200 OK

History

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 901,
      "title": "sales-call-13-aprel",
      "status": "PENDING",
      "created_at": "2026-05-04T10:39:58.501Z",
      "duration": null,
      "audio_url": "/media/audio/273bc5f8-1f91-4573-b3df-3c38c44294d0.mp3"
    }
  ]
}

Status kodlari #

200

History yoki detail qaytdi.

401

API key yuborilmagan yoki noto'g'ri.

404

Transcript topilmadi.

v2 transcript detail #

GET https://back.aisha.group/api/v2/stt/get/{id}/

Bitta async transkript yozuvining holati va natijasini qaytaradi.

Autentifikatsiya: X-Api-Key talab qilinadi.

  • Status SUCCESS bo'lganda transcript natijasi qaytadi.

Misollar #

v2 detail

curl --request GET \
  --url https://back.aisha.group/api/v2/stt/get/901/ \
  --header 'X-Api-Key: your_api_key'

Javoblar #

200 OK

Completed

{
  "id": 901,
  "title": "sales-call-13-aprel",
  "status": "SUCCESS",
  "created_at": "2026-05-04T10:39:58.501Z",
  "duration": 612.4,
  "transcript": "Uzoq meeting transcript matni...",
  "summary": "Qisqa summary...",
  "diarization": [],
  "audio_url": "/media/audio/273bc5f8-1f91-4573-b3df-3c38c44294d0.mp3"
}

Status kodlari #

200

Detail qaytdi.

401

API key yuborilmagan yoki noto'g'ri.

404

Transcript topilmadi.

Task status polling #

GET https://back.aisha.group/task-status/{task_id}/?instance_id={id}

Async task holatini tekshiradi. instance_id ownership tekshiruv uchun majburiy.

Autentifikatsiya: X-Api-Key yoki user access token talab qilinadi.

  • Statusni olish uchun task instance_id qiymati bilan bog‘langan bo‘lishi kerak.

Misollar #

task-status

curl --request GET \
  --url 'https://back.aisha.group/task-status/task-123/?instance_id=944' \
  --header 'X-Api-Key: your_api_key'

Javoblar #

200 OK

Pending

{
  "task_id": "task-123",
  "status": "PENDING",
  "transcript_status": "PENDING",
  "message": "Task is still processing"
}
200 OK

Success

{
  "task_id": "task-123",
  "status": "SUCCESS",
  "transcript_status": "SUCCESS",
  "result": {
    "transcript": "Hello world"
  }
}

Status kodlari #

200

Task holati qaytdi.

400

instance_id yo'q.

403

Access rad etildi.

500

Task failed yoki unknown state.