La même intelligence que le widget — chat multilingue (+100 langues), base de connaissances, documents (RAG) — accessible par API pour vos applications mobiles, desktop ou serveur. Aucun secret côté client : clé publique + jetons de session courts.
Votre clé publique (pk_live_…, visible dans le dashboard → Installation)
identifie votre compte. Elle n'est pas un secret : chaque appel est validé par l'origine
de la requête, qui doit figurer dans vos domaines autorisés (dashboard → Installation → Domaines).
Origin automatiquement.X-Parlyo-App: com.votreapp.ios
et ajoutez com.votreapp.ios à vos domaines autorisés. Un identifiant non déclaré est refusé (403).https://parlyo.io/api/embed · Réponses JSON · Erreurs stables
{"error","code"}. Le JWT expire après 15 min : sur un 401, re-appelez /config et rejouez la requête.| Endpoint | Auth | Rôle |
|---|---|---|
GET /config?pk=…&lang=fr | pk + Origin ou X-Parlyo-App | Configuration (nom, accueil, questions suggérées, couleurs) localisée + jwt de session. |
POST /chat | Bearer JWT | Message → réponse du conseiller (replyText), fondée sur votre base + vos documents (RAG). Corps : {message, history[], sessionId?}. |
POST /voice-token | Bearer JWT | Jeton éphémère verrouillé pour la voix temps réel (WebSocket direct Gemini Live). Web uniquement pour l'instant. |
POST /voice-beat | Bearer JWT | Battement 30 s pendant une session voix (métrage). |
history[{ "role": "user", "text": "Bonjour" }, { "role": "model", "text": "Bonjour ! Comment puis-je aider ?" }]
# 1. Config + JWT (app mobile : X-Parlyo-App au lieu d'un Origin)
curl "https://parlyo.io/api/embed/config?pk=pk_live_VOTRE_CLE&lang=fr" \
-H "X-Parlyo-App: com.votreapp.ios"
# 2. Chat
curl -X POST "https://parlyo.io/api/embed/chat" \
-H "X-Parlyo-App: com.votreapp.ios" \
-H "Authorization: Bearer LE_JWT" \
-H "Content-Type: application/json" \
-d '{"message":"Quels sont vos horaires ?","history":[]}'
const BASE = "https://parlyo.io/api/embed";
const PK = "pk_live_VOTRE_CLE";
const APP = "com.votreapp.ios"; // apps natives uniquement
let jwt = null;
async function session() {
const r = await fetch(`${BASE}/config?pk=${PK}&lang=fr`, { headers: { "X-Parlyo-App": APP } });
const j = await r.json(); jwt = j.jwt; return j; // j.greeting, j.suggestions…
}
async function ask(message, history = []) {
if (!jwt) await session();
let r = await fetch(`${BASE}/chat`, {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${jwt}`, "X-Parlyo-App": APP },
body: JSON.stringify({ message, history }),
});
if (r.status === 401) { await session(); return ask(message, history); } // JWT expiré → 1 retry
return (await r.json()).replyText;
}
var request = URLRequest(url: URL(string: "https://parlyo.io/api/embed/chat")!)
request.httpMethod = "POST"
request.setValue("com.votreapp.ios", forHTTPHeaderField: "X-Parlyo-App")
request.setValue("Bearer \(jwt)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(["message": text, "history": []])
let (data, _) = try await URLSession.shared.data(for: request)
val body = JSONObject(mapOf("message" to text, "history" to JSONArray()))
val req = Request.Builder()
.url("https://parlyo.io/api/embed/chat")
.header("X-Parlyo-App", "com.votreapp.android")
.header("Authorization", "Bearer $jwt")
.post(body.toString().toRequestBody("application/json".toMediaType()))
.build()
Le conseiller répond à partir de votre base de connaissances (dashboard → Connaissances — remplissable en un clic avec « Importer depuis mon site ») et de vos documents (PDF, TXT, Markdown, CSV) qu'il consulte automatiquement pendant la conversation. Aucun paramètre API supplémentaire : uploadez vos documents dans le dashboard, ils sont immédiatement consultables.
| Code | Signification | Que faire |
|---|---|---|
origin_forbidden 403 | Origine / X-Parlyo-App non déclarée | Ajouter le domaine ou bundle id dans le dashboard |
invalid_jwt 401 | Session expirée (15 min) | Re-appeler /config, rejouer (1 retry) |
rate_limited 429 | Trop de requêtes (chat : 60/min/IP, 20/min/session) | Backoff exponentiel |
quota_msgs 429 | Quota mensuel de conversations atteint | Upgrade du plan |
quota_voice / daily_cap 429 | Quota voix atteint | Basculer en texte, upgrade |
pk_ peut vivre dans le code client — la protection vient des domaines/bundle ids déclarés.sk_ (backend-à-backend), streaming des réponses, webhooks de leads. Écrivez-nous : [email protected].