Lou Partner API
v0.1.0 · OpenAPI spec (JSON)
Self-service partner API. Authentication via a secret key `sk_live_…` (Authorization: Bearer). Each key is scoped to its owner (pdv/brand/network) and to its `<domain>:<action>` scopes.
Authentication
Secret partner key `sk_live_…` in the `Authorization: Bearer` header.
curl -s "https://lou.care/api/v1/me" \
-H "Authorization: Bearer $LOU_API_KEY"get/api/v1/me— Key identity
Returns the resolved owner and scopes of the presented key. Sentinel: exposes no business data.
curl -s "https://lou.care/api/v1/me" \
-H "Authorization: Bearer $LOU_API_KEY"Responses
200— OK401— Missing, invalid, revoked or expired API key429— Rate limit exceeded
get/api/v1/brand— Brand profile
Profile of the key’s brand (brand-owned keys). Requires the `catalog:read` scope. Fields limited to `public`/`owner` access class columns (field-level).
curl -s "https://lou.care/api/v1/brand" \
-H "Authorization: Bearer $LOU_API_KEY"Responses
200— OK401— Missing, invalid, revoked or expired API key403— Insufficient scope (catalog:read required)404— Non-brand key or brand not found429— Rate limit exceeded
get/api/v1/products— Owner catalog
Products of the key’s owner — a brand (its products), a store (activated products) or a network (products activated by its member stores, distinct), non-archived, paginated. Requires `catalog:read`. Fields limited to `public`/`owner` columns.
curl -s "https://lou.care/api/v1/products?limit=50&offset=0" \
-H "Authorization: Bearer $LOU_API_KEY"Parameters
limit(query, integer, optional)offset(query, integer, optional)
Responses
200— OK400— Invalid query401— Missing, invalid, revoked or expired API key403— Insufficient scope (catalog:read required)404— Unsupported key429— Rate limit exceeded
patch/api/v1/products/{ean}— Update product description
Updates a product’s `long_description` for the key’s BRAND (brand-owned keys only). Requires `catalog:write`. Intentionally narrow: no status, no validation, no activation. The description goes through self-service review (Charte): served → written (`written:true`); otherwise the verdict is returned (`attestation_required` / `blocked_medical` / `locked`) WITHOUT writing. Strict parity with the `update_product_description` MCP client tool.
curl -s -X PATCH "https://lou.care/api/v1/products/<ean>" \
-H "Authorization: Bearer $LOU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"longDescription":"…"}'Parameters
ean(path, string, required)
Responses
200— Served (written) OR review verdict (not written)400— Invalid EAN or body401— Missing, invalid, revoked or expired API key403— Insufficient scope (catalog:write) or non-brand key404— Product not found for this brand429— Rate limit exceeded
get/api/v1/campaigns— Owner campaigns
Campaigns of the key’s owner (brand/store/network), non-archived, paginated. Requires `campaigns:read`. Fields limited to `public`/`owner` access class columns (field-level).
curl -s "https://lou.care/api/v1/campaigns?limit=50&offset=0" \
-H "Authorization: Bearer $LOU_API_KEY"Parameters
limit(query, integer, optional)offset(query, integer, optional)
Responses
200— OK400— Invalid query401— Missing, invalid, revoked or expired API key403— Insufficient scope (campaigns:read required)429— Rate limit exceeded
MCP — client connector
Tenant-safe MCP surface, publishable as a connector (ChatGPT / Claude). OAuth 2.1 authentication (consent) — distinct from the REST API key above. Writes are governed (draft + Charte review), never direct publish. Same access rules (role × domain) as the portal.
Endpoint
https://lou.care/api/mcp/clientExposed tools (13)
aggregate_tablereadtenant-configAgrégat read-only d’une table : fonctions dans un enum FERMÉ (count/count_distinct/sum/avg/min/max), `groupBy` optionnel, `filters` structurés, `where` par agrégat (FILTER) + `alias` → taux de remplissage en UNE requête. Rend le TOTAL réel (fin du « ≥1000 »). PAGINATION des GROUPES (avec `groupBy`) : la réponse porte `total` (nombre réel de groupes), `hasMore` et `nextOffset` → rappeler avec `offset: nextOffset` jusqu’à `hasMore:false` ; groupes triés par clé (ordre stable). ADMIN = cross-tenant (full read). TENANT = préciser pdvId/brandId possédé → agrège SES lignes (WHERE owner injecté), tables non-agrégeables refusées. Aucun SQL brut ; identifiants validés catalogue ; transaction READ ONLY.
create_product_claim_draftwritecatalogCrée un claim produit en BROUILLON (validation_status=draft, proof_ref=NULL) via le chemin gouvernance. JAMAIS published/ai_validated/reviewed_by. Claim MÉDICAL accepté EN DRAFT (capture pour revue) : inerte tant que non publié ; double-gate humain à la PUBLICATION (published + reviewed_by, LOU-221). WRITE — gated.
get_conversation_tracereadconversationsRenvoie une conversation (métadonnées) et ses messages dans l’ordre, pour investigation QA. Read-only.
get_pharmacy_configreadtenant-configConfiguration d’un PDV : identité, thème/domaine, plan, config d’accueil (marques mises en avant, suggestions). Read-only.
get_rag_sources_for_answerreadconversationsRenvoie les chunks RAG (rag_chunks_used) ayant servi à générer un message assistant. Read-only.
get_tenant_healthreadconversationsSanté d’un PDV : statut, volume de conversations (7j / 30j / total), présence d’une config d’accueil. Read-only.
get_turn_diagnosticsreadconversationsDiagnostic « replay-from-inputs » d’un tour (LOU-846) : modèle, version prompt + deploy, mode, campagnes éligibles / cardées / pill, sortie LLM brute pré-strip, bloc RAG (min_score, top_k, chunks retenus/écartés), et appels d’OUTILS (scope=tool, LOU-1134 : nom + outcome ok/empty/temporarily_unavailable/other_error + inputs masqués PHI-safe + flag threw→Sentry). Par conversationId (tout le fil) ou messageId (un tour). Read-only.
list_tenantsreadtenant-configListe paginée des PDV (tenants) avec filtres type / statut / recherche texte. Read-only.
search_conversationsreadconversationsRecherche paginée de conversations par PDV / marque / mode / issue / fenêtre temporelle. Read-only.
update_product_claimwritecatalogÉdite un claim produit (claimType, claimText, riskTier, population) à TOUT statut. Éditer un claim PUBLISHED le repasse en DRAFT (re-review IA/admin), SAUF principal admin = confiance (comme aujourd’hui au BO). proof/review jamais ; médical reste sous double-gate (LOU-221/908). WRITE — gated.
update_product_classificationwritecatalogCorrige la classification d’un produit : `productType` (∈ les 9 types, hors-enum rejeté, ne crée jamais de type). Écrit product_type + category_data ; ne touche JAMAIS validation_status. WRITE — gated.
update_product_descriptionwritecatalogMet à jour la `long_description` d’un produit (factuelle, claims strippés). N’écrit JAMAIS short_description ni validation_status. Gate Charte serveur : description bloquée si non conforme. WRITE — gated.
whoamireadtenant-configIdentité de l’appelant : type de principal, capacités (read/write) et — pour un tenant — la liste de ses accès (rôle × owner). Équivalent MCP du GET /me de l’API. Read-only, aucune donnée métier.