Intégrer votre agent
Ces trois routes sont celles qu'appellent la page de chat publique et le widget. Elles sont ouvertes : aucune clé, aucun jeton. Ce qui les protège est l'identifiant de l'agent, la formule à laquelle il est rattaché et une limitation de débit. Tout accepte et retourne du JSON.
Le widget, en une ligne
Collez cette ligne avant la balise </body>
de votre site. Remplacez mon-agent
par l'adresse de votre agent — vous la trouvez, avec le code déjà prêt à
copier, sur la fiche de l'agent dans votre tableau de bord.
<script data-agent-ia src="https://www.quoralo.com/api/widget/mon-agent" async></script>
Le script pose une bulle en bas à droite et ouvre le chat dans une iframe : rien de votre page n'est modifié, et rien du chat ne peut lire votre page. Les couleurs, l'avatar et le message d'accueil se règlent depuis le tableau de bord — le code n'a pas à changer. Le widget est inclus dans toutes les formules, la gratuite comprise.
Où coller cette ligne dépend de votre site : WordPress, Shopify, Wix et trois autres plateformes ont chacune leur menu — le chemin exact, plateforme par plateforme.
Les routes que votre agent appelle
/api/leads Capture un contact (coordonnées d'un visiteur intéressé), associé à un agent et à une conversation optionnelle. Endpoint public, limité à 10 requêtes/minute par IP. Le plan du propriétaire de l'agent doit inclure la capture de contacts (Croissance et plus).
Corps de la requête
| Champ | Type | Requis | Description |
|---|---|---|---|
| agentId | string | Oui | Identifiant de l'agent |
| name | string | Oui | Nom complet du visiteur |
| string | Oui | Adresse email du visiteur | |
| phone | string | Non | Numéro de téléphone |
| conversationId | string | Non | ID de la conversation en cours — le contenu de l'échange est lu depuis elle |
| source | "chat" | "widget" | Non | Origine de la capture. Défaut : "chat" |
| consentement | true | Oui | Doit valoir exactement true — la personne a accepté |
| consentementTexte | string | Oui | Le texte exact qu'elle a accepté, 10 à 500 caractères |
Exemple de requête
POST /api/leads
Content-Type: application/json
{
"agentId": "abc123",
"name": "Marie Dupont",
"email": "marie@exemple.fr",
"phone": "06 12 34 56 78",
"consentement": true,
"consentementTexte": "J'accepte que mes coordonnées soient utilisées pour être recontacté(e)."
} Exemple de réponse (201)
{
"data": {
"id": "lead_xyz789",
"agentId": "abc123",
"conversationId": null,
"name": "Marie Dupont",
"email": "marie@exemple.fr",
"phone": "06 12 34 56 78",
"score": 75,
"source": "chat",
"consentementDonne": true,
"consentementLe": "2026-03-31T10:00:00.000Z",
"consentementTexte": "J'accepte que mes coordonnées soient utilisées pour être recontacté(e).",
"createdAt": "2026-03-31T10:00:00.000Z"
}
}
La réponse porte la ligne entière, preuve du consentement comprise —
c'est elle qui ressort dans l'export CSV. Un consentement absent ou
différent de true donne un 400, un agent dont la formule n'inclut pas la capture un 403.
/api/appointments Crée un rendez-vous ou une réservation pour un agent. Endpoint public (pas de token), limité à 5 requêtes/minute par IP. Le plan du propriétaire de l'agent doit inclure la prise de rendez-vous (Croissance et plus).
Corps de la requête
| Champ | Type | Requis | Description |
|---|---|---|---|
| agentId | string | Oui | Identifiant de l'agent |
| name | string | Oui | Nom complet du visiteur |
| string | Oui | Adresse email du visiteur | |
| phone | string | Non | Numéro de téléphone |
| date | string | Oui | Date du créneau (YYYY-MM-DD) |
| time | string | Oui | Heure du créneau (HH:MM) |
| bookingType | string | Non | "appointment" (défaut) ou "reservation" |
| partySize | number | Non | Nombre de personnes (réservations, 1-50) |
| notes | string | Non | Notes du visiteur (max 500 caractères) |
| conversationId | string | Non | ID de la conversation en cours |
Exemple de requête
POST /api/appointments
Content-Type: application/json
{
"agentId": "abc123",
"name": "Marie Dupont",
"email": "marie@exemple.fr",
"phone": "06 12 34 56 78",
"date": "2026-09-12",
"time": "10:30"
} Exemple de réponse (201)
{
"data": {
"id": "appt_xyz789",
"agentId": "abc123",
"date": "2026-09-12",
"time": "10:30",
"status": "confirmed",
"confirmationRef": "RES-A3K9M2",
"createdAt": "2026-08-24T10:00:00.000Z"
}
} status vaut
pending si l'agent est configuré en confirmation manuelle. En cas de créneau
complet, la réponse est un 409 avec
errorCode: "slot_full"
(ou duplicate).
/api/appointments/slots Disponibilités d'un agent. Endpoint public, limité à 30 requêtes/minute par IP. Deux modes selon les paramètres fournis.
Paramètres de requête
| Champ | Type | Requis | Description |
|---|---|---|---|
| agentId | string | Oui | Identifiant de l'agent |
| date | string | Non | YYYY-MM-DD — retourne les créneaux de ce jour |
Sans date : dates disponibles
{ "dates": [{ "date": "2026-09-12", "label": "ven. 12 sept." }] } Avec date : créneaux du jour
{
"times": [
{ "time": "12:00", "label": "12:00", "available": true,
"capacity": 8, "bookedCount": 3, "remaining": 5, "group": "Midi" }
],
"timeGroups": [{ "label": "Midi", "start": "12:00", "end": "14:00" }],
"maxPartySize": 6
} Et maintenant ?
Les guides pas à pas, du premier agent à sa mise en ligne.
Le widget est inclus dans toutes les formules, la gratuite comprise.
Une intégration particulière ? Décrivez-la-nous.
Vous pouvez créer votre agent et l'essayer tout de suite.