# dev.okto.it > Documentation développeur d'okto.it, une suite de services en ligne (voice, msg, pdf, sign, file, cal, visio, wiki, shop, data…) organisés en espaces : une équipe = un espace, avec un porte-monnaie de crédit. Les API à clé s'appellent en HTTP avec une clé développeur de l'espace. Aujourd'hui, une seule API à clé est ouverte : voice (voix → texte d'un fichier ou en direct, texte → voix d'un coup ou en direct). Toutes les réponses d'erreur sont en français. ## Clé développeur - Format : `okto_key_<12 caractères hexadécimaux>_`. - Création : https://okto.it/space/keys (aussi https://voice.okto.it/keys, qui y renvoie), par le propriétaire ou un gestionnaire de l'espace. On coche les services autorisés (voice pour l'instant). - Montrée une seule fois, révocable. Elle appartient à un espace : ses appels sont payés par le crédit de cet espace. - En-tête de chaque requête : `Authorization: Bearer okto_key_…`. - Ne jamais la commiter. Dans une app mobile, une clé (y compris une variable `EXPO_PUBLIC_…`) peut être extraite : acceptable pour un prototype ; pour une app publiée, appeler voice depuis un serveur qui garde la clé. ## API voice (https://voice.okto.it) ### POST /v1/transcribe — voix → texte - Corps : le fichier audio, soit brut avec `Content-Type` parmi `audio/mp4`, `audio/m4a`, `audio/aac`, `audio/mpeg`, `audio/wav`, `audio/webm`, `audio/ogg`, `audio/flac` ; soit `multipart/form-data` avec le fichier dans le champ `file`. - Paramètres facultatifs, en requête (`?language=fr-FR&vocabulary=Kapsuls,UCA`) ou en champs du formulaire : - `language` : code BCP-47 ; sans lui, détection automatique. - `vocabulary` : termes à bien reconnaître, séparés par des virgules, 100 au plus. - Limites : 20 Mo, 10 minutes d'audio. - Réponse : `200` `{ "text": "…", "seconds": 12.4 }` (`seconds` = durée de l'audio). ### WebSocket /v1/stream — voix → texte en direct - Ouvrir : depuis un serveur, `wss://voice.okto.it/v1/stream?languages=fr-FR&vocabulary=…&maxMinutes=30` avec l'en-tête `Authorization: Bearer okto_key_…`. Depuis un navigateur ou une app (la clé reste sur le serveur) : le serveur appelle `POST https://voice.okto.it/v1/stream` (JSON `{ "languages": ["fr-FR"], "vocabulary": [], "maxMinutes": 60 }`, tout facultatif) → `201 { id, url, expiresIn: 60, maxMinutes }` ; la page ouvre `new WebSocket(url)` (adresse à usage unique, valable 60 s). - Envoyer : trames binaires PCM 16 bits little-endian mono 16 kHz, en temps réel, 20 à 100 ms chacune, silences compris (voice découpe les phrases). Texte : `{"type":"stop"}` (fin, la dernière phrase arrive encore), `{"type":"pause"}` (fin de phrase immédiate). - Recevoir (JSON) : `ready { id, rate, maxMinutes, languages }` ; `text { id, text, final, at }` (provisoire ~toutes les 0,5 s puis définitif, même `id` : remplacer le texte de la phrase) ; `usage { seconds }` ; `error { status, message, action? }` (refus à l'ouverture : fermeture avec le code 4000 + statut) ; `end { reason, seconds }` puis fermeture (`client`, `limit`, `idle` = 2 min sans trame, `credit`, `refused`, `restart`). - Navigateur : AudioWorklet qui rééchantillonne le micro (44,1/48 kHz) en Int16 16 kHz par paquets de 320 échantillons et les poste au thread principal, qui les envoie au WebSocket ; le nœud doit être relié à la sortie (gain 0) pour tourner. Code complet : https://dev.okto.it/voice/#stream - Décompte : parole seulement, `voice.minutes`, minute par minute pendant le flux ; crédit épuisé → `error` 402 puis `end` `credit`. 60 min par flux au plus, 3 flux simultanés par clé. ### WebSocket /v1/stream?mode=say — texte → voix en direct - Le même WebSocket dans l'autre sens : premier son en 0,7 à 0,9 s (contre 2 à 6 s pour `POST /v1/say`, qui attend le fichier entier). Préférer ce mode pour un assistant ou un dialogue. - Ouvrir : serveur, `wss://voice.okto.it/v1/stream?mode=say&voice=Kore` avec `Authorization: Bearer okto_key_…` ; navigateur ou app, le serveur appelle `POST https://voice.okto.it/v1/stream` avec `{ "mode": "say", "voice": "Kore" }` → `201 { id, url, expiresIn: 60 }`. - Envoyer (JSON) : `{"type":"say","text":"…","id":"q1","voice":"Puck"}` (1000 caractères, 20 phrases en attente au plus, dites dans l'ordre une à la fois) ; `{"type":"cancel"}` (coupe la phrase en cours et vide la file) ; `{"type":"stop"}` (dit le reste puis ferme). - Recevoir : `ready { id, mode: "say", rate: 24000, voice, maxMinutes }` ; par phrase, `audio_start { id, rate }`, puis des trames binaires PCM 16 bits little-endian mono 24 kHz (~60 ms chacune), puis `audio_end { id, seconds, cancelled? }` ; `error { id?, status, message, action? }` ; `end { reason, seconds }`. - Lecture navigateur : convertir chaque trame Int16 en Float32 (÷ 32768), `AudioBuffer` à 24000 Hz, `AudioBufferSourceNode.start(t)` avec `t` = fin du morceau précédent. Code complet : https://dev.okto.it/voice/#say-stream - Décompte : voix produite, `voice.speech` (0,04 €/min), phrase par phrase ; crédit vérifié avant chaque phrase (402 → `end` `credit`). ### POST /v1/say — texte → voix - Corps JSON : `{ "text": "…", "voice": "Kore", "format": "web" }`. - `text` : 1 à 1000 caractères, obligatoire. - `voice` : `Kore` (défaut) ou `Aoede` (féminines), `Charon` ou `Puck` (masculines). - `format` : `web` (défaut, 24 kHz) ou `phone` (8 kHz). - Réponse : `200`, `Content-Type: audio/wav` (PCM 16 bits mono). - voice ne garde rien : mettre en cache côté app les phrases qui reviennent. ### Erreurs Corps JSON `{ "error": "message en français" }`. - `400` : paramètre invalide. - `401` : clé absente, invalide ou révoquée, ou service voice non coché sur la clé. - `402` : crédit de l'espace insuffisant ; la réponse porte aussi `action`, l'adresse où recharger. - `413` : fichier trop grand (20 Mo) ou trop long (10 minutes). - `415` : format audio non reconnu (m4a, mp4, aac, mp3, wav, webm, ogg, flac acceptés). - `423` : espace suspendu. - `429` : trop de requêtes, ou plafond du jour de la clé atteint. - `502`, `503` : moteur indisponible, réessayer après une pause. ### Prix et plafond - Décompté du crédit de l'espace, à la seconde. Crédit offert à l'inscription, puis recharges. Pas d'usage gratuit. - Transcription : 0,02 € par minute d'audio envoyé (fichier) ou de parole (en direct). - Synthèse : 0,04 € par minute de voix produite (`/v1/say` et `/v1/stream?mode=say`). - Plafond de sécurité par clé : 30 minutes par jour, transcription et synthèse réunies (`429` au-delà), réglable sur demande. ### Données L'audio et le texte ne sont pas conservés par voice. Ils sont traités par le moteur Gemini de Google, en mode sans rétention ni entraînement. Seules les durées sont comptées. ## Exemples ```sh curl https://voice.okto.it/v1/say -H "Authorization: Bearer $OKTO_KEY" -H "Content-Type: application/json" -d '{ "text": "Bonjour", "voice": "Kore" }' -o bonjour.wav curl "https://voice.okto.it/v1/transcribe?language=fr-FR" -H "Authorization: Bearer $OKTO_KEY" -F "file=@bonjour.wav;type=audio/wav" ``` Expo / React Native (SDK 58) : enregistrer avec `useAudioRecorder(RecordingPresets.HIGH_QUALITY)` d'`expo-audio` (fichier m4a), envoyer `recorder.uri` par le `fetch` global dans un `FormData` (`form.append("file", { uri, name: "audio.m4a", type: "audio/mp4" })`, sans fixer `Content-Type`) ; pour `/v1/say`, lire la réponse avec `arrayBuffer()` du `fetch` d'`expo/fetch`, l'écrire avec `new File(Paths.cache, "x.wav")` d'`expo-file-system` (`create()` puis `await write(bytes)`), et la jouer avec `useAudioPlayer` (`replace({ uri })` puis `play()`). ## Pages - [Accueil](https://dev.okto.it/) : trois façons de construire (API à clé, applis d'app.okto.it, connecteur IA ai.okto.it), démarrer en 3 étapes, prix. - [Référence de l'API voice](https://dev.okto.it/voice/) : clé, routes (fichier, direct, synthèse), paramètres, réponses, erreurs, prix, données. - [Guide voice dans une app Expo](https://dev.okto.it/voice/expo/) : installation, permissions micro, module `voice.ts`, composant complet, erreurs, relais serveur Node/Express. ## Autres façons de construire - [app.okto.it](https://app.okto.it) : décrire une appli, l'assistant la construit et l'héberge. - [ai.okto.it](https://ai.okto.it) : connecteur MCP pour brancher Claude ou ChatGPT sur ses services okto.it. - [Tarifs](https://okto.it/pricing) · [Nous écrire](https://okto.it/contact?service=dev)