API partenaires Ematea
Contrat HTTP v1 pour créer un dossier, lancer le comparateur, analyser des documents et reprendre un dossier dans Ematea.
https://ematea.fr/extranet/api/v1
API serveur à serveur. Ne mettez jamais une clé dans du JavaScript navigateur, une application mobile ou un dépôt de code.
Authentification, droits et isolation
Chaque appel protégé passe la clé délivrée pour le cabinet dans l’en-tête HTTP :
Authorization: Bearer emt_live_votre_cle
La clé est liée à un seul cabinet Ematea. Le cabinet n’est jamais pris dans le JSON : toutes les lectures, créations et tarifications sont forcées côté serveur sur celui de la clé.
| Droit | Autorise |
|---|---|
tarifs | Comparateur multi-fournisseurs. |
ocr | Dépôt et analyse de documents de prêt. |
dossiers | Création idempotente et lecture des dossiers du cabinet. |
sso | Lien de reprise à usage unique vers Ematea. |
La désactivation globale, le blocage de la clé ou la suspension du cabinet bloque les appels sans délai. La limite par minute est configurée par clé (1 à 240).
Cycle d’intégration conseillé
- Créez un brouillon avec votre référence externe stable.
- Envoyez ce
dossier_idau comparateur. - Envoyez si besoin l’offre de prêt ou le tableau d’amortissement à l’OCR.
- Créez un lien SSO pour ouvrir le dossier et le finaliser dans Ematea.
Dossiers
POST/dossiers.php droit dossiers
Crée un brouillon pour le cabinet de la clé. La paire clé API + external_reference rend l’opération idempotente : une nouvelle tentative retourne le même dossier.
POST https://ematea.fr/extranet/api/v1/dossiers.php
Authorization: Bearer emt_live_votre_cle
Content-Type: application/json
{
"external_reference": "courtigo-quote-4182",
"formData": {
"projectType": "residence_principale", "loanType": "change", "bankId": "credit-agricole", "date_effet": "2026-10-01",
"borrowers": [{
"id": 1, "gender": "F", "firstName": "Jeanne", "lastName": "Martin", "birthDate": "1985-05-10", "postCode": "75001", "job": 1,
"email": "jeanne.martin@example.fr", "phone": "0600000000", "smoker": false, "travelKm": "lt15", "heights": false, "manual": false, "sport": false, "riskyJob": false, "isPPE": false,
"guarantees": [{"loan_id":1,"quotite":100,"type":"dc_ptia_itt_ipt","ipp":true,"mno":true,"franchise":90}]
}],
"loans": [{"id":1,"type":"amortissable","amount":250000,"duration":240,"rate":3.45,"deferred":0}]
}
}| Champ | Requis | Notes |
|---|---|---|
external_reference | oui | Votre identifiant unique, maximum 191 caractères. |
formData.borrowers[0].firstName, lastName, email | oui | Le premier emprunteur est nécessaire. phone et quota sont optionnels. |
formData.loans | oui | Au moins un prêt. Alias acceptés : montant, duree_mois, taux, differe_mois. |
bankId, date_effet | non | Date au format YYYY-MM-DD. |
Réponse 201 (ou 200 si la référence existe déjà) :
{
"ok": true,
"data": {"dossier_id": 123, "created": true, "external_reference": "courtigo-quote-4182"}
}GET/dossiers.php?id=123 droit dossiers
Lit uniquement un dossier du cabinet de la clé.
{
"ok": true,
"data": {
"id": 123, "status": "simulation", "montant_total": "250000.00",
"banque_nom": "credit-agricole", "nb_assures": 1, "date_effet": "2026-10-01",
"nom_produit_final": null, "last_step": 1,
"created_at": "2026-09-23 10:15:00", "updated_at": "2026-09-23 10:15:00"
}
}Contrat formData complet
Pour une tarification partenaire, le profil est volontairement strict : Ematea refuse les valeurs par défaut silencieuses. Envoyez le même payload que le comparateur.
| Bloc | Champs requis |
|---|---|
| Racine | projectType, loanType, bankId, date_effet au format YYYY-MM-DD. |
loans[] | id, amount, duration (mois), type, rate, deferred. Les alias durationMonths et deferredMonths sont acceptés. |
borrowers[] | Un ou deux assurés. Pour chacun : gender (M ou F), firstName, lastName, birthDate, postCode, job (code 1 à 13), email, smoker, travelKm, heights, manual, sport, riskyJob, isPPE. |
borrowers[].guarantees[] | Une entrée par prêt : loan_id, quotite, type, ipp, mno, franchise (30, 60, 90, 120 ou 180). |
| Options conservées | phone, birthName, birthCity, birthPostalCode, nationality, address, cityName, isPPEFamily, ainsi que les informations banque et assurance actuelle. |
travelKm vaut lt15, 15_20, 20_25 ou gt25. Chaque fournisseur applique ensuite son propre seuil de déclaration.
external_reference. La répétition est idempotente : aucun doublon n’est créé, mais les assurés, garanties et prêts du brouillon sont synchronisés avec le dernier payload.PATCH/dossiers.php droit dossiers
Deux actions complètent le parcours sans modifier le profil :
{
"action": "select_offer",
"dossier_id": 123,
"selected_offer": {"source_api":"simulassur","nom_produit":"Generali 7305","porteur_risque":"Generali","mensualite":32.4,"cout_total":7776}
}
{
"action": "attach_documents",
"dossier_id": 123,
"batch_token": "jeton_retourne_par_l_ocr"
}La première enregistre l’offre retenue. La seconde rattache les documents OCR du lot au dossier et au premier assuré.
GET /dossiers.php?id=... retourne le formData canonical, les assures synchronises, les loans, l'offre choisie, le compteur d'offres tarifees et les metadonnees des documents rattaches. Aucun dossier d'un autre cabinet ne peut etre lu.Comparateur multi-fournisseurs
POST/tarification.php droit tarifs
Le body est le formData des dossiers, directement ou enveloppé dans {"formData": {...}}. Ajoutez dossier_id pour rattacher et sauvegarder les offres. Les alias durationMonths et deferredMonths sont pris en charge.
{
"dossier_id": 123,
"projectType": "residence_principale",
"loanType": "change",
"bankId": "credit-agricole",
"date_effet": "2026-10-01",
"borrowers": [{"gender":"F","firstName":"Jeanne","lastName":"Martin","birthDate":"1985-05-10","postCode":"75001","job":1,"email":"jeanne.martin@example.fr","smoker":false,"travelKm":"lt15","heights":false,"manual":false,"sport":false,"riskyJob":false,"isPPE":false,"guarantees":[{"loan_id":1,"quotite":100,"type":"dc_ptia_itt_ipt","ipp":true,"mno":true,"franchise":90}]}],
"loans": [{"id":1,"amount":250000,"duration":240,"type":"amortissable","rate":3.45,"deferred":0}]
}La réponse est un flux Content-Type: text/event-stream. Chaque message utilise ce format :
event: tarif
data: {"type":"tarif","data":{...}}
| Evenement | Donnees |
|---|---|
start | nb_produits, frais_par_assure, nb_assures, fournisseurs, code_commission. |
tarif | Une offre au fil de l’eau. Champs usuels : source_api, nom_produit, porteur_risque, mensualite, cout_total, taea, garanties, formalites. Ignorez les champs supplémentaires inconnus. |
progress | Avancement, sans valeur de résultat final. |
done | nb_offres, dossier_id, garanties_rejetees, puis un diagnostic par source : ugip, simulassur, exade, utwin, zenioo. Le diagnostic peut comporter configure, nb, erreur, acces. |
error | {"message":"..."}, suivi de done vide si le flux ne peut pas démarrer. |
done avant de considérer la recherche terminée. Une absence d’offre n’est pas une erreur : consultez les diagnostics.OCR de documents de prêt
POST/ocr.php droit ocr
Envoyez un multipart/form-data, pas du JSON. Taille maximale : 12 Mo. Formats : PDF, JPG, PNG.
| Champ | Requis | Valeurs |
|---|---|---|
document | oui | Le fichier. |
type_document | non | auto, offre_pret, tableau_amortissement. |
upload_token / batch_token | non | Jeton à réutiliser pour grouper les fichiers d’un même dossier. |
curl -X POST "https://ematea.fr/extranet/api/v1/ocr.php" \ -H "Authorization: Bearer emt_live_votre_cle" \ -F "document=@offre.pdf" \ -F "type_document=offre_pret"
Réponse :
{
"status": "success", "document_id": 456,
"upload_token": "token_de_lot", "batch_token": "token_de_lot",
"data": {"...": "donnees extraites"},
"completeness": {"...": "champs presents"},
"quality": {"...": "indicateurs de qualite"},
"_debug": {"...": "informations techniques optionnelles"}
}data varie selon le document. Traitez les valeurs comme des propositions OCR à confirmer avant tarification.
Reprise automatique dans Ematea
POST/sso.php droit sso
Crée une URL à usage unique qui connecte le compte courtier choisi et ouvre le dossier. Le compte doit appartenir au même cabinet et être actif. courtier_user_id est facultatif seulement si un compte de reprise par défaut est configuré sur la clé.
{"dossier_id":123,"courtier_user_id":45}
{
"ok": true,
"data": {"dossier_id": 123, "expires_in": 300, "launch_url": "https://.../extranet/sso.php?token=..."}
}Codes, erreurs et support
Les erreurs JSON suivent ce format :
{"ok":false,"error":{"code":"invalid_request","message":"..."}}| HTTP | Code courant | Action |
|---|---|---|
| 400 | invalid_json, invalid_request | Corriger le JSON ou les paramètres. |
| 401 | unauthorized | Vérifier la clé et l’en-tête Bearer. |
| 403 | forbidden | Le droit de la clé ou le compte SSO ne convient pas. |
| 404 | not_found | Le dossier n’est pas dans le cabinet de la clé. |
| 405 | method_not_allowed | Utiliser la méthode documentée. |
| 409 / 422 | conflict, invalid_request | Corriger le conflit ou les champs métier. |
| 429 | rate_limited | Respecter Retry-After, puis réessayer. |
| 500 / 503 | internal_error, api_disabled, api_not_initialized | Backoff, puis support si le problème persiste. |
Conservez l’en-tête X-Request-Id retourné sur les endpoints JSON et communiquez-le au support Ematea. N’envoyez jamais de clé API ni de document dans un ticket.
Compatibilité et sécurité
- Cette documentation décrit la version
v1. Les champs supplémentaires sont compatibles : ignorez ceux que votre client ne gère pas. - Une clé se consulte dans Mon compte > Clés API pour les utilisateurs propriétaire ou accès complet du cabinet. Sa création, ses droits, son blocage et son renouvellement sont gérés par Ematea.
- Un renouvellement révoque immédiatement l’ancienne clé. Prévoyez une rotation avec mise à jour atomique de votre coffre de secrets.