API URL vers Markdown#
L'endpoint POST /v1/convert/url-to-markdown convertit toute page web accessible publiquement en Markdown GitHub-Flavored propre, avec un bloc de métadonnées frontmatter YAML. Chaque page est rendue dans un vrai navigateur, puis passée dans un extracteur de lisibilité qui supprime le superflu (navigation, pieds de page, asides, scripts, formulaires, boutons), avant d'être sérialisée en Markdown avec des liens normalisés, des blocs de code délimités, et les URLs relatives résolues en URLs absolues. C'est exactement ce dont les pipelines d'ingestion LLM et RAG ont besoin, à la place du HTML brut. Les conversions s'exécutent en mode synchrone ou asynchrone par lot, et les résultats sont renvoyés sous forme d'octets Markdown bruts ou d'une URL de téléchargement présignée.
Endpoint#
POST /v1/convert/url-to-markdown
Content-Type : application/json
Format de sortie : Markdown (.md, UTF-8) avec un bloc frontmatter YAML en haut du fichier contenant les métadonnées de la page. Le format de sortie n'est pas configurable. Du Markdown avec frontmatter YAML est toujours produit.
Authentification#
Cet endpoint prend en charge l'authentification par clé privée et par clé publique.
Clé privée#
Incluez votre clé secrète dans l'en-tête X-API-Key. Utilisez cette méthode pour les appels serveur à serveur, où la clé n'est jamais exposée au client.
X-API-Key: sk_your_private_key
Clé publique avec JWT#
Pour une utilisation côté client, générez d'abord un token JWT avec votre clé publique, puis passez-le en tant que token Bearer.
Étape 1. Obtenir un token :
POST /v1/auth/token
X-API-Key: pk_your_public_key
Étape 2. Utiliser le token :
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Paramètres de requête#
Paramètres de premier niveau#
| Parameter | Type | Required | Default | Description | Plan Gating |
|---|---|---|---|---|---|
url |
string or string[] |
Oui | -- | Une chaîne URL unique ou un tableau d'URLs à convertir. Plusieurs URLs nécessitent le mode asynchrone. | -- |
async_mode |
boolean |
Non | false |
Exécute la conversion de manière asynchrone. Renvoie immédiatement un batch_id pour l'interrogation. Requis pour le traitement par lots (plusieurs URLs). |
Nécessite l'accès au mode asynchrone |
direct_download |
boolean |
Non | false |
Renvoie les octets Markdown bruts dans le corps de la réponse au lieu d'une réponse JSON avec une URL présignée. Forcé à true pour les clés publiques. Incompatible avec async_mode et plusieurs URLs. |
-- |
output_format |
boolean |
Non | false |
Quand true avec plusieurs URLs, regroupe tous les fichiers Markdown de sortie dans une archive ZIP unique. Nécessite plusieurs URLs. |
Nécessite l'accès à la sortie ZIP |
output_filename |
string |
Non | Généré automatiquement | Nom de fichier personnalisé pour le fichier de sortie. L'extension .md est ajoutée automatiquement. Format par défaut : {domain}_{timestamp}.md. |
-- |
job_id |
string |
Non | -- | ID de tâche fourni par le client pour la reprise après timeout. Clés publiques uniquement. Quand une conversion synchrone dépasse les limites de timeout du reverse proxy, le client peut interroger GET /v1/convert/status/{job_id} pour récupérer le résultat. Ignoré pour les clés privées. |
-- |
notification_email |
string |
Non | Email du propriétaire du projet | Adresse email à notifier lorsqu'une tâche asynchrone se termine. Clés privées uniquement. | -- |
callback_url |
string |
Non | -- | URL webhook qui recevra une requête POST lorsque la conversion se termine. Clés privées uniquement. | Nécessite l'accès aux webhooks |
Paramètres du navigateur et du rendu#
| Parameter | Type | Required | Default | Description | Plan Gating |
|---|---|---|---|---|---|
viewport_width |
integer |
Non | 1920 |
Largeur de la fenêtre d'affichage du navigateur en pixels. Affecte le contenu responsive et la variante de mise en page capturée avant l'extraction. | -- |
viewport_height |
integer |
Non | 1080 |
Hauteur de la fenêtre d'affichage du navigateur en pixels. Utilisée comme référence pour le rendu et le calcul des unités de viewport. | -- |
load_media |
boolean |
Non | true |
Attend que toutes les images et vidéos soient entièrement chargées avant l'extraction. Quand la valeur est false, l'extraction est plus rapide mais les images en chargement différé (lazy-loaded) peuvent conserver des valeurs src de substitution dans la sortie Markdown. |
-- |
enable_scroll |
boolean |
Non | true |
Fait défiler la page de haut en bas pour déclencher le chargement du contenu différé (chargeurs basés sur IntersectionObserver). | -- |
handle_sticky_header |
boolean |
Non | true |
Détecte les en-têtes collants/fixes et fait défiler la page vers le haut avant l'extraction afin de préserver correctement l'ordre du contenu. | -- |
handle_cookies |
boolean |
Non | true |
Ferme automatiquement les bannières de consentement aux cookies (OneTrust, Cookiebot, Didomi, Usercentrics, et bannières génériques) avant l'extraction. | -- |
wait_for_images |
boolean |
Non | true |
Attend que tous les éléments <img> terminent de charger (timeout de 5 secondes par image) afin que le texte alt et les valeurs src finales soient capturés correctement. |
-- |
wait_for_selector |
string |
Non | null |
Sélecteur CSS à attendre avant l'extraction. Renvoie 422 s'il n'apparaît jamais dans le délai wait_for_selector_timeout. Utile pour les SPA qui hydratent le contenu après le chargement. |
-- |
wait_for_selector_timeout |
integer |
Non | 10000 |
Millisecondes d'attente pour wait_for_selector (maximum 60000). |
-- |
block_ads |
boolean |
Non | false |
Interrompt les requêtes vers les domaines connus de publicité/traçage afin qu'ils ne se chargent jamais et ne ralentissent pas l'extraction. | -- |
block_media |
boolean |
Non | false |
Interrompt entièrement les requêtes d'images et audio/vidéo pour un rendu plus rapide et plus léger. Contrairement à load_media (qui contrôle uniquement l'attente), cela empêche totalement le téléchargement des médias. |
-- |
Authentification et requêtes personnalisées#
| Parameter | Type | Required | Default | Description | Plan Gating |
|---|---|---|---|---|---|
auth |
object |
Non | null |
Identifiants HTTP Basic Auth pour l'URL cible. Format : {"username": "...", "password": "..."}. Ne peut pas être utilisé en même temps qu'un en-tête personnalisé Authorization. |
Nécessite l'accès à l'authentification de base |
cookies |
array |
Non | null |
Tableau d'objets cookie à injecter avant la navigation. Maximum 50 cookies. Chaque cookie doit avoir name, value, et soit domain soit url. |
Nécessite l'accès à l'authentification de base |
headers |
object |
Non | null |
Dictionnaire d'en-têtes HTTP personnalisés envoyés avec chaque requête vers l'URL cible. Maximum 20 en-têtes. En-têtes bloqués : host, content-length, transfer-encoding, connection, upgrade, te, trailer. |
Nécessite l'accès à l'authentification de base |
single_page et pdf_options de l'endpoint url-to-pdf sont acceptés par souci de cohérence de forme des requêtes, mais n'ont aucun effet sur la sortie Markdown. Markdown n'a pas de notion de pages, de marges ou d'orientation.
Schéma de l'objet cookie#
Chaque élément du tableau cookies doit respecter cette structure :
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
Oui | -- | Nom du cookie. |
value |
string |
Oui | -- | Valeur du cookie. |
domain |
string |
Conditionnel | -- | Domaine du cookie. domain ou url doit être fourni. |
url |
string |
Conditionnel | -- | URL à associer au cookie. domain ou url doit être fourni. |
path |
string |
Non | "/" |
Chemin du cookie. Par défaut "/" quand domain est défini. |
Réponse#
Synchrone avec téléchargement direct (direct_download=true)#
Clé privée renvoie les octets Markdown bruts :
HTTP 200 OK
Content-Type: text/markdown; charset=utf-8
Content-Disposition: inline; filename="example_20260421_123456789.md"
X-Object-Key: env/files/{project_id}/url-to-markdown/example_20260421_123456789.md
X-File-Size: 8421
X-Conversion-Time: 6.3
X-Filename: example_20260421_123456789.md
(UTF-8 Markdown with YAML frontmatter)
Clé publique renvoie du JSON avec une URL présignée :
{
"presigned_url": "https://spaces.example.com/...",
"object_key": "env/files/{project_id}/url-to-markdown/example_20260421_123456789.md",
"filename": "example_20260421_123456789.md",
"file_size": 8421,
"conversion_time_seconds": 6.3,
"job_id": "client-provided-id"
}
Synchrone sans téléchargement direct (direct_download=false)#
Disponible uniquement avec les clés privées.
{
"presigned_url": "https://spaces.example.com/...",
"object_key": "env/files/{project_id}/url-to-markdown/example_20260421_123456789.md",
"filename": "example_20260421_123456789.md",
"file_size": 8421,
"conversion_time_seconds": 6.3
}
Mode asynchrone#
Renvoie immédiatement un batch_id pour l'interrogation.
HTTP 202 Accepted
{
"status": "processing",
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"url_count": 5,
"output_format": "individual"
}
Quand output_format=true (regroupement ZIP) :
{
"status": "processing",
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"url_count": 5,
"output_format": "zip"
}
Interrogation du statut de la tâche (clés publiques uniquement)#
Pour la reprise après timeout avec une clé publique :
GET /v1/convert/status/{job_id}
Authorization: Bearer <jwt_token>
| Status | Response |
|---|---|
| En cours | {"status": "processing"} |
| Succès | {"status": "success", "presigned_url": "...", "object_key": "..."} |
| Échec | {"status": "failed", "error": "..."} |
Interrogation du statut du lot (clés privées uniquement)#
Pour les tâches asynchrones par lot, interrogez avec le batch_id reçu dans la réponse 202 :
GET /v1/convert/batch/{batch_id}
X-API-Key: sk_your_private_key
Renvoie le statut agrégé, les statuts par URL, ainsi que des URLs de téléchargement présignées. Voir Interrogation du statut du lot pour le schéma complet de la réponse.
Charge utile du callback webhook#
Quand un callback_url est fourni, EnConvert envoie une requête POST à cette URL à la fin de la conversion.
Tâche avec une seule URL :
{
"job_id": "activity_id",
"status": "success",
"batch_id": "...",
"gcs_uri": "object_key",
"filename": "example_20260421_123456789.md",
"file_size": 8421
}
Tâche par lot :
{
"job_id": "activity_id",
"status": "success",
"batch_id": "...",
"total_tasks": 10,
"successful_tasks": 8,
"failed_tasks": 2,
"tasks": [
{"url": "https://example.com/page1", "status": "success", "filename": "page1.md"},
{"url": "https://example.com/page2", "status": "failed", "filename": null}
]
}
Format de sortie#
Chaque fichier Markdown commence par un bloc frontmatter YAML contenant les métadonnées de la page, suivi du corps de l'article extrait.
---
url: https://example.com/articles/my-post
title: My Post Title
description: A short summary from the meta description or og:description tag.
links:
- url: https://example.com/related
text: Related article
- url: https://example.com/about
text: About the author
images:
- url: https://example.com/hero.jpg
alt: Hero image alt text
- url: https://example.com/diagram.png
alt: Architecture diagram
---
# My Post Title
Opening paragraph of the article body, converted to GitHub-Flavored Markdown...
## A Section Heading
- List item one
- List item two
\`\`\`python
def example():
return "code blocks are fenced with language hints"
\`\`\`
[A link in the body](https://example.com/linked-page)

Champs du frontmatter#
| Field | Type | Description |
|---|---|---|
url |
string |
L'URL finale après redirections (ce n'est pas toujours l'URL que vous avez envoyée). |
title |
string |
Le titre de la page issu de <title>, avec repli sur le titre court détecté par Readability. |
description |
string |
La valeur de <meta name="description">, avec repli sur <meta property="og:description">. |
links |
array |
Chaque <a href> trouvé sur la page, avec les URLs absolues et le texte d'ancrage visible. |
images |
array |
Chaque <img src> trouvé sur la page, avec les URLs absolues et le texte alt. |
Conventions Markdown#
- Style de titre : ATX (
#,##,###) - Puces de liste :
- - Emphase :
*bold*,*italic*avec échappement de*et_dans le texte littéral - Retours à la ligne souples : deux espaces en fin de ligne (préservés dans la sortie)
- Blocs de code : délimités (
```) avec indices de langage détectés depuisclass="language-xxx",class="lang-xxx",class="highlight-source-xxx",data-lang, etdata-language - Liens :
[text](url)quand un texte d'ancrage est présent, forme autolink<url>quand l'ancrage est vide, les liens uniquement ancrés (#foo) et les liensjavascript:sont convertis en texte brut - Images :
, avectitlepréservé quand présent, avec repli surdata-srcquandsrcest absent (images en chargement différé) - Règles horizontales :
---
Fonctionnalités#
Extraction propre du contenu#
EnConvert utilise l'algorithme Readability (la même bibliothèque qui alimente le mode lecture de Firefox) pour isoler le contenu principal de l'article du reste de la page, puis applique une seconde passe de post-traitement pour produire du Markdown propre.
Supprimé avant la conversion :
- Navigation (
<nav>), pieds de page (<footer>), asides (<aside>) - Scripts (
<script>,<noscript>), styles (<style>), iframes, formulaires, boutons - SVG en ligne, canvas et éléments template
- Les attributs
style,class,id, et tous les gestionnaires d'événementson*
Préservé :
- Titres, paragraphes, listes, tableaux, citations, blocs de code
- Liens avec leur
hrefet leur texte d'ancrage (URLs absolues) - Images avec
alt,title, etsrcabsolu - Figures et figcaptions (les images en ligne y sont conservées)
Mode de capture claire#
Avant l'extraction, la page est rendue dans un vrai navigateur et nettoyée de la même manière que pour url-to-pdf :
- Bannières de consentement aux cookies : fermées automatiquement sur la page principale et les iframes (OneTrust, Cookiebot, Didomi, Usercentrics, et bannières génériques).
- Fermeture des modales et popups : les overlays sont fermés via la touche Échap, les boutons de fermeture ARIA, les boutons de fermeture basés sur des classes, et les boutons de dialogue basés sur des rôles.
- Révélation des animations au défilement : force la visibilité des éléments masqués par WOW.js, AOS, ScrollReveal, GSAP ScrollTrigger, et les classes d'animation génériques.
- Gestion des en-têtes collants : les en-têtes collants/fixes sont détectés et la page est ramenée en haut afin de préserver l'ordre du contenu.
Résolution des URLs absolues#
Chaque href et src relatif dans l'article extrait est résolu par rapport à l'URL finale de la page (après redirections), de sorte que la sortie Markdown contient toujours des liens absolus et cliquables, ce qui est utile pour les pipelines d'ingestion LLM qui verraient sinon des chemins relatifs cassés.
Les liens uniquement ancrés (#section), les liens javascript:, mailto:, et tel: ne sont pas réécrits. Les liens uniquement ancrés et les liens javascript: sont convertis en texte brut car ils n'ont aucun sens en dehors de la page d'origine.
Détection du langage des blocs de code#
Les blocs de code sont délimités avec un indice de langage détecté quand c'est possible :
<pre><code class="language-python">...</code></pre> → ```python
<pre data-lang="js">...</pre> → ```js
<pre><code class="highlight-source-shell">...</code></pre> → ```shell
Les classes correspondant à language-*, lang-*, highlight-source-*, et brush:* sont reconnues, ainsi que les attributs data-lang et data-language sur le <pre> et son <code> imbriqué. Si aucun indice n'est trouvé, le bloc est délimité sans étiquette de langage.
HTTP Basic Auth#
Passez auth avec username et password pour convertir des pages protégées par HTTP Basic Authentication.
{
"url": "https://staging.example.com/docs/article",
"auth": {
"username": "admin",
"password": "secret"
}
}
Injection de cookies#
Injectez jusqu'à 50 cookies avant le chargement de la page. Utile pour convertir des pages d'articles réservées aux membres ou spécifiques à une locale.
{
"url": "https://example.com/members/post",
"cookies": [
{"name": "session_id", "value": "abc123", "domain": "example.com"},
{"name": "locale", "value": "en-US", "domain": "example.com"}
]
}
En-têtes personnalisés#
Envoyez jusqu'à 20 en-têtes HTTP personnalisés avec chaque requête vers la page cible.
{
"url": "https://example.com/api-docs",
"headers": {
"X-Custom-Token": "my-token-value",
"Accept-Language": "en-US"
}
}
Chargement différé des images#
Quand load_media et enable_scroll sont activés (tous deux à true par défaut), le convertisseur fait défiler la page lentement pour déclencher les chargeurs différés, puis attend que toutes les images terminent de charger avant de capturer le HTML final. Cela garantit que les valeurs data-src ont été promues en véritables valeurs src et que la liste images du frontmatter est complète.
Définissez load_media=false pour une extraction plus rapide quand vous n'avez besoin que du corps textuel. Des valeurs src de substitution peuvent alors subsister dans la sortie.
Fonctionnalités de rendu supplémentaires#
- Normalisation des unités de viewport : les unités CSS de viewport (
vh,svh,lvh,dvh) sont converties en valeurs de pixels fixes avant l'extraction. - Mode furtif : masquage de l'empreinte du navigateur pour éviter la détection de bot sur les pages protégées.
- Interception des popups : ferme automatiquement tout nouvel onglet ou popup déclenché par la page.
- Contournement CSP : gère les restrictions Content Security Policy et Trusted Types qui bloqueraient sinon la manipulation de la page.
Restrictions liées au forfait d'abonnement#
| Feature | Founding | Indie | Studio | Enterprise |
|---|---|---|---|---|
| Conversion basique (URL unique, synchrone) | Oui | Oui | Oui | Oui |
| Options de viewport et de rendu | Oui | Oui | Oui | Oui |
| Mode asynchrone | Non | Oui | Oui | Oui |
| Traitement par lots (plusieurs URLs) | Non | Oui | Oui | Oui |
| Regroupement de sortie ZIP | Non | Non | Oui | Oui |
| Callbacks webhook | Non | Non | Oui | Oui |
| HTTP Basic Auth | Non | Oui | Oui | Oui |
| Injection de cookies | Non | Oui | Oui | Oui |
| En-têtes personnalisés | Non | Oui | Oui | Oui |
| Conversions mensuelles | 100 | Selon le forfait | Selon le forfait | Illimité |
| Limite de taille de lot | 0 | Selon le forfait | Selon le forfait | Illimité |
| Rétention des fichiers | 1 heure | Selon le forfait | Selon le forfait | Selon le forfait |
Mode asynchrone#
Le mode asynchrone est utile pour les conversions longues ou lors de la conversion de plusieurs URLs.
Fonctionnement#
- Envoyez une requête avec
async_mode=true(ou passez plusieurs URLs, ce qui active automatiquement le mode asynchrone). - L'API renvoie immédiatement un HTTP 202 avec un
batch_idet unurl_count. - Chaque URL est convertie en arrière-plan, envoyée vers le stockage, et suivie individuellement.
- Suivez l'achèvement via l'interrogation du statut du lot, la notification par email, ou le callback webhook.
Notification par email#
Par défaut, un email d'achèvement est envoyé à l'adresse email du propriétaire du projet. Remplacez-la avec notification_email :
{
"url": ["https://example.com/page1", "https://example.com/page2"],
"async_mode": true,
"notification_email": "[email protected]"
}
Callback webhook#
Fournissez un callback_url pour recevoir une notification POST automatique à l'achèvement :
{
"url": ["https://example.com/page1", "https://example.com/page2"],
"async_mode": true,
"callback_url": "https://your-server.com/webhook/enconvert"
}
Le webhook est envoyé avec un timeout de 30 secondes et considère les codes HTTP 200, 201, 202, et 204 comme une livraison réussie.
Traitement par lots et en masse#
Convertissez plusieurs URLs en une seule requête. Nécessite le mode asynchrone et une clé privée.
Sortie individuelle (par défaut)#
Chaque URL produit un fichier Markdown séparé :
{
"url": [
"https://example.com/post-1",
"https://example.com/post-2",
"https://example.com/post-3"
],
"async_mode": true
}
Sortie en archive ZIP#
Regroupez tous les fichiers Markdown dans une archive ZIP unique :
{
"url": [
"https://example.com/post-1",
"https://example.com/post-2",
"https://example.com/post-3"
],
"async_mode": true,
"output_format": true,
"output_filename": "blog-archive"
}
Le fichier ZIP est nommé {output_filename}_{timestamp}.zip ou batch_{timestamp}.zip si aucun nom personnalisé n'est fourni.
Exemples de code#
Python (clé privée)#
import requests
response = requests.post(
"https://api.enconvert.com/v1/convert/url-to-markdown",
headers={"X-API-Key": "sk_your_private_key"},
json={
"url": "https://example.com/articles/my-post",
"direct_download": True
}
)
response.raise_for_status()
markdown_text = response.content.decode("utf-8")
print(markdown_text)
PHP (clé privée)#
$ch = curl_init("https://api.enconvert.com/v1/convert/url-to-markdown");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: sk_your_private_key"
],
CURLOPT_POSTFIELDS => json_encode([
"url" => "https://example.com/articles/my-post"
])
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo $data["presigned_url"];
Node.js (clé privée)#
const response = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "sk_your_private_key"
},
body: JSON.stringify({
url: "https://example.com/articles/my-post"
})
});
const data = await response.json();
console.log(data.presigned_url);
Go (clé privée)#
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]interface{}{
"url": "https://example.com/articles/my-post",
})
req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/url-to-markdown", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "sk_your_private_key")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(respBody))
}
JavaScript côté navigateur (clé publique)#
// Step 1: Get a JWT token
const tokenRes = await fetch("https://api.enconvert.com/v1/auth/token", {
method: "POST",
headers: { "X-API-Key": "pk_your_public_key" }
});
const { token } = await tokenRes.json();
// Step 2: Convert URL to Markdown (public keys receive raw bytes)
const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({
url: "https://example.com/articles/my-post"
})
});
const markdown = await convertRes.text();
console.log(markdown);
React (clé publique)#
import { useState } from "react";
function UrlToMarkdown() {
const [loading, setLoading] = useState(false);
const [markdown, setMarkdown] = useState("");
async function convertUrl() {
setLoading(true);
try {
// Get JWT token
const tokenRes = await fetch("https://api.enconvert.com/v1/auth/token", {
method: "POST",
headers: { "X-API-Key": "pk_your_public_key" }
});
const { token } = await tokenRes.json();
// Convert
const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-markdown", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({ url: "https://example.com/articles/my-post" })
});
setMarkdown(await convertRes.text());
} finally {
setLoading(false);
}
}
return (
<div>
<button onClick={convertUrl} disabled={loading}>
{loading ? "Converting..." : "Convert to Markdown"}
</button>
{markdown && <pre>{markdown}</pre>}
</div>
);
}
export default UrlToMarkdown;
Réponses d'erreur#
| Status | Condition |
|---|---|
400 Bad Request |
Paramètre url manquant ou vide |
400 Bad Request |
output_format=true avec une seule URL (plusieurs URLs requises) |
400 Bad Request |
direct_download=true avec plusieurs URLs |
400 Bad Request |
direct_download=true avec async_mode=true |
400 Bad Request |
Objet auth invalide (username ou password manquant) |
400 Bad Request |
cookies invalide (n'est pas un tableau, dépasse 50 entrées, champs requis manquants) |
400 Bad Request |
headers invalide (n'est pas un objet, dépasse 20 entrées, noms d'en-tête bloqués, valeurs non textuelles) |
400 Bad Request |
Conflit entre auth et l'en-tête personnalisé Authorization |
400 Bad Request |
Clé publique tentant plusieurs URLs |
401 Unauthorized |
Clé API / token JWT manquant ou invalide |
402 Payment Required |
Quota mensuel d'ops épuisé |
402 Payment Required |
Le lot dépasserait le quota mensuel d'ops restant |
402 Payment Required |
Limite de stockage atteinte |
403 Forbidden |
Endpoint non inclus dans les endpoints autorisés de la clé API |
403 Forbidden |
Fonctionnalité non disponible sur le forfait actuel (asynchrone, webhook, ZIP, basic auth) |
403 Forbidden |
La taille du lot dépasse la limite du forfait |
404 Not Found |
ID de tâche introuvable (lors de l'interrogation du statut) |
500 Internal Server Error |
Échec de la conversion (crash du navigateur, erreur de navigation, échec de l'extraction) |
Limites#
| Limit | Value |
|---|---|
| Timeout de navigation de page | 60 secondes |
| Timeout de chargement par image | 5 secondes |
| Timeout de fermeture de la bannière cookies | 3 secondes |
| Nombre maximum de cookies par requête | 50 |
| Nombre maximum d'en-têtes personnalisés par requête | 20 |
| Opérations mensuelles | Selon le forfait (Founding : 500) |
| Taille de lot | Selon le forfait (Founding : désactivé) |
| Rétention des fichiers | Selon le forfait (Founding : 1 heure) |
| Timeout de livraison webhook | 30 secondes |
Questions fréquentes#
Comment convertir une page web en Markdown avec une API REST ?#
Envoyez une requête POST à /v1/convert/url-to-markdown avec un url dans le corps JSON et votre clé dans l'en-tête X-API-Key. Vous recevez en retour une réponse JSON avec un presigned_url vers le fichier Markdown, ou les octets Markdown UTF-8 bruts si vous définissez direct_download=true.
Puis-je convertir des pages web en Markdown pour des pipelines LLM et RAG ?#
Oui. La sortie est conçue pour l'ingestion LLM. L'algorithme Readability (la même bibliothèque derrière le mode lecture de Firefox) isole l'article principal, le superflu comme <nav>, <footer>, les scripts et les formulaires est supprimé, chaque lien et URL d'image relatifs sont résolus en URL absolue, et un bloc frontmatter YAML porte les champs url, title, description, links, et images de la page.
Puis-je convertir plusieurs URLs en Markdown en une seule requête API ?#
Oui. Passez un tableau d'URLs dans url avec async_mode=true (nécessite une clé privée et un forfait avec accès au traitement par lots) ; l'API renvoie un HTTP 202 avec un batch_id que vous interrogez via GET /v1/convert/batch/{batch_id}. Définissez output_format=true pour regrouper tous les fichiers Markdown dans une archive ZIP unique.
Pourquoi certaines images de ma sortie Markdown ont-elles des valeurs src de substitution ?#
Cela se produit quand load_media=false. L'extraction est plus rapide mais les images en chargement différé peuvent conserver des valeurs src de substitution. Laissez load_media et enable_scroll à leur valeur par défaut true afin que la page défile pour déclencher les chargeurs différés et que chaque image termine de charger (timeout de 5 secondes par image) avant la capture.
L'API URL vers Markdown fonctionne-t-elle sur des pages protégées par une connexion ?#
Oui, sur les forfaits avec accès à l'authentification de base : passez auth avec username et password pour HTTP Basic Auth, injectez jusqu'à 50 cookies de session, ou envoyez jusqu'à 20 headers personnalisés, ce qui est utile pour les pages d'articles réservées aux membres ou en environnement de préproduction (staging).