Genesis — everything you need to know to call this endpoint
/comprendre takes raw unstructured text (an email body, a pasted message, anything) and returns a full classification: email type, client, product lines, delivery info, and an explainable audit trail.
It always returns a response. If the LLM (Claude Haiku via Bedrock) is available, extraction is high quality. If not, a keyword/regex fallback extracts what it can. In both cases, Snake SAT classification runs on the extracted features.
POST /comprendre
Content-Type: application/json
{
"text": "your email or message text here",
"factory_id": 3,
"anthropic": false
}
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
text | string | yes | — | The raw text to classify. Email body, pasted message, any unstructured French text about glass products. |
factory_id | int | no | 3 | Monce factory ID. Options: 1 (VIT), 3 (Monce), 4 (VIP), 9 (Euro), 10 (TGVI). |
anthropic | bool | no | false | Set to true to enable Claude Haiku extraction. Default uses keyword/regex extraction only — no LLM, no API key needed. |
# Default (Snake only, no LLM, instant)
curl -X POST https://emailclassifier.aws.monce.ai/comprendre \
-H "Content-Type: application/json" \
-d '{"text": "Bonjour, merci de nous livrer 200 feuillete 44.2 clair 1000x2000. Livraison le 25/04 sur chantier Lille."}'
# With Haiku extraction (needs API key on EC2)
curl -X POST https://emailclassifier.aws.monce.ai/comprendre \
-H "Content-Type: application/json" \
-d '{"text": "Bonjour, merci de nous livrer 200 feuillete 44.2 clair 1000x2000.", "anthropic": true}'
# Devis (default mode)
curl -X POST https://emailclassifier.aws.monce.ai/comprendre \
-H "Content-Type: application/json" \
-d '{"text": "Pourriez-vous nous faire un prix pour 100 trempes 10mm?"}'
# Relance (default mode)
curl -X POST https://emailclassifier.aws.monce.ai/comprendre \
-H "Content-Type: application/json" \
-d '{"text": "Toujours en attente de la commande #4521. Ca fait 2 semaines de retard."}'
{
"factory_id": 3,
"version": "v0.2.0",
"mock": false, // false = Haiku, true = keyword fallback
"classification": {
"Prediction": "Commande", // top class
"Probability": { // all 5 classes, sums to ~1.0
"Commande": 0.99,
"Devis": 0.01,
"Relance": 0.0,
"Spam": 0.0,
"Autre": 0.0
},
"method": "snake_sat", // always snake_sat
"tier": 1
},
"client": {
"match": "Verreries du Nord", // detected company name (or null)
"numero_client": "CLI-07329", // mock ID from domain hash
"confidence": 0.95,
"method": "snake_sat",
"contact": "Jean Dupont" // extracted contact name
},
"lignes": [ // product lines extracted from text
{
"ligne": 1,
"texte_brut": "200 feuillete 44.2 clair 1000x2000",
"qty": 200,
"dims": "1000x2000",
"article": {
"num_article": "31939", // mock article ID
"denomination": "Feuillete 44.2 clair",
"confidence": 0.68,
"method": "snake_sat",
"tier": 1,
"field_type": null // or "intercalaire"/"remplissage"
}
}
],
"delai_demande": "2026-04-25", // delivery date if mentioned
"lieu_livraison": "chantier Lille", // delivery location if mentioned
"quality_score": 0.69, // avg confidence across all matches
"latency_ms": 2305, // total server time
"xai": {
"classification_audit": "...", // full Snake audit for email type
"client_audit": "...", // how client was identified
"lignes_audit": ["L1: ...", "L2: ..."],// per-line matching audit
"actions_suggerees": [ // recommended next steps
"Creer commande ERP avec lignes produit extraites",
"Confirmer delai 2026-04-25 avec logistique"
]
}
}
mock and anthropic fieldsanthropic is the input flag. mock is the output flag. Together they tell you what happened.
Request anthropic | Response mock | What ran | Latency |
|---|---|---|---|
| false (default) | true | Keyword extraction + Snake SAT | <10ms |
| true | false | Claude Haiku extraction + Snake SAT | 1.5–3s |
| true | true | Haiku failed → keyword fallback + Snake SAT | ~5s (timeout + fallback) |
Default is keyword + Snake. No API key, no network, no cost. Snake does the classification with real SAT models. This is the mode the EC2 runs in out of the box.
With anthropic=true: Claude Haiku extracts richer features from natural language before Snake classifies. Better at understanding context, synonyms, implicit meaning. Requires AWS_BEARER_TOKEN_BEDROCK on the EC2.
When: Default. No flag needed. No API key needed.
What happens: Keyword/regex extraction runs locally. Detects quantities, dimensions, dates, product keywords, tone markers, urgency words. Builds the 13 features. Snake classifies.
Latency: <10ms total. Pure local computation.
Cost: Zero. No network calls, no API usage.
Accuracy: Good for structured text with explicit quantities, bullet points, glass product names. Misses nuance and implicit meaning. The Snake models carry the classification — as long as the keyword extraction catches the right boolean features, the prediction is correct.
When: "anthropic": true in request AND AWS_BEARER_TOKEN_BEDROCK is set on EC2.
What happens: The full text is sent to Claude Haiku 4.5 with a structured extraction prompt. Claude returns JSON with expediteur, intention, lignes_articles, delai, lieu_livraison, ton, urgence. This JSON is then parsed into 13 features that feed Snake.
Latency: 1.5–3s (dominated by Haiku round-trip to Bedrock eu-west-3).
Accuracy: High. Claude handles synonyms ("livrer" = "expedier" = "envoyer"), implicit quantities, ambiguous phrasing. The 13 features are reliably extracted even from messy text.
Fallback chain: eu-west-3 → us-west-2 → us-east-1. If all three Bedrock regions fail, falls through to Mode B.
Regardless of extraction mode, the same 13 features are computed and fed to Snake:
| # | Feature | Type | How it's computed |
|---|---|---|---|
| 1 | has_quantity | bool | Any product line has qty ≠ null |
| 2 | has_product_ref | bool | Text contains ref/BC/CMD/PO/# patterns |
| 3 | has_dimensions | bool | Any product line has dims (LxH) |
| 4 | has_price | bool | Text contains prix/tarif/devis/cotation |
| 5 | has_attachment_pdf | bool | Attachments list contains .pdf |
| 6 | has_delivery_date | bool | delai_demande is not null |
| 7 | ton | cat | "formel" or "informel" |
| 8 | has_greeting | bool | Body starts with Bonjour/Madame/Salut/... |
| 9 | nb_product_lines | int | Count of extracted product lines |
| 10 | has_urgency_words | bool | Text contains urgent/asap/critique/... |
| 11 | has_complaint_words | bool | Text contains reclamation/casse/probleme/... |
| 12 | has_question_mark | bool | Body or subject contains "?" |
| 13 | domain_known | bool | Sender domain is not gmail/yahoo/free |
/comprendre is designed for raw text — no structure needed. But you'll get better results with more signal:
{
"text": "De: jean.dupont@verreriesdunord.fr\nObjet: Commande feuillete\n\nBonjour,\nMerci de nous livrer :\n- 200 pieces feuillete 44.2 clair 1000x2000\n- 50 trempe 10mm 800x1200\nLivraison 25/04 chantier Lille.\nCordialement, Jean Dupont"
}
Include sender email, subject, bullet-point lines, quantities, dimensions, dates, signature. Haiku extracts everything; even the fallback catches most of it.
{
"text": "Bonjour, je voudrais commander 50 vitrages feuillete 44.2 pour le chantier de Lyon, livraison avant fin avril svp."
}
Natural sentence. Haiku gets it all. Fallback catches "commander" (intention), "50" (qty), "feuillete 44.2" (product), "fin avril" (date), "chantier de Lyon" (location).
{
"text": "200 feuillete 44.2 1000x2000"
}
Telegram-style. Both modes detect quantity + product + dimensions. Classification works but confidence is lower (no intention keywords, no greeting, no delivery date).
// Empty text: returns "Autre" with low confidence
{"text": ""}
// Non-glass text: returns "Autre" or "Spam"
{"text": "Buy cheap watches online!!!"}
// Pure question: returns "Devis"
{"text": "Quel est votre prix pour du trempe 10mm?"}
The API key controls which mode runs. Set it in /home/ubuntu/emailclassifier/.env:
# Bedrock token (preferred — works with eu-west-3 Bedrock gateway) AWS_BEARER_TOKEN_BEDROCK=ABSK...your_token... # Or direct Anthropic key (if using direct API instead of Bedrock) # ANTHROPIC_API_KEY=sk-ant-...
The systemd service loads this via EnvironmentFile=/home/ubuntu/emailclassifier/.env. After changing, restart:
sudo systemctl restart emailclassifier
To test without Haiku (force fallback mode): temporarily clear the .env file. All requests will use keyword extraction and return mock=true.
| Guarantee | Always | Notes |
|---|---|---|
| Returns 200 with valid JSON | yes | Unless text field is missing (422) |
classification.Prediction is one of 5 classes | yes | Commande/Devis/Relance/Spam/Autre |
classification.Probability sums to ~1.0 | yes | Rounding may cause ±0.01 |
xai audit trail present | yes | Snake audit in both modes |
lignes populated | depends | Empty if no products detected in text |
client.match populated | depends | Requires email or company in text |
delai_demande populated | depends | Only if a date is mentioned |
| Latency < 5s | yes | Haiku: 1.5-3s, fallback: <10ms |
# Python
import requests
r = requests.post("https://emailclassifier.aws.monce.ai/comprendre",
json={"text": email_body, "factory_id": 3})
result = r.json()
if result["classification"]["Prediction"] == "Commande":
create_erp_order(result["lignes"], result["client"])
elif result["classification"]["Prediction"] == "Devis":
generate_quote(result["lignes"])
# Check extraction quality
if result["mock"]:
flag_for_manual_review(result)
# JavaScript (Outlook add-in)
const res = await fetch("https://emailclassifier.aws.monce.ai/comprendre", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({text: emailBody, factory_id: 3})
});
const data = await res.json();
showClassification(data.classification.Prediction, data.xai);