# API Bridge (tools.epsimo.org): reference for AI agents > API Bridge is a credit-metered REST API (and MCP server) for B2B company data: website qualification, one-call enrichment, professional email discovery, page text, questions about a website and search in the official French company registry. Generated from the live OpenAPI document and cost table. ## Quick start 1. Get a free API key at https://tools.epsimo.org/#signup (100 free credits per month). 2. Call `GET /usage` to check the balance. 3. Send JSON with the key in the `x-token` header: ```bash curl -X POST https://tools.epsimo.org/qualify \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr"}' ``` ## Authentication - Send the key in the `x-token` header on every REST call. The MCP endpoint also accepts `Authorization: Bearer `. - Keys look like `ab_live_...`; create one at https://tools.epsimo.org/#signup. - Never put the key in a URL or a query string. - A key must have accepted the current terms of service (https://tools.epsimo.org/legal/terms), otherwise metered calls return 403. ## Credits and pricing Cost per successful call (failed calls are not billed): - `qualify` (POST /qualify): 4 credits, 1 credit when served from the 7-day cache - `enrich` (POST /enrich): 8 credits, 3 credits when served from the 7-day cache - `question` (POST /question): 3 credits - `scrape` (POST /scrape): 2 credits - `email-verify` (POST /email-verify): 2 credits - `entreprise` (POST /entreprise): 1 credit - `entreprise-geo` (POST /entreprise/geo): 1 credit - `usage` (GET /usage): Free - `health` (GET /health): Free Free credits: 100 per month (free plan). Credit packs (one-time purchase, no subscription): - 1,000 credits: 40 EUR - 5,000 credits: 200 EUR - 10,000 credits: 400 EUR Price per credit: 0.04 EUR (cheapest pack). Buy at https://tools.epsimo.org/#pricing (Stripe checkout). Purchased credits are used after the free ones. Monthly quota (credits a key can spend per UTC month): - free: 10,000 credits - pro: 100,000 credits ## Rate limits - free keys: 60 requests per minute - pro keys: 300 requests per minute - Anonymous calls and public pages: 30 requests per minute per IP. - Over the limit: HTTP 429 `Rate limit exceeded` with `Retry-After: 60`. - Monthly quota reached: HTTP 429 `Monthly quota reached`, `Retry-After` = seconds until the next UTC month. ## Errors HTTP errors have the body `{"status": , "error_message": ""}`. - 402: `Insufficient credits: route costs N, available M. Buy credits via POST /billing/checkout`. - 403: `Invalid or missing token` (no or unknown key), `Forbidden for this key`, or `Terms of service not accepted. See /legal/terms and POST /legal/terms/accept`. - 422: request validation failed (FastAPI `detail` list). - 429: rate limit or monthly quota (see above); wait `Retry-After` seconds. - 502: the French company registry could not be reached (`/entreprise*`); other registry HTTP errors are passed through as `Entreprise API error: ...`. Not billed. - 503: the French company registry is busy (upstream rate limit), with `Retry-After`; not billed. `Service temporarily unavailable` when a dependency fails. Business failures of `/qualify`, `/question`, `/scrape` and `/enrich` come back as HTTP 200 with a `status` field in the body other than 200 (for example 400 for an invalid URL, 422 when the site cannot be read, 502 when `/enrich` found nothing). `/email-verify` uses a string `status` (`valid`, `not_found`, `suppressed`, `error`). Only successful outcomes are billed. ## Caching - `/qualify` and the company sections of `/enrich` are cached 7 days per normalised URL. A hit has `cached: true` and costs the cached price; `refresh: true` recomputes at full cost. - French registry responses (`/entreprise`, `/entreprise/geo`, the registry section of `/enrich`) are cached 60 minutes. ## Data provenance and limitations - French registry: API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0. - Qualification, answers and summaries are generated by a language model from the website text: estimates, not facts. - Emails are inferred from published address patterns and MX/SPF/DMARC checks; mailboxes are never probed. Opted-out domains and persons are never returned. - Personal email addresses found in page text are redacted. - `departement`, `code_postal`, `code_commune`, `region` and `epci` filter on establishments (offices), not on the head office: a result's `siege` (HQ) can be in another place. The offices that matched are in `matching_etablissements`; read them before telling a user where a company is located. ## Do not - Do not present inferred email addresses as verified: they are pattern-based and the mailbox is never probed. - Do not loop on 429: wait the number of seconds in `Retry-After`, then retry once. - Do not start a bulk run without calling `GET /usage` first to check the balance and the monthly quota. - Do not send fields that are not in the request tables: unknown fields are ignored, so a misspelled filter silently returns unfiltered results (invalid values get 422). - Do not put the API key in a URL or a query string, and do not log or echo it. - Do not treat a `siege` (head office) address as the place that matched an establishment filter: use `matching_etablissements`. ## MCP The API is also an MCP server (Streamable HTTP, JSON-RPC 2.0) at `https://tools.epsimo.org/mcp`, with one tool per endpoint, billed in the same credits. `initialize` and `tools/list` are public; every `tools/call` needs the key (`x-token: ` or `Authorization: Bearer `) and runs the REST route with the same auth, rate limits, credits and response body. Tools: `qualify_company`, `enrich_company`, `find_email`, `search_french_companies`, `search_companies_near`, `scrape_page`, `ask_website`, `get_usage`. Claude Code: ```bash claude mcp add --transport http api-bridge https://tools.epsimo.org/mcp --header "x-token: $API_KEY" ``` Claude Desktop only speaks stdio: bridge the HTTP endpoint with `mcp-remote` in `claude_desktop_config.json` (replace `ab_live_...` with your key): ```json { "mcpServers": { "api-bridge": { "command": "npx", "args": [ "-y", "mcp-remote", "https://tools.epsimo.org/mcp", "--header", "x-token:${API_KEY}" ], "env": { "API_KEY": "ab_live_..." } } } } ``` Cursor (`.cursor/mcp.json`) or any client that speaks HTTP (replace `ab_live_...` with your key): ```json { "mcpServers": { "api-bridge": { "type": "http", "url": "https://tools.epsimo.org/mcp", "headers": { "x-token": "ab_live_..." } } } } ``` ## Functions | Function id | Endpoint | Cost | Standalone file | | --- | --- | --- | --- | | `qualify` | `POST /qualify` | 4 credits, 1 cached | https://tools.epsimo.org/docs/qualify.md | | `enrich` | `POST /enrich` | 8 credits, 3 cached | https://tools.epsimo.org/docs/enrich.md | | `question` | `POST /question` | 3 credits | https://tools.epsimo.org/docs/question.md | | `scrape` | `POST /scrape` | 2 credits | https://tools.epsimo.org/docs/scrape.md | | `email-verify` | `POST /email-verify` | 2 credits | https://tools.epsimo.org/docs/email-verify.md | | `entreprise` | `POST /entreprise` | 1 credit | https://tools.epsimo.org/docs/entreprise.md | | `entreprise-geo` | `POST /entreprise/geo` | 1 credit | https://tools.epsimo.org/docs/entreprise-geo.md | | `usage` | `GET /usage` | free | https://tools.epsimo.org/docs/usage.md | | `health` | `GET /health` | free | https://tools.epsimo.org/docs/health.md | ## Company qualification (POST /qualify) Function id: `qualify`. Standalone file: https://tools.epsimo.org/docs/qualify.md ### Purpose Industry, target audience, market and a value proposition from any company website. ### When to use - You need the industry, target audience, market (B2B/B2C) and a one-sentence value proposition of a company from its website. ### Do not use when - You also need the registry record or the email domain: call `enrich` once instead of several functions. - You need raw page text (use `scrape`) or a free-form answer (use `question`). ### Endpoint - Method and URL: `POST https://tools.epsimo.org/qualify` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 4 credits, 1 credit when served from the 7-day cache ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `url` | string | yes | - | - | The company website URL to scrape and qualify. | | `refresh` | boolean | no | `false` | - | Bypass the 7-day result cache and recompute (full cost). | ### Example request ```bash curl -X POST https://tools.epsimo.org/qualify \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr"}' ``` Request body: ```json { "url": "https://acme.fr" } ``` ### Example response ```json { "value_proposition": "ACME builds cloud invoicing software for small businesses.", "industry": "Software", "target_audience": "business owners", "market": "B2B", "status": 200, "error_message": null } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - Results are cached 7 days per normalised URL; a cache hit has `cached: true` and costs the cached price. `refresh: true` recomputes at full cost. - HTTP 200 with a body `status` other than 200 (for example 422 when the site could not be read, 400 for an invalid URL) is a failure and is not billed. - The classification is generated by a language model from the site text: treat it as an estimate. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `qualify_company` on `https://tools.epsimo.org/mcp`. Arguments: `url` (required), `refresh`. ## One-call enrichment (POST /enrich) Function id: `enrich`. Standalone file: https://tools.epsimo.org/docs/enrich.md ### Purpose Registry record, qualification and a professional email in a single request. ### When to use - You need several facts about one company in a single call: French registry record, qualification, email domain and, with `first_name` + `last_name`, the likely contact email. ### Do not use when - You only need one section: the dedicated function is cheaper. - The company is not French and you only need the registry part. ### Endpoint - Method and URL: `POST https://tools.epsimo.org/enrich` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 8 credits, 3 credits when served from the 7-day cache ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `url` | string | yes | - | - | The company website URL. | | `first_name` | string or null | no | - | - | Contact first name (with last_name, enables the contact section). | | `last_name` | string or null | no | - | - | Contact last name (with first_name, enables the contact section). | | `siren` | string or null | no | - | pattern `^\d{9}$` | 9-digit SIREN; exact registry match when given. | | `company_name` | string or null | no | - | - | Company name for the registry search (default: derived from the URL). | | `refresh` | boolean | no | `false` | - | Bypass the 7-day result cache and recompute (full cost). | ### Example request ```bash curl -X POST https://tools.epsimo.org/enrich \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr","first_name":"Jean","last_name":"Dupont"}' ``` Request body: ```json { "url": "https://acme.fr", "first_name": "Jean", "last_name": "Dupont" } ``` ### Example response ```json { "url": "https://acme.fr", "registry": {"nom_complet": "ACME", "siren": "123456789", "...": "..."}, "qualification": {"industry": "Software", "market": "B2B", "...": "..."}, "email_domain": {"domain": "acme.fr", "provider": "OVHcloud", "...": "..."}, "contact": {"email": "jean.dupont@acme.fr", "confidence": "high", "...": "..."}, "errors": {}, "cached": false, "source": {"registry": "API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0"}, "status": 200, "error_message": null } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - Sections fail independently: a failed section is null and explained in `errors`, the rest is still usable. - `status: 502` in the body means neither the registry nor the qualification was found; that call is not billed. - Company-level sections are cached 7 days (`cached: true`, cached price); `refresh: true` recomputes at full cost. - `siren` (9 digits) gives an exact registry match; otherwise the registry is searched by `company_name` or the domain name. - The contact email is pattern-inferred, never probed (see `email-verify`). - Registry data source: API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `enrich_company` on `https://tools.epsimo.org/mcp`. Arguments: `url` (required), `siren`, `company_name`, `first_name`, `last_name`, `refresh`. ## Ask the site (POST /question) Function id: `question`. Standalone file: https://tools.epsimo.org/docs/question.md ### Purpose A short, grounded answer about a company website, without reading it yourself. ### When to use - You need a short answer about a company that is stated on its website (offer, pricing, positioning, customers). ### Do not use when - The answer is not likely to be on the page: the model answers from the page text only. - You need structured fields (use `qualify`). ### Endpoint - Method and URL: `POST https://tools.epsimo.org/question` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 3 credits ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `url` | string | yes | - | - | - | | `question` | string | yes | - | - | - | ### Example request ```bash curl -X POST https://tools.epsimo.org/question \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr","question":"What does the company sell?"}' ``` Request body: ```json { "url": "https://acme.fr", "question": "What does the company sell?" } ``` ### Example response ```json { "answer": "ACME sells cloud invoicing software to small businesses.", "status": 200, "error_message": null } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - HTTP 200 with a body `status` other than 200 (422 when the page could not be read or answered) is a failure and is not billed. - Personal email addresses in the answer are redacted. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `ask_website` on `https://tools.epsimo.org/mcp`. Arguments: `url` (required), `question` (required). ## Page extraction (POST /scrape) Function id: `scrape`. Standalone file: https://tools.epsimo.org/docs/scrape.md ### Purpose The main text of any page, direct fetch with a headless-browser fallback. ### When to use - You need the readable text of one page to process it yourself. ### Do not use when - You only need a summary or a classification (use `qualify` or `question`). ### Endpoint - Method and URL: `POST https://tools.epsimo.org/scrape` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 2 credits ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `url` | string | yes | - | - | The company website URL to scrape and qualify. | ### Example request ```bash curl -X POST https://tools.epsimo.org/scrape \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr"}' ``` Request body: ```json { "url": "https://acme.fr" } ``` ### Example response ```json { "text": "ACME builds cloud invoicing software for small businesses...", "length": 743, "method": "direct", "elapsed_s": 0.8, "status": 200, "error_message": null } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - Direct fetch first, headless-browser fallback when needed; `method` says which one was used. - Personal email addresses in the text are redacted. - HTTP 200 with a body `status` other than 200 is a failure and is not billed. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `scrape_page` on `https://tools.epsimo.org/mcp`. Arguments: `url` (required). ## Email discovery (POST /email-verify) Function id: `email-verify`. Standalone file: https://tools.epsimo.org/docs/email-verify.md ### Purpose The most likely professional address, inferred from published patterns — never probed. ### When to use - You need the most likely professional email of a named person at a company whose website you know. ### Do not use when - You need a verified, deliverable address: the result is pattern-inferred (`verification: "pattern_inferred"`) and the mailbox is never probed (no SMTP). - You do not have both the first and the last name. ### Endpoint - Method and URL: `POST https://tools.epsimo.org/email-verify` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 2 credits ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `url` | string | yes | - | - | The company website URL (used to derive the email domain). | | `first_name` | string | yes | - | - | First name of the contact. | | `last_name` | string | yes | - | - | Last name of the contact. | ### Example request ```bash curl -X POST https://tools.epsimo.org/email-verify \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://acme.fr","first_name":"Jean","last_name":"Dupont"}' ``` Request body: ```json { "url": "https://acme.fr", "first_name": "Jean", "last_name": "Dupont" } ``` ### Example response ```json { "domain_used": "acme.fr", "email": "jean.dupont@acme.fr", "confidence": "high", "pattern": "{f}.{l}", "verification": "pattern_inferred", "candidates": [ {"email": "jean.dupont@acme.fr", "pattern": "{f}.{l}", "score": 0.908}, {"email": "jdupont@acme.fr", "pattern": "{fi}{l}", "score": 0.027} ], "domain_checks": {"mx": ["mx1.mail.ovh.net"], "provider": "OVHcloud", "spf": true, "dmarc": true, "disposable": false}, "generic_emails": ["contact@acme.fr"], "cached": false, "status": "valid" } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - `confidence` (high / medium / low) and the ranked `candidates` tell how sure the pattern is; present the address as a guess, not a fact. - Only `status: "valid"` is billed; `not_found`, `error` and `suppressed` are free. - The suppression list is respected: an opted-out domain or person returns `email: null` and `status: "suppressed"`. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `find_email` on `https://tools.epsimo.org/mcp`. Arguments: `url` (required), `first_name` (required), `last_name` (required). ## French company search (POST /entreprise) Function id: `entreprise`. Standalone file: https://tools.epsimo.org/docs/entreprise.md ### Purpose 10M+ companies: name, activity, size, headcount, revenue and directors. ### When to use - You need French companies matching a name, activity code (NAF/APE), size, headcount, revenue, location or director name. ### Do not use when - You search around GPS coordinates (use `entreprise-geo`). - The company is not registered in France. ### Endpoint - Method and URL: `POST https://tools.epsimo.org/entreprise` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 1 credit ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `q` | string or null | no | - | - | Search terms: company name, address, directors, or elected officials. | | `departement` | string or null | no | - | - | Department code(s), 2-3 digits, comma-separated. Filters on establishments. | | `per_page` | integer | no | `10` | >= 1; <= 25 | Number of results per page (max 25). | | `activite_principale` | string or null | no | - | - | NAF/APE activity code(s), comma-separated. Applies to the legal unit only. | | `section_activite_principale` | string or null | no | - | - | Activity section letter(s), comma-separated. A=Agriculture, B=Extractive, C=Manufacturing, D=Energy, E=Water, F=Construction, G=Commerce, H=Transport, I=Hospitality, J=IT, K=Finance, L=Real estate, M=Scientific, N=Admin support, O=Public admin, P=Education, Q=Health, R=Arts, S=Other services, T=Households, U=Extra-territorial. | | `categorie_entreprise` | string or null | no | - | - | Company size category: PME, ETI, or GE. Comma-separated. | | `nature_juridique` | string or null | no | - | - | Legal category code(s) of the legal unit, comma-separated. | | `tranche_effectif_salarie` | string or null | no | - | - | Employee headcount bracket code(s), comma-separated. | | `etat_administratif` | string or null | no | - | - | Administrative status: 'A' = Active, 'C' = Ceased. | | `code_postal` | string or null | no | - | - | Postal code(s), 5 digits, comma-separated. Filters on establishments. | | `code_commune` | string or null | no | - | - | INSEE commune code(s), 5 chars, comma-separated. Filters on establishments. | | `region` | string or null | no | - | - | Region code(s), 2 digits, comma-separated. Filters on establishments. | | `epci` | string or null | no | - | - | EPCI SIREN number(s), comma-separated. Filters on establishments. | | `code_collectivite_territoriale` | string or null | no | - | - | Territorial collectivity code (Commune=INSEE code, EPCI=SIREN, Département=INSEE+'D', Région=INSEE). | | `nom_personne` | string or null | no | - | - | Last name of a stakeholder (director or elected official). | | `prenoms_personne` | string or null | no | - | - | First name(s) of a stakeholder (director or elected official). | | `date_naissance_personne_min` | string or null | no | - | - | Minimum birth date of a stakeholder (YYYY-MM-DD). | | `date_naissance_personne_max` | string or null | no | - | - | Maximum birth date of a stakeholder (YYYY-MM-DD). | | `type_personne` | string or null | no | - | - | Stakeholder type: 'dirigeant' (director) or 'elu' (elected official). | | `ca_min` | integer or null | no | - | - | Minimum revenue (chiffre d'affaires) in euros. | | `ca_max` | integer or null | no | - | - | Maximum revenue (chiffre d'affaires) in euros. | | `resultat_net_min` | integer or null | no | - | - | Minimum net income (résultat net) in euros. | | `resultat_net_max` | integer or null | no | - | - | Maximum net income (résultat net) in euros. | | `id_convention_collective` | string or null | no | - | - | Collective agreement identifier (IDCC) of an establishment. | | `id_finess` | string or null | no | - | - | FINESS geographic identifier of an establishment (9 digits). | | `id_rge` | string or null | no | - | - | RGE (Reconnu Garant de l'Environnement) identifier of an establishment. | | `id_uai` | string or null | no | - | - | UAI (Unité Administrative Immatriculée) identifier of an establishment. | | `convention_collective_renseignee` | boolean or null | no | - | - | Only companies with at least one establishment with a declared collective agreement. | | `egapro_renseignee` | boolean or null | no | - | - | Only companies with a professional gender equality index (Egapro). | | `est_achats_responsables` | boolean or null | no | - | - | Only companies with the RFAR (Relations Fournisseurs et Achats Responsables) label. | | `est_alim_confiance` | boolean or null | no | - | - | Only companies with at least one Alim'Confiance sanitary control result. | | `est_association` | boolean or null | no | - | - | Only associations (RNA identifier or association legal category). | | `est_bio` | boolean or null | no | - | - | Only companies with at least one establishment certified organic (Agence Bio). | | `est_collectivite_territoriale` | boolean or null | no | - | - | Only territorial collectivities. | | `est_entrepreneur_individuel` | boolean or null | no | - | - | Only sole proprietorships (entreprises individuelles). | | `est_entrepreneur_spectacle` | boolean or null | no | - | - | Only companies with a performing arts entrepreneur license. | | `est_ess` | boolean or null | no | - | - | Only social and solidarity economy (ESS) companies. | | `est_finess` | boolean or null | no | - | - | Only companies in the health/social sector (FINESS). | | `est_organisme_formation` | boolean or null | no | - | - | Only companies with a training organization establishment. | | `est_patrimoine_vivant` | boolean or null | no | - | - | Only companies with the Entreprise du Patrimoine Vivant (EPV) label. | | `est_qualiopi` | boolean or null | no | - | - | Only companies with Qualiopi certification. | | `est_rge` | boolean or null | no | - | - | Only companies recognized as Garant de l'Environnement (RGE). | | `est_siae` | boolean or null | no | - | - | Only work integration social enterprises (SIAE). | | `est_service_public` | boolean or null | no | - | - | Only public service organizations. Note: not exhaustive, may contain false positives. | | `est_l100_3` | boolean or null | no | - | - | Only administrations per article L.100-3 CRPA. Note: not exhaustive, may contain false positives. | | `est_societe_mission` | boolean or null | no | - | - | Only mission-driven companies (sociétés à mission). | | `est_uai` | boolean or null | no | - | - | Only companies with a UAI establishment (education sector). | | `page` | integer | no | `1` | >= 1 | Page number to return. | | `page_etablissements` | integer or null | no | - | >= 1 | Page number for the matching_etablissements sub-pagination. | | `limite_matching_etablissements` | integer or null | no | - | >= 1; <= 100 | Number of matching establishments to include per result (1-100). | | `minimal` | boolean or null | no | - | - | If true, returns a minimal response excluding secondary fields. Use 'include' to selectively add them back. | | `include` | string or null | no | - | - | Only with minimal=true. Comma-separated list of secondary fields to include: complements, dirigeants, finances, matching_etablissements, siege, score. | | `sort_by_size` | boolean or null | no | - | - | If true, sort results by company size (number of establishments). | ### Example request ```bash curl -X POST https://tools.epsimo.org/entreprise \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"q":"invoicing","departement":"69","per_page":10}' ``` Request body: ```json { "q": "invoicing", "departement": "69", "per_page": 10 } ``` ### Example response ```json { "results": [ {"nom_complet": "ACME", "siren": "123456789", "siege": {"code_postal": "69001", "libelle_commune": "Lyon"}} ], "total_results": 128, "page": 1, "per_page": 10, "total_pages": 13, "source": "API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0" } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - `departement`, `code_postal`, `code_commune`, `region` and `epci` filter on establishments (offices), not on the head office: a result's `siege` (HQ) can be in another place. The offices that matched are in `matching_etablissements`; read them before telling a user where a company is located. - Paginated: `page` and `per_page` (max 25); `total_results` and `total_pages` tell how many pages exist. `minimal: true` returns lean results. - Registry responses are cached 60 minutes. - Source: API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0 (the `source` field of every result). ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) - 503: The French company registry is busy (upstream rate limit). Not billed. Wait `Retry-After` seconds. Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `search_french_companies` on `https://tools.epsimo.org/mcp`. Arguments: `q`, `activite_principale`, `section_activite_principale`, `categorie_entreprise`, `departement`, `region`, `code_postal`, `code_commune`, `tranche_effectif_salarie`, `etat_administratif`, `ca_min`, `ca_max`, `page`, `per_page`, `minimal`. Other request fields from the table above are passed through. ## Geo search (POST /entreprise/geo) Function id: `entreprise-geo`. Standalone file: https://tools.epsimo.org/docs/entreprise-geo.md ### Purpose Every company around a GPS point, with radius and activity filters. ### When to use - You need French companies within a radius (max 50 km) of a GPS point. ### Do not use when - You search by name or administrative area (use `entreprise`). ### Endpoint - Method and URL: `POST https://tools.epsimo.org/entreprise/geo` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: 1 credit ### Request fields | Name | Type | Required | Default | Constraints | Description | | --- | --- | --- | --- | --- | --- | | `lat` | number | yes | - | - | Latitude of the search center point. | | `long` | number | yes | - | - | Longitude of the search center point. | | `radius` | number | no | `5` | >= 0; <= 50 | Search radius in km (max 50). | | `activite_principale` | string or null | no | - | - | NAF/APE activity code(s), comma-separated. | | `section_activite_principale` | string or null | no | - | - | Activity section letter(s), comma-separated (A-U). | | `limite_matching_etablissements` | integer or null | no | - | >= 1; <= 100 | Number of matching establishments to include per result (1-100). | | `minimal` | boolean or null | no | - | - | If true, returns a minimal response excluding secondary fields. | | `include` | string or null | no | - | - | Only with minimal=true. Comma-separated secondary fields: complements, dirigeants, finances, matching_etablissements, siege, score. | | `page` | integer | no | `1` | >= 1 | Page number to return. | | `per_page` | integer | no | `10` | >= 1; <= 25 | Number of results per page (max 25). | | `page_etablissements` | integer or null | no | - | >= 1 | Page number for the matching_etablissements sub-pagination. | | `sort_by_size` | boolean or null | no | - | - | If true, sort results by company size (number of establishments). | ### Example request ```bash curl -X POST https://tools.epsimo.org/entreprise/geo \ -H "x-token: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"lat":45.7640,"long":4.8357,"radius":2}' ``` Request body: ```json { "lat": 45.764, "long": 4.8357, "radius": 2 } ``` ### Example response ```json { "results": [ {"nom_complet": "ACME", "siren": "123456789", "siege": {"code_postal": "69001"}} ], "total_results": 42, "page": 1, "per_page": 10, "total_pages": 5, "source": "API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0" } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - Matches establishments (offices) near the point: a result's `siege` (HQ) can be far away; the offices that matched are in `matching_etablissements`. - Paginated like `entreprise` (max 25 per page). - Registry responses are cached 60 minutes. - Source: API Recherche d'Entreprises (DINUM), Licence Ouverte 2.0. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 422: Request validation failed (a field is missing, mistyped or out of range) - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) - 503: The French company registry is busy (upstream rate limit). Not billed. Wait `Retry-After` seconds. Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `search_companies_near` on `https://tools.epsimo.org/mcp`. Arguments: `lat` (required), `long` (required), `radius`, `activite_principale`, `page`, `per_page`, `minimal`. Other request fields from the table above are passed through. ## Balance and usage (GET /usage) Function id: `usage`. Standalone file: https://tools.epsimo.org/docs/usage.md ### Purpose Free and purchased credits, monthly quota and per-route usage this month. ### When to use - Before a batch: check `free_balance`, `purchased_balance`, `monthly_quota` and `credits_consumed` of the calling key. - After a batch: per-route requests and credits for the current UTC month. ### Do not use when - Polling it in a loop: it is free but still rate limited. ### Endpoint - Method and URL: `GET https://tools.epsimo.org/usage` - Auth: `x-token: $API_KEY` header (API key from https://tools.epsimo.org/#signup) - Cost: Free ### Request fields No request body. ### Example request ```bash curl https://tools.epsimo.org/usage \ -H "x-token: $API_KEY" ``` ### Example response ```json { "principal": "ab_live_1a2b3c4d", "month": "2026-10", "free_balance": 100, "purchased_balance": 1000, "monthly_quota": 10000, "credits_consumed": 12, "routes": { "qualify": {"requests": 2, "credits": 8}, "email_verify": {"requests": 2, "credits": 4} }, "status": 200, "error_message": null } ``` Trimmed: some fields are omitted; "..." marks omitted fields. ### Response notes - Free credits are spent before purchased credits. ### Errors - 402: Insufficient credits - 403: Invalid or missing token, forbidden key, or terms not accepted - 429: Rate limit exceeded or monthly quota reached (`Retry-After` seconds; 60 for the rate limit) Error body: `{"status": , "error_message": ""}`. ### MCP tool Tool `get_usage` on `https://tools.epsimo.org/mcp`. Arguments: none. ## Health Check (GET /health) Function id: `health`. Standalone file: https://tools.epsimo.org/docs/health.md ### Purpose Service status. Free, no key needed. ### When to use - You want to know whether the service is up. No key needed. ### Do not use when - Checking a key or a balance (use `usage`). ### Endpoint - Method and URL: `GET https://tools.epsimo.org/health` - Auth: none (public) - Cost: Free ### Request fields No request body. ### Example request ```bash curl https://tools.epsimo.org/health ``` ### Example response ```json { "status": "healthy", "timestamp": 1760000000.0 } ``` ### Response notes - `timestamp` is the server time in Unix seconds. ### Errors None besides network errors. ### MCP tool No MCP tool.