service-public APIservice-public.fr ↗
Access structured French government guides, administrative procedures, and legal references from service-public.fr via 3 API endpoints covering search, autocomplete, and Fiches Pratiques.
What is the service-public API?
The service-public.fr API exposes 3 endpoints for querying the official French public service portal: full-text search across practical guides and news, autocomplete suggestions with direct-access link bundles, and structured retrieval of any Fiche Pratique or category page by its ID. The get_fiche_by_id endpoint returns parsed sections, breadcrumb navigation, introductory text, and raw page content for guides covering topics from housing and retirement to civil status and taxation.
curl -X GET 'https://api.parse.bot/scraper/ea53a944-7aff-4f88-9cab-0d2d959bd911/get_suggestions?query=retraite' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace service-public-fr-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
Service-Public.fr Cyberbullying API Client
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Any, Dict, List, Optional
class ParseClient:
"""Client for Service-Public.fr Cyberbullying API via Parse.bot"""
def __init__(self, api_key: Optional[str] = None):
self.base_url = "https://api.parse.bot"
self.scraper_id = "ea53a944-7aff-4f88-9cab-0d2d959bd911"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key not provided and PARSE_API_KEY not set")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""Make an API call to the Parse scraper endpoint"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
try:
if method == "GET":
response = requests.get(url, headers=headers, params=params, timeout=30)
elif method == "POST":
response = requests.post(url, headers=headers, json=params, timeout=30)
else:
raise ValueError(f"Unsupported method: {method}")
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"API Error: {e}")
raise
def get_suggestions(self, query: str) -> Dict[str, Any]:
"""Get autocomplete suggestions and direct access links for a search term"""
return self._call("get_suggestions", method="GET", query=query)
def search_site(self, query: str, page: int = 1) -> Dict[str, Any]:
"""Search service-public.fr for practical guides, news, and services"""
return self._call("search_site", method="GET", query=query, page=page)
def get_fiche_by_id(self, id: str) -> Dict[str, Any]:
"""Fetch a practical guide (Fiche Pratique) or category page by its ID"""
return self._call("get_fiche_by_id", method="GET", id=id)
def get_cyberbullying_guide(self) -> Dict[str, Any]:
"""Get the main cyberbullying guide (Fiche F32239)"""
return self._call("get_cyberbullying_guide", method="GET")
def get_emergency_contacts(self) -> Dict[str, Any]:
"""Get emergency contacts and support organizations for cyberbullying"""
return self._call("get_emergency_contacts", method="GET")
def get_legal_texts_cyberbullying(self) -> Dict[str, Any]:
"""Extract legal text references from the cyberbullying guide"""
return self._call("get_legal_texts_cyberbullying", method="GET")
def print_section(title: str, content: str, width: int = 80) -> None:
"""Print a formatted section header"""
print(f"\n{'='*width}")
print(f" {title}")
print(f"{'='*width}\n")
def main():
"""Practical workflow example: Search for cyberbullying, get guide, and extract key info"""
api_key = os.getenv("PARSE_API_KEY")
client = ParseClient(api_key)
# Step 1: Get suggestions for cyberbullying-related terms
print_section("STEP 1: Get Suggestions for 'cyberharcèlement'")
suggestions_response = client.get_suggestions("cyberharcèlement")
if suggestions_response.get("status") == "success":
data = suggestions_response.get("data", {})
print("Autocomplete suggestions:")
for suggestion in data.get("autocomplete", [])[:3]:
print(f" • {suggestion}")
# Show practical guides from direct access
fiches = data.get("acces_direct", {}).get("fiches_pratiques", [])
if fiches:
print("\nDirect access to practical guides:")
for fiche in fiches[:2]:
print(f" • {fiche.get('title')}")
print(f" URL: {fiche.get('url')}")
# Step 2: Search for related documents
print_section("STEP 2: Search for Justice-Related Documents")
search_response = client.search_site("justice harassment", page=1)
if search_response.get("status") == "success":
results = search_response.get("data", {}).get("results", [])
print(f"Found {len(results)} results\n")
# Process first 3 results
fiche_ids_to_fetch = []
for i, result in enumerate(results[:3], 1):
title = result.get("title", "Unknown")
doc_id = result.get("id", "")
print(f"{i}. {title}")
print(f" ID: {doc_id}")
if doc_id:
fiche_ids_to_fetch.append(doc_id)
# Step 3: Get the main cyberbullying guide
print_section("STEP 3: Get Main Cyberbullying Guide (F32239)")
guide_response = client.get_cyberbullying_guide()
if guide_response.get("status") == "success":
guide_data = guide_response.get("data", {})
print(f"Title: {guide_data.get('title')}")
print(f"URL: {guide_data.get('url')}")
# Show breadcrumb navigation
breadcrumb = guide_data.get("breadcrumb", [])
if breadcrumb:
print(f"\nBreadcrumb: {' > '.join(breadcrumb)}")
# Show first 2 sections
sections = guide_data.get("sections", [])
if sections:
print(f"\nGuide sections ({len(sections)} total):")
for section in sections[:2]:
title = section.get("title", "")
content = section.get("content", "")[:100]
print(f"\n {title}")
if content:
print(f" {content}...")
# Step 4: Get emergency contacts
print_section("STEP 4: Extract Emergency Contacts")
contacts_response = client.get_emergency_contacts()
if contacts_response.get("status") == "success":
contacts = contacts_response.get("data", {}).get("emergency_contacts", [])
print(f"Found {len(contacts)} emergency contacts:\n")
for contact in contacts:
if "number" in contact:
print(f"📞 {contact.get('number')}")
print(f" {contact.get('label')}\n")
elif "source_section" in contact:
print(f"📋 {contact.get('source_section')}")
content = contact.get("content", "")
if content:
# Show first 150 chars of content
preview = content[:150].replace("\n", " ")
print(f" {preview}...\n")
# Step 5: Get legal text references
print_section("STEP 5: Extract Legal Text References")
legal_response = client.get_legal_texts_cyberbullying()
if legal_response.get("status") == "success":
legal_refs = legal_response.get("data", {}).get("legal_references", [])
print(f"Legal references ({len(legal_refs)} found):\n")
for i, ref in enumerate(legal_refs, 1):
print(f"{i}. {ref}")
# Step 6: Fetch details for one of the search results
if fiche_ids_to_fetch:
print_section(f"STEP 6: Get Detailed Information for First Search Result (ID: {fiche_ids_to_fetch[0]})")
detail_response = client.get_fiche_by_id(fiche_ids_to_fetch[0])
if detail_response.get("status") == "success":
detail_data = detail_response.get("data", {})
print(f"Title: {detail_data.get('title')}")
print(f"ID: {detail_data.get('id')}")
sections = detail_data.get("sections", [])
if sections:
print(f"\nFirst section from this document:")
first_section = sections[0]
print(f" Title: {first_section.get('title')}")
content_preview = first_section.get("content", "")[:200]
print(f" Content: {content_preview}...")
if __name__ == "__main__":
main()Get autocomplete suggestions and direct access links for a search term on service-public.fr.
| Param | Type | Description |
|---|---|---|
| queryrequired | string | Search term to get autocomplete suggestions for (e.g. 'retraite', 'logement') |
{
"type": "object",
"fields": {
"acces_direct": "object containing categorized direct access links (fiches_pratiques, slf, actualites)",
"autocomplete": "array of suggested search terms"
},
"sample": {
"data": {
"acces_direct": {
"slf": [
{
"url": "/particuliers/vosdroits/R60625",
"title": "Frais de justice applicables au règlement des petits litiges en Europe"
}
],
"actualites": [
{
"url": "/particuliers/actualites/A18404",
"title": "Affaires civiles - Simplifiez vos démarches civiles grâce à l'application justice.fr"
}
],
"fiches_pratiques": [
{
"url": "/particuliers/vosdroits/N261",
"title": "Accès au droit et à la justice"
}
]
},
"autocomplete": [
"justice",
"commissaire de justice",
"décision de justice"
]
},
"status": "success"
}
}About the service-public API
Search and Autocomplete
The search_site endpoint accepts a query string and an optional page integer for pagination. Each result object in the results array includes a title, url, and id — the last of which can be passed directly to get_fiche_by_id for structured content retrieval. The response also returns total_results_on_page so you can detect sparse result pages without an extra request.
The get_suggestions endpoint returns two structures for a given query: an autocomplete array of suggested search terms, and an acces_direct object that groups direct-access links into three categories — fiches_pratiques, slf (services en ligne et formulaires), and actualites (news). This is useful for building typeahead interfaces or surfacing the most relevant official resources for a given topic without a full search.
Structured Guide Retrieval
get_fiche_by_id accepts an id parameter following the portal's naming conventions: F prefix for individual practical guides (e.g. F32239), N for category/node pages (e.g. N31146), and R for resource references. The response includes title, intro, breadcrumb (as an array of navigation labels), sections (each with a title and content field, mirroring the accordion structure of the source page), and raw_text for full-text use cases. The url field gives the canonical page address for citation or linking.
Coverage Scope
The API covers all publicly accessible content on service-public.fr: practical guides for individuals, professionals, and associations; administrative procedure descriptions; legal text references; and news items. Content is in French, reflecting the source portal. IDs for specific guides are discoverable through search_site result objects or from the portal's own URL structure.
The service-public API is a managed, monitored endpoint for service-public.fr — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when service-public.fr changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official service-public.fr API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Building a French administrative chatbot that retrieves structured Fiche Pratique sections by ID for accurate procedure answers
- Populating a typeahead search field with
get_suggestionsautocomplete terms and direct links for government topics - Indexing service-public.fr guides by crawling
search_siteresults page by page and fetching full content viaget_fiche_by_id - Extracting breadcrumb paths from guide responses to map the taxonomy of French administrative topics
- Monitoring updates to specific Fiches Pratiques by polling
get_fiche_by_idwith known IDs and comparingraw_textorsections - Surfacing relevant official French government resources within a legal-tech or HR compliance application using
search_sitequeries - Resolving administrative procedure details for a given topic by chaining
search_siteto retrieve IDs and thenget_fiche_by_idfor full structured content
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does service-public.fr have an official developer API?+
What does `get_fiche_by_id` return for a category page (N-prefix ID) versus an individual guide (F-prefix ID)?+
title, intro, breadcrumb, sections, raw_text, url, and id. Category pages (N-prefix) tend to have sections that list child guides rather than procedural steps, while individual guides (F-prefix) typically have accordion sections with detailed procedural or legal content. The breadcrumb array reflects the page's position in the site hierarchy in both cases.Does the API return content for pages that require a user account on service-public.fr?+
Can I filter search results by topic category or document type (e.g. only Fiches Pratiques for professionals)?+
search_site endpoint currently accepts a query string and a page number; there are no category, audience, or document-type filter parameters. Results mix guides, news, and services matching the query. You can fork the API on Parse and revise it to add filtering or faceted search capabilities against specific topic segments.Is there a way to list all available Fiche IDs without searching?+
search_site result objects or by knowing the ID from the portal's URL structure. You can fork the API on Parse and revise it to add a sitemap-traversal or category-crawl endpoint that enumerates guides systematically.