Skip to main content
Tous les exemples utilisent des requêtes HTTP classiques. Les en-têtes et corps sont encodés en JSON UTF-8.

1. Authentification

Chaque requête doit contenir l’en-tête :
Authorization: Bearer <API_TOKEN_DE_LA_SOCIETE>
API_TOKEN_DE_LA_SOCIETE correspond au champ api_token de la table company. Si l’en-tête est manquant ou invalide, le serveur renvoie 401 Unauthorized.

2. Créer / mettre à jour un client

POST /api/v1/customers
ChampTypeObligatoireDescription
companyIdentifierstringouiIdentifiant unique du client (propre à votre système).
metadataobject (JSON)ouiMéta-données librement définies (nom, email, etc.). Toutes les clefs et valeurs doivent être des chaînes de caractères.

Réponses possibles

CodeSignification
200Création ou mise à jour réussie ({ success: "…" }).
400Paramètres manquants.
401Token d’API invalide.
500Erreur interne.

Exemple de requête

curl -X POST https://api.moustacheai.com/api/v1/customers \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "companyIdentifier": "CLIENT_123",
        "metadata": {
          "email": "contact@client.fr",
          "nom": "Société Exemple"
        }
      }'

2bis. Récupérer un client

GET /api/v1/customers Permet de récupérer les informations d’un client existant à partir de son identifiant.

Paramètres de requête (query string)

ParamètreTypeObligatoireDescription
companyIdentifierstringouiIdentifiant unique du client (même valeur que pour POST /api/v1/customers).

Réponses possibles

CodeCorps JSON
200{ "id": 1, "company_identifier": "CLIENT_123", "data": { "email": "...", "nom": "..." } }
400{ "error": "Missing companyIdentifier query parameter" }
401{ "error": "Unauthorized: Unknown token" }
404{ "error": "Customer not found" }
500{ "error": "Internal Server Error" }

Exemple de requête

curl -X GET 'https://api.moustacheai.com/api/v1/customers?companyIdentifier=CLIENT_123' \
  -H "Authorization: Bearer MON_API_TOKEN"
Réponse :
{
  "id": 42,
  "company_identifier": "CLIENT_123",
  "data": {
    "email": "contact@client.fr",
    "nom": "Société Exemple"
  }
}

3. Envoyer une question à un agent

POST /api/v1/responses
ChampTypeObligatoireDescription
companyIdentifierstringouiIdentifiant du client (même valeur que pour /customers).
agentUUIDstringouiUUID de l’agent (assistant) qui doit répondre.
questionstringouiQuestion de l’utilisateur final.
streambooleannon (def: true)true → réponse en flux (SSE) ; false → réponse complète en une fois.
filesarraynonFichiers (images) pour la vision. Chaque élément: { "url": "...", "type": "image/png", "name": "optionnel" }. url peut être une URL publique HTTPS ou un data: URL base64.
Aucun uuid n’est requis : le serveur génère un identifiant de message unique. Si files est fourni, l’assistant doit utiliser un modèle vision (vision activée), sinon la requête échoue en 403. Les fichiers peuvent être envoyés :
  • en JSON via files (URL publique ou data: URL base64) ;
  • en multipart/form-data via un champ files (un ou plusieurs fichiers).

Réponses (mode stream)

  • 200 OK : renvoie un flux texte text/html; charset=utf-8 dont chaque chunk est une partie de la réponse. Le flux se termine par le marqueur :EOS:.
  • Autres codes d’erreur : voir tableau ci-dessous.

Réponses (mode non stream)

CodeCorps JSON
200{ "message": "…", "buttons": [ "Option 1", "Option 2" ] }
400{ "error": "Missing parameters" }
401{ "error": "Unauthorized: Unknown token" }
404{ "error": "Unauthorized: Assistant not found for your company" }
403{ "error": "Image inputs require a vision-enabled model for this assistant" }
500{ "error": "Answer not found" } ou erreur interne.

Exemple : réponse complète (stream = false)

curl -X POST https://api.moustacheai.com/api/v1/responses \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "companyIdentifier": "CLIENT_123",
        "agentUUID": "28ce3b2d-5791-4905-8d66-123456789abc",
        "question": "Quels sont vos horaires d\'ouverture ?",
        "stream": false
      }'
Réponse :
{
  "message": "Nous sommes ouverts du lundi au vendredi de 9h à 18h.",
  "buttons": null
}

Exemple : question avec fichiers (stream = false)

curl -X POST https://api.moustacheai.com/api/v1/responses \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "companyIdentifier": "CLIENT_123",
        "agentUUID": "28ce3b2d-5791-4905-8d66-123456789abc",
        "question": "Peux-tu décrire l’image ?",
        "stream": false,
        "files": [
          {
            "url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
            "type": "image/jpeg",
            "name": "produit-1.jpg"
          }
        ]
      }'

