Agent docs
Docs your agent can read.
Plain Markdown for Claude, Cursor or any LLM agent. llms.txt is the
index, llms-full.txt holds every function, credit cost, rate limit, error and the MCP
setup in one file, and each function also has its own .md file. The raw schema is at
/openapi.json and agents can call the API directly through /mcp. Costs
and examples are generated from the live API, so they match what is billed.
Files and endpoints
https://tools.epsimo.org/llms.txtIndex (llmstxt.org): start herehttps://tools.epsimo.org/llms-full.txtEverything in one Markdown filehttps://tools.epsimo.org/docs/qualify.mdFunction qualifyhttps://tools.epsimo.org/docs/enrich.mdFunction enrichhttps://tools.epsimo.org/docs/question.mdFunction questionhttps://tools.epsimo.org/docs/scrape.mdFunction scrapehttps://tools.epsimo.org/docs/email-verify.mdFunction email-verifyhttps://tools.epsimo.org/docs/entreprise.mdFunction entreprisehttps://tools.epsimo.org/docs/entreprise-geo.mdFunction entreprise-geohttps://tools.epsimo.org/docs/usage.mdFunction usagehttps://tools.epsimo.org/docs/health.mdFunction healthhttps://tools.epsimo.org/openapi.jsonOpenAPI 3 schemahttps://tools.epsimo.org/mcpMCP server (Streamable HTTP)
Paste this into your agent
Read https://tools.epsimo.org/llms.txt, then fetch the per-function Markdown you need. Send the key in the x-token header ($API_KEY). Call GET /usage before bulk runs, wait for Retry-After on 429 and treat inferred emails as unverified.
llms-full.txt
The full reference, as served at /llms-full.txt.
# 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 <API key>`.
- 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": <int>, "error_message": "<text>"}`.
- 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: <API key>` or `Authorization: Bearer <API key>`) 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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": <int>, "error_message": "<text>"}`.
### 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.