VoiceSuite

Nagranie rozmowy na wejściu.
Tekst, mówcy i parametry głosu na wyjściu.

Wysyłasz plik audio przez API. My robimy transkrypcję z dokładnym czasem, rozdzielamy mówców i oceniamy, jak brzmi każda wypowiedź. Gotowy wynik wysyłamy na Twój adres webhooka.

Poproś o token testowy

Co dostajesz

Transkrypcja z czasem

Każda wypowiedź z czasem początku i końca, wyrównana do słów. Język rozpoznajemy sami. Polski i angielski działają najlepiej.

Mówcy

Rozdzielamy, kto mówi kiedy. Jeśli znasz liczbę rozmówców, podaj ją w num_speakers, a podział będzie dokładniejszy.

Parametry głosu

  • emocja dominująca i jej pewność;
  • intensywność i emocje drugorzędne;
  • styl wypowiedzi;
  • prozodia: tempo, głośność, wysokość.

Emocja i parametry głosu to ocena modelu, nie fakt. Opisują, jak brzmi nagranie, a nie co czuje albo myśli mówca. Nie używaj ich jako jedynej podstawy decyzji o ludziach, na przykład w rekrutacji, ocenie pracownika albo ocenie wiarygodności.

Jak to działa

  1. Dostajesz token projektu i sekret webhooka. Wydajemy je ręcznie, jeden zestaw na projekt.
  2. Wysyłasz nagranie przez POST /v1/jobs razem z adresem callback_url, na który ma wrócić wynik.
  3. Nagranie trafia do silnika bez publicznego adresu. Łączy się z nim tylko nasza bramka API.
  4. Wynik przychodzi na Twój webhook, podpisany HMAC. Możesz go też pobrać z GET /v1/jobs/{id}/result.

API

Adres bazowy: https://voicesuite.health. Każde wywołanie /v1/jobs wymaga nagłówka Authorization: Bearer <token>.

Zlecenie

curl -X POST https://voicesuite.health/v1/jobs \
  -H "Authorization: Bearer vk_..." \
  -F "file=@rozmowa.m4a" \
  -F "callback_url=https://twoja-aplikacja.pl/webhooks/voice" \
  -F "job_ref=rozmowa-2026-11-06-01" \
  -F "num_speakers=2"

HTTP/1.1 202 Accepted
{"id": "3f2a…", "state": "queued"}
PoleOpis
fileWymagane. Do 100 MB. Formaty: mp3, wav, m4a, ogg, opus, flac, aac, wma, webm, mp4, mov, mkv, amr, 3gp.
callback_urlWymagane. Tylko https i tylko publiczny adres. Adresy prywatne, lokalne i z loginem w URL odrzucamy.
job_refOpcjonalne. Twój identyfikator, do 80 znaków A–Z a–z 0–9 . _ : -. Ponowne wysłanie z tym samym job_ref nie tworzy drugiego zlecenia.
num_speakersOpcjonalne, od 1 do 20.

Status i wynik

GET /v1/jobs/{id}          → state: queued | running | done | error, stage, error, delivery
GET /v1/jobs/{id}/result   → wynik (409, gdy jeszcze nie gotowy; 410, gdy wygasł)
GET /v1/health             → {"ok": true, "engine": "ok"}

Zlecenie innego projektu odpowiada 404, tak jakby nie istniało.

Webhook

POST https://twoja-aplikacja.pl/webhooks/voice
X-Voice-Job: 3f2a…
X-Voice-Timestamp: 1793980800
X-Voice-Signature: sha256=9c1e…

{"id": "3f2a…", "job_ref": "rozmowa-2026-11-06-01", "state": "done",
 "result": {
   "engine": "voice-1", "language": "pl", "label_language": "pl", "duration": 312.4, "speakers": 2, "warnings": [],
   "notice": "Emotion and voice parameters are model estimates from the recording, not facts about the speaker.",
   "segments": [
     {"start": 0.42, "end": 3.10, "speaker": "Osoba 1", "text": "Dzień dobry, dzwonię w sprawie umowy.",
      "emotion": {"label": "spokój / neutralnie", "score": 0.55},
      "params": {"intensity": 2, "secondary": [], "style": {…}, "prosody": {…}, "justification": "…"}}
   ]}}

Gdy przetwarzanie się nie uda, przychodzi "state": "error" z kodem unreadable_audio albo processing_failed. Odpowiedz kodem 2xx. Innym kodem, przekierowaniem albo brakiem odpowiedzi uruchomisz ponowienie: do 8 prób w rosnących odstępach, od 30 sekund do około pół godziny. Przekierowań nie wykonujemy.

Weryfikacja podpisu

import hashlib, hmac, time

def verify(secret: str, timestamp: str, raw_body: bytes, signature: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
    mac = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest("sha256=" + mac, signature)

Podpisujemy surowe bajty treści, więc liczysz HMAC przed parsowaniem JSON. Znacznik czasu chroni przed powtórzeniem starego wywołania.

Kody błędów

HTTPZnaczenie
400Niepoprawny callback_url, job_ref albo num_speakers lub pusty plik.
401Brak tokenu, zły token albo token unieważniony.
413 / 415Plik za duży albo nieobsługiwany format.
422Silnik odrzucił nagranie.
429Za dużo zleceń w toku w jednym projekcie. Poczekaj na wyniki.
503Silnik chwilowo niedostępny. Nagranie nie zostało przyjęte; wyślij je ponownie po czasie z nagłówka Retry-After.

Prywatność

Nagranie

Przechodzi przez pamięć bramki prosto do silnika. Nie zapisujemy go na dysku, a silnik kasuje plik zaraz po przetworzeniu.

Wynik

Po odebraniu kasujemy go z silnika. U nas zostaje 30 dni, żeby można go było pobrać ponownie, a potem znika.

Dostęp

Przechowujemy tylko skrót tokenu. Zlecenia i wyniki widzi wyłącznie projekt, który je wysłał.

Dostęp

Tokeny wydajemy ręcznie, jeden na projekt. Opisz krótko, jakie nagrania chcesz analizować i w jakiej skali: kontakt@hexagonblue.tech.