Open in the interactive docs · markdown for agents: https://neuraldeep.tech/docs/speechcore.md

SpeechCore · audio/video transcription

A separate service speechcore.neuraldeep.tech — transcription of long audio and video (files up to 2 GB): speaker diarization, word-level timecodes, export to SRT/VTT/TSV/DOCX/PDF. On the web — sign in with the same Hub account; via API — with the same sk-* key as for /v1/*. For short audio and OpenAI compatibility there's also the synchronous whisper-1 (the "Transcription" section above) — while SpeechCore is tailored for long recordings and diarization.

API base — https://speechcore.neuraldeep.tech/api (NOT api.neuraldeep.tech). The limit is counted in transcriptions per day; a key sees its remainder in GET /usage (used_today, daily_limit, remaining). Beyond the limit an upload still goes through, billed per minute, if the wallet has money. Otherwise you get 429 saying when it resets ("Resets at 00:00 UTC (03:00 Moscow time).") and a Retry-After header until midnight UTC. Works asynchronously: POST /upload → {task_id} → poll GET /transcriptions/{id}/status until status=completed → fetch the result: GET /transcriptions/{id} (JSON with segments, speakers, detected_language, duration) or GET /transcriptions/{id}/markdown (text with timecodes).

Transcription options — query parameters for POST /upload (the file goes in the multipart body, options in the URL):

POST /upload errors. task_id comes only with a 200, so check the status first. An error body is {"detail": "..."} with the reason: 400 — unsupported file format (accepted: wav, flac, aiff, mp3, m4a, aac, ogg, oga, opus, wma, amr, mp4, m4v, mov, avi, mkv, webm, wmv, flv, 3gp, mpg, mpeg, ts), 401 — the key is wrong or revoked, 422 — a parameter out of range (e.g. diarize_speakers_num not in 1–20), 429 — the daily limit is used up and the wallet is empty, 503 — the service is temporarily unavailable, retry later.

# options in the URL query string, file in the multipart body (-F)
curl -s "https://speechcore.neuraldeep.tech/api/upload?diarize=true&diarize_speakers_num=3&language=ru&hotwords=NeuralDeep,Kimi,RAG&initial_prompt=A%20technical%20call%20about%20LLM" \
  -H "Authorization: Bearer $YOUR_KEY" \
  -F "[email protected]"
# 1. upload (the same sk-key as for /v1/*)
tid=$(curl -s https://speechcore.neuraldeep.tech/api/upload \
  -H "Authorization: Bearer $YOUR_KEY" \
  -F "[email protected]" | jq -r .task_id)

# 2. status
curl "https://speechcore.neuraldeep.tech/api/transcriptions/$tid/status" \
  -H "Authorization: Bearer $YOUR_KEY"

# 3. result as text (markdown with timecodes)
curl "https://speechcore.neuraldeep.tech/api/transcriptions/$tid/markdown" \
  -H "Authorization: Bearer $YOUR_KEY"

# your transcriptions as a list
curl "https://speechcore.neuraldeep.tech/api/transcriptions?limit=20" \
  -H "Authorization: Bearer $YOUR_KEY"
import time, httpx

BASE = "https://speechcore.neuraldeep.tech/api"
H = {"Authorization": "Bearer $YOUR_KEY"}

# 1. upload a file (audio/video, up to 2 GB) + options in params
params = {
    "diarize": "true",            # speaker separation
    "diarize_speakers_num": 3,    # if the number of voices is known
    "language": "ru",
    "hotwords": "NeuralDeep, Kimi, RAG",          # special words/terms
    "initial_prompt": "A technical call about LLM",
}
with open("meeting.mp3", "rb") as f:
    r = httpx.post(f"{BASE}/upload", headers=H, params=params, files={"file": f}, timeout=300)
# task_id comes only with a 200; an error body is {"detail": "..."} with the reason
if r.status_code != 200:
    raise RuntimeError(f"upload {r.status_code}: {r.text}")
tid = r.json()["task_id"]

# 2. polling (every couple of seconds)
while True:
    st = httpx.get(f"{BASE}/transcriptions/{tid}/status", headers=H)
    st.raise_for_status()
    st = st.json()
    if st["status"] in ("completed", "failed"):
        break
    time.sleep(2)

# 3. result: segments + timecodes, or ready markdown
data = httpx.get(f"{BASE}/transcriptions/{tid}", headers=H).json()
print("language:", data["detected_language"], "duration:", data["duration"])
print(httpx.get(f"{BASE}/transcriptions/{tid}/markdown", headers=H).text)

Web-interface features (speechcore.neuraldeep.tech), beyond the API:

Polling and fetching the result don't consume the limit — it's spent only at upload (1 file = 1 transcription). Files up to 2 GB, the upload has to finish within 30 minutes; upload large files whole — processing runs in the background on GPU, so keep a reasonable timeout on polling. Diarization and special words work the same in the web and via the API.

Reference sections (markdown for agents)