# Obat Travaux — Annuaire des artisans du bâtiment > Annuaire en ligne référençant les entreprises et artisans du bâtiment en France. Permet de trouver un professionnel qualifié par métier (plombier, électricien, peintre, menuisier…), par ville, département ou région. Avis clients vérifiés, certifications, demande de devis gratuite. **Version** : 1 · **Dernière mise à jour** : 2026-05-12 · **Couverture** : France métropolitaine et DOM-TOM. Tous les libellés (noms de métiers, descriptions, avis) sont en français. La recherche plein-texte du MCP est insensible à la casse et aux accents ; tolérance aux fautes typographiques à partir de 5 caractères (1 typo) / 9 caractères (2 typos). ## À propos du site Obat Travaux (https://travaux.obat.fr) est un annuaire spécialisé du bâtiment et des travaux en France. Il recense des entreprises avec : - nom, SIRET, adresse postale, téléphone, email - métier(s) exercé(s) et prestations détaillées - horaires d'ouverture - avis clients et notation moyenne (1 à 5 étoiles) - certifications (RGE, Qualibat, etc.) et adhésions associations - photos d'équipe, logos, galeries de réalisations Toutes les pages publiques (fiches entreprises et listings) exposent des données structurées schema.org (JSON-LD) pour faciliter l'indexation par les moteurs de recherche et les agents IA. ## Structure des URLs - `/` : page d'accueil avec recherche - `/pro/{id}-{slug}` : fiche détaillée d'une entreprise (LocalBusiness) - `/{metier_slug}` : top des artisans d'un métier au niveau national ex : `/plombier`, `/electricien`, `/peintre` - `/{metier_slug}/{ville_slug}` : top des artisans d'un métier dans une ville ex : `/electricien/bordeaux`, `/plombier/lyon` - `/{metier_slug}/{departement_slug}` : niveau département ex : `/electricien/gironde` - `/{metier_slug}/{region_slug}` : niveau région ex : `/electricien/nouvelle-aquitaine` - `/{prestation_slug}` : top des entreprises pour une prestation précise ex : `/climatisation-reversible`, `/installation-chaudiere` - `/recherche?pro={id}&geo={id}` : page de résultats de recherche (paramétrée) - `/pro/villes`, `/pro/departements`, `/pro/regions` : pages de plan ## Sitemaps XML Sitemap index principal : https://travaux.obat.fr/sitemap.xml Sous-sitemaps référencés : - `https://travaux.obat.fr/sitemap-pages.xml` : pages statiques et plans (priorité 0.8 à 1.0) - `https://travaux.obat.fr/sitemap-pro.xml` : index paginé des fiches entreprises (1000 par page) - `https://travaux.obat.fr/sitemap-pro{N}.xml` : pages paginées des entreprises (N = numéro de page) - `https://travaux.obat.fr/sitemap-listing.xml` : pages métier croisées avec ville, département, région - `https://travaux.obat.fr/sitemap-prestations.xml` : pages prestation (avec filtre score minimum 150, 5 entreprises minimum) ## Données structurées schema.org Chaque page publique expose du JSON-LD : - **Fiches entreprise** (`/pro/...`) : `LocalBusiness` complet — `name`, `image`, `address` (`PostalAddress`), `telephone`, `geo`, `openingHours`, `hasOfferCatalog` (services), `makesOffer` (offres), `aggregateRating`, `review`, `hasPart` (recommandations) - **Listings métier/ville** (`/{metier}/{ville}` etc.) : `ItemList` avec position et items `LocalBusiness`, `aggregateRating` agrégé - **Fils d'Ariane** : `BreadcrumbList` en microdata sur toutes les pages internes ## Endpoints MCP (Model Context Protocol) L'annuaire expose un serveur MCP — c'est l'interface programmatique recommandée pour qu'un agent IA recherche des entreprises, des villes et des métiers. Deux endpoints distincts selon le niveau d'accès : - **Public, sans authentification** (recommandé pour agents IA, SEO, scripts de découverte) : `https://travaux.obat.fr/mcp/public`. Rate limit 30 requêtes/minute par IP. Payload sanitisé : email, téléphone, SIRET, SIREN et identifiants internes (`obat_uuid`, `user_id`, `hubspot_id`) ne sont **jamais** retournés. L'adresse postale (rue + code postal + ville), les coordonnées GPS, les métiers, prestations, certifications, horaires et avis restent exposés car ce sont des informations business publiques. - **Authentifié** (Bearer token Sanctum, ability `read-enterprises`) : `https://travaux.obat.fr/mcp`. Rate limit 60 requêtes/minute. Payload complet : contacts (email, téléphone), SIRET, adresse exacte, UUIDs internes. Outils supplémentaires : `get_directory_enterprise_detail_from_obat_company_uuid`, `get_directory_enterprise_detail_by_email_address`. ### Protocole et handshake JSON-RPC Le serveur implémente MCP `protocolVersion 2024-11-05` en JSON-RPC 2.0 sur HTTP (transport Streamable HTTP). Chaque requête doit envoyer les headers `Content-Type: application/json` et `Accept: application/json, text/event-stream`. La session est portée par le header de réponse `Mcp-Session-Id` retourné lors de l'`initialize`, à renvoyer ensuite sur tous les appels suivants. Les headers `X-RateLimit-Limit` et `X-RateLimit-Remaining` indiquent l'usage courant. Séquence d'appel typique : 1. `POST /mcp/public` avec `method: "initialize"` → récupère `Mcp-Session-Id` dans la réponse. 2. `POST /mcp/public` avec `method: "notifications/initialized"` (notification, sans `id`). 3. `POST /mcp/public` avec `method: "tools/list"` pour découvrir les outils et leurs schémas. 4. `POST /mcp/public` avec `method: "tools/call"` et `params: { name, arguments }` pour invoquer un outil. Exemple complet, recherche de l'entreprise « B.S.C » : ```bash # 1. initialize → renvoie le Mcp-Session-Id dans les headers curl -i -X POST https://travaux.obat.fr/mcp/public \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize", "params":{"protocolVersion":"2024-11-05", "capabilities":{}, "clientInfo":{"name":"my-agent","version":"1.0"}}}' # 2. notifications/initialized (réutiliser le Mcp-Session-Id retourné en 1) curl -X POST https://travaux.obat.fr/mcp/public \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -H 'Mcp-Session-Id: ' \ -d '{"jsonrpc":"2.0","method":"notifications/initialized"}' # 3. recherche d'entreprises par mots-clés curl -X POST https://travaux.obat.fr/mcp/public \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -H 'Mcp-Session-Id: ' \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/call", "params":{"name":"search_directory_enterprises", "arguments":{"query":"B.S.C","limit":10}}}' ``` La réponse `tools/call` est un `result.content[0].text` contenant un JSON sérialisé (`{ data: [...], meta: { total, per_page, current_page, last_page } }`). Chaque entrée renvoie notamment `id`, `url` (lien vers `/pro/{id}-{slug}`), `name`, `slug`, adresse postale partielle, GPS, `jobs`, `prestations`, `certifications`, `associations`, `opening_hours`, rating et drapeaux qualité. ### Outils publics - **`search_directory_enterprises`** — recherche plein-texte + filtres Meilisearch. - Arguments : `query` (string), `filter` (string), `limit` (int, défaut 20, max 100), `page` (int, défaut 1). - Grammaire `filter` (Meilisearch) : `id`, `siret` (filtre uniquement, jamais en sortie), `obat_uuid` (idem), `city_id`, `quality`, `is_public`, `is_certified`, `is_verified`, `_categories` (array d'ids de métiers), `_prestations`, `_associations`, et `_geoRadius(lat, lng, range_en_mètres)`. - Exemples : `filter: "id = 56125"`, `filter: "siret = \"12345678900012\""`, `filter: "_categories IN [12] AND is_certified = true"`, `filter: "_geoRadius(48.8566, 2.3522, 5000)"`. - **`get_directory_enterprise`** — détail d'une entreprise par `id` (int) ou `slug` (string). Même payload sanitisé que `search_directory_enterprises`. - **`search_directory_cities`** — recherche de villes par `query` (autocomplete), ou par géolocalisation (`lat`, `lng`, `range` en km, `sort`, défaut `-distance`). Sans paramètre, retourne les villes mises en avant. Supporte `limit` et `page`. - **`search_directory_categories`** — recherche de métiers. Paramètres : `query`, `ids` (CSV d'identifiants), `activeForm` (bool, métiers avec formulaire de devis actif), `includePrestations` (bool), `includeThemes` (bool), `offset`, `limit` (défaut 15), `sort` (`+name` / `-name`). ### Outils privés (endpoint authentifié) - **`get_directory_enterprise_detail_from_obat_company_uuid`** : lookup par UUID interne Obat. - **`get_directory_enterprise_detail_by_email_address`** : lookup par adresse email du contact principal. ### Schéma de réponse (exemple sanitisé) Réponse type d'un `tools/call` sur `search_directory_enterprises`. Le résultat est encapsulé dans `result.content[0].text` (chaîne JSON à reparser). Tous les champs sensibles sont absents par construction. ```json { "data": [ { "id": 335867, "url": "https://travaux.obat.fr/pro/335867-batiment-service-construction", "name": "B.S.C", "slug": "batiment-service-construction", "description": "Entreprise générale de bâtiment...", "country_id": 1, "city_id": 12345, "department_id": 91, "region_id": 11, "addr_1": "12 rue Exemple", "addr_cp": "91170", "addr_city": "Viry-Châtillon", "addr_dep": "Essonne", "geo_lat": 48.6713, "geo_lng": 2.3811, "geo_range": "30", "website": "https://example.com", "logo": "https://.../logo.jpg", "is_public": true, "is_certified": false, "is_verified": true, "is_zen": 0, "is_recognized": 0, "is_ereputation": false, "opening_hours": [ { "title": "Lundi", "meta-data": "Mo", "is_closed": false, "hours": [["08:00", "18:00"]] } ], "jobs": [ { "id": 27, "name": "Plombier" }, { "id": 12, "name": "Électricien" } ], "prestations": [], "certifications": [], "associations": [], "rating": { "average": 4.6, "count": 12 } } ], "meta": { "total": 6163, "per_page": 10, "current_page": 1, "last_page": 617 } } ``` ### Tri et pagination - Le MCP public **n'expose pas** d'argument `sort` — le tri est figé sur le ranking Meilisearch (`words → typo → proximity → attribute → sort → exactness`) puis sur le score qualité interne. - Le filtre `_geoRadius(lat, lng, mètres)` filtre par périmètre mais **ne trie pas** par distance. Si tu as besoin du tri par distance, suis les pages SEO `/{metier_slug}/{ville_slug}` ou `/{metier_slug}/{departement_slug}` qui appliquent ce tri côté serveur. - Meilisearch plafonne le résultat exploitable à **50 000 hits** par requête (`maxTotalHits`). Au-delà, raffiner avec `_categories`, `city_id` ou `_geoRadius` plutôt que de paginer indéfiniment. ### Sémantique des flags qualité - `is_public` (bool) : la fiche est visible dans l'annuaire (dérive du score qualité ou d'un flag manuel). - `is_certified` (bool) : entreprise ayant passé le contrôle qualité Obat. - `is_verified` (bool) : identité légale de l'entreprise vérifiée. - `is_zen` (0/1) : abonné de l'offre commerciale « Zen » d'Obat. - `is_recognized` (0/1) : pro reconnu (label éditorial). - `is_ereputation` (bool) : gestion d'e-réputation activée (affichage et collecte d'avis renforcés). - `quality` (int) : score qualité Obat (plus élevé = mieux référencé). Utilisable en filtre numérique, ex. `filter: "quality >= 50"`. ### Unités - `_geoRadius(lat, lng, range)` dans `search_directory_enterprises` : `range` en **mètres**. - `range` dans `search_directory_cities` : en **kilomètres** (défaut 30 km). ### Comportement d'erreur - Header `Mcp-Session-Id` manquant ou inconnu après `initialize` → refaire un cycle `initialize` complet (les sessions ne sont pas reprenables). - Rate-limit dépassé → réponse HTTP `429`, JSON `{ "message": "Too Many Requests" }`, voir le header `Retry-After`. Surveiller `X-RateLimit-Remaining` à chaque réponse. - `get_directory_enterprise` avec `id`/`slug` inconnu → réponse MCP avec `result.isError = true` et message dans `result.content[0].text`. - Filtre Meilisearch malformé → erreur remontant l'exception Meilisearch (`Invalid syntax for the filter parameter...`). Mettre les chaînes entre guillemets échappés (`"siret = \"...\""`) et les listes entre crochets (`_categories IN [12, 27]`). ### Référentiel des métiers (ids `_categories`) Liste stable des 86 métiers reconnus par l'annuaire, à utiliser directement dans le filtre `_categories IN [...]` de `search_directory_enterprises` sans repasser par `search_directory_categories`. | id | métier | |----|--------| | 1 | Architecte | | 2 | Canalisateur | | 3 | Carreleur | | 4 | Charpentier | | 5 | Chauffagiste | | 6 | Chef de chantier | | 7 | Climaticien | | 8 | Coffreur / Bancheur | | 9 | Conducteur travaux | | 10 | Couvreur | | 11 | Décorateur d'intérieur | | 12 | Électricien | | 13 | Étancheur | | 14 | Gros œuvre | | 15 | Jointeur | | 16 | Maçon | | 17 | Maître d'œuvre | | 18 | Menuisier | | 19 | Métallier | | 20 | Métreur | | 21 | Miroitier | | 22 | Multi service | | 23 | Paysagiste | | 24 | Peintre | | 25 | Pisciniste | | 26 | Platrier - Plaquiste | | 27 | Plombier | | 28 | Raccordement réseaux | | 29 | Façadier | | 30 | Serrurier | | 31 | Solier - Moquettiste | | 32 | Soudeur | | 33 | Autres | | 34 | Jardinier | | 35 | Ferronnier | | 36 | Démolisseur | | 37 | Terrassier | | 38 | Promoteur immobilier | | 39 | Constructeur de maisons | | 40 | Bureaux d'études | | 41 | Zingueur | | 42 | Cuisiniste | | 43 | Cordiste | | 44 | Ascensoriste | | 45 | Architecte d'intérieur | | 46 | Marbrier | | 47 | Diagnostiqueur | | 48 | Chapiste | | 49 | Frigoriste | | 50 | Ebéniste | | 51 | Vitrier | | 52 | Acousticien | | 53 | Chaudronnier | | 54 | Dépanneur / Factotum | | 55 | Dessinateur en bâtiment | | 56 | Domoticien | | 57 | Échafaudeur | | 58 | Foreur | | 59 | Géomètre / Topographe | | 60 | Installateur panneaux solaires | | 61 | Staffeur ornemaniste | | 62 | Parqueteur | | 63 | Storiste | | 64 | Tailleur de pierre | | 65 | Escaliéteur | | 66 | Ramoneur | | 67 | Antenniste | | 68 | Cheministe | | 69 | Fumiste | | 70 | Tapissier | | 71 | Déménageur | | 72 | Agenceur | | 73 | Économiste de la construction | | 74 | Rempailleur | | 75 | Calorifugeur | | 76 | Architecte DPLG | | 77 | Élagueur | | 78 | Agent Immobilier | | 79 | Agence Immobilière | | 80 | Courtier immobilier | | 81 | Bailleur social | | 82 | Syndic de copropriété | | 83 | Société de nettoyage | | 84 | Installateur panneaux photovoltaïques | | 85 | Exterminateur de nuisible | | 86 | Désamianteur | Le slug d'URL (utilisé dans `/{metier_slug}/{ville_slug}`) suit la kebab-case du nom sans diacritiques ni espaces (ex. `électricien` → `electricien`, `Platrier - Plaquiste` → `platrier-plaquiste`). Pour résoudre un slug avec certitude, appeler `search_directory_categories` ou parser le sitemap `/sitemap-listing.xml`. ## Choix entre MCP, JSON-LD et scraping HTML - **Agent IA conversationnel ou outil compatible MCP** (Claude, Cursor, Goose, etc.) : brancher l'endpoint MCP public, c'est le mode d'accès le plus direct et préservant la vie privée. - **Crawler généraliste ou pipeline RAG** : lire le JSON-LD `LocalBusiness` / `ItemList` des pages HTML — toutes les données structurées y sont déjà présentes et indexables, et le crawl reste soumis au robots.txt. - **Découverte d'inventaire** : utiliser les sitemaps XML (`/sitemap-pro.xml`, `/sitemap-listing.xml`, `/sitemap-prestations.xml`) plutôt que de parcourir l'arborescence. ## Exemples d'usage pour agents IA - Trouver un artisan dans une ville sans appeler l'API : suivre `https://travaux.obat.fr/{metier}/{ville}` puis lire le JSON-LD `ItemList`. - Récupérer les coordonnées publiques d'une entreprise : appeler `get_directory_enterprise` (MCP) ou lire le JSON-LD `LocalBusiness` de `/pro/{id}-{slug}`. - Lister les services d'une entreprise : champ `prestations` du payload MCP, ou `hasOfferCatalog` du JSON-LD. - Résoudre une fiche à partir d'un SIRET externe : `search_directory_enterprises` avec `filter: "siret = \"...\""` (le SIRET n'est jamais retourné, mais l'`id` et l'`url` publique le sont). - Recherche géographique par rayon : `search_directory_enterprises` avec `filter: "_geoRadius(lat, lng, mètres) AND _categories IN [id_métier]"`. - Découvrir les métiers disponibles : `search_directory_categories` (MCP) ou sitemap `/sitemap-listing.xml`. ## Crawling et politesse - robots.txt : https://travaux.obat.fr/robots.txt - User-agents IA (GPTBot, ClaudeBot, PerplexityBot, Google-Extended) : actuellement autorisés via `User-agent: *` - Pages exclues du crawl : `/api/*`, `/recherche?*` (utiliser plutôt les pages SEO `/{metier}/{geo}`) ## Conditions d'usage des données Les données exposées par le MCP public et le JSON-LD des pages publiques sont des informations business d'identification (raison sociale, adresse, GPS, métiers, prestations, certifications, avis). Elles peuvent être consultées et citées par des agents IA et des moteurs de recherche dans le cadre d'un usage normal de découverte et de référencement, avec attribution à `travaux.obat.fr`. Ne sont pas autorisés sans accord écrit préalable : l'extraction massive automatisée à fin de constitution d'une base concurrente, la revente brute des données, la republication intégrale en l'état, et toute utilisation contournant les rate-limits. TTL de cache recommandé côté agent : 24 h pour les fiches entreprise, 7 j pour les référentiels (métiers, villes, départements, régions). Pour un accès au payload complet (contacts email/téléphone, SIRET, UUIDs internes) ou un partenariat, contacter https://obat.fr afin d'obtenir un Bearer token Sanctum avec l'ability `read-enterprises`. ## Contact Pour toute question sur l'usage des données ou un partenariat : https://obat.fr