Exemple : envoi multipart/form-data

curl -X POST https://api.moustacheai.com/api/v1/responses \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -F "companyIdentifier=CLIENT_123" \
  -F "agentUUID=28ce3b2d-5791-4905-8d66-123456789abc" \
  -F "question=Peux-tu décrire l’image ?" \
  -F "stream=false" \
  -F "files=@/chemin/vers/produit-1.jpg"

Exemple : plusieurs fichiers (multipart/form-data)

curl -X POST https://api.moustacheai.com/api/v1/responses \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -F "companyIdentifier=CLIENT_123" \
  -F "agentUUID=28ce3b2d-5791-4905-8d66-123456789abc" \
  -F "question=Compare ces deux images" \
  -F "stream=false" \
  -F "files=@/chemin/vers/produit-1.jpg" \
  -F "files=@/chemin/vers/produit-2.jpg"

Exemple : réponse en flux (stream = true)

curl -N -X POST https://api.moustacheai.com/api/v1/responses \
  -H "Authorization: Bearer MON_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "companyIdentifier": "CLIENT_123",
        "agentUUID": "28ce3b2d-5791-4905-8d66-123456789abc",
        "question": "Je souhaite prendre rendez-vous.",
        "stream": true
      }'
Le flux affiche progressivement la réponse puis se termine par :EOS:.

3bis. Récupérer l’historique d’une conversation

GET /api/v1/responses Permet de récupérer l’historique complet (questions/réponses) d’une conversation entre un client et un agent, au format JSON.

Paramètres de requête (query string)

ParamètreTypeObligatoireDescription
companyIdentifierstringouiIdentifiant du client (même valeur que pour /customers).
agentUUIDstringouiUUID de l’agent (assistant) dont on veut l’historique.
L’authentification se fait via le header :
Authorization: Bearer <API_TOKEN_DE_LA_SOCIETE>

Réponse

CodeCorps JSON
200{ "messages": [ { "message": "…", "buttons": ["Option 1"], "message_type": "Question", "created_at": "…" }, ... ] }
400{ "error": "Missing parameters" }
401{ "error": "Unauthorized: Unknown token" }
404{ "error": "Unauthorized: Assistant not found for your company" } ou Customer not found
500{ "error": "Internal Server Error" }
Chaque message du tableau contient :
  • message : texte de la question ou réponse
  • buttons : tableau d’options (si présent)
  • message_type : “Question” ou “Answer”
  • created_at : date ISO

Exemple de requête

curl -X GET 'https://api.moustacheai.com/api/v1/responses?companyIdentifier=CLIENT_123&agentUUID=28ce3b2d-5791-4905-8d66-123456789abc' \
  -H "Authorization: Bearer MON_API_TOKEN"
Réponse :
{
  "messages": [
    {
      "message": "Bonjour, comment puis-je vous aider ?",
      "buttons": null,
      "message_type": "Question",
      "created_at": "2024-06-07T12:34:56.000Z"
    },
    {
      "message": "Je souhaite prendre rendez-vous.",
      "buttons": null,
      "message_type": "Answer",
      "created_at": "2024-06-07T12:35:10.000Z"
    }
  ]
}

4. Codes d’erreur communs

CodeMotif
400Paramètre manquant ou invalide
401En-tête Authorization absent / mauvais
404Agent introuvable pour la société
500Erreur interne inattendue

5. Bonnes pratiques

  1. Timeout côté client : pour le mode stream, coupez la connexion si aucun chunk n’est reçu depuis >20 s.
  2. Réessais : en cas de 500 réessayez avec back-off exponentiel.
  3. Sécurité : stockez l’API_TOKEN côté serveur uniquement.

6. Détails techniques du mode stream

Le mode streaming (stream: true, valeur par défaut) utilise un ReadableStream HTTP côté serveur.

Format

  • Content-Type : text/html; charset=utf-8
  • Chaque chunk contient un fragment de texte de la réponse de l’agent, encodé en UTF-8.
  • Le flux se termine par le marqueur :EOS: (End Of Stream).
  • Le timeout serveur est de 120 secondes (maxDuration). Si l’agent met plus longtemps à répondre, la connexion sera coupée.

Backpressure

Le serveur utilise le mécanisme pull() du ReadableStream : les chunks sont mis en file d’attente et envoyés dès que le client est prêt à les consommer. Si le client lit lentement, le serveur met les données en tampon.

Interruption

Si le client ferme la connexion (signal abort), le serveur interrompt la génération et pousse un message d’abandon dans le flux avant de le fermer.

Multipart/form-data

Le streaming fonctionne aussi avec un envoi multipart/form-data (pour joindre des fichiers). Les champs texte (companyIdentifier, agentUUID, question, stream) sont lus depuis le FormData, et les fichiers sont convertis en data: URL base64 avant d’être transmis à l’assistant.