API URL vers PDF#
L'endpoint POST /v1/convert/url-to-pdf convertit toute URL publiquement accessible en un document PDF haute fidélité. Il prend en charge le rendu continu sur une seule page ou une sortie paginée avec des tailles de page personnalisées, ainsi que la gestion du lazy loading, la fermeture des bannières de cookies, l'authentification HTTP Basic, l'injection de cookies et les en-têtes personnalisés. Exécutez les conversions de façon synchrone pour obtenir une URL de téléchargement présignée ou des octets PDF bruts, ou utilisez le mode asynchrone pour convertir plusieurs URLs en lot avec des notifications par webhook et par e-mail.
Endpoint#
POST /v1/convert/url-to-pdf
Content-Type : application/json
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 à l'aide de votre clé publique, puis transmettez-le comme 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 la requête#
Paramètres de premier niveau#
| Parameter | Type | Required | Default | Description | Plan Gating |
|---|---|---|---|---|---|
url |
string ou 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 façon asynchrone. Renvoie immédiatement un batch_id pour l'interrogation (polling). Obligatoire pour un traitement par lot (plusieurs URLs). |
Nécessite l'accès asynchrone |
direct_download |
boolean |
Non | false |
Renvoie les octets PDF bruts dans le corps de la réponse au lieu d'une réponse JSON contenant une URL présignée. Forcé à true pour les clés publiques. Incompatible avec async_mode et plusieurs URLs. |
-- |
output_format |
boolean |
Non | false |
Lorsque true avec plusieurs URLs, regroupe tous les PDF de sortie dans une seule archive ZIP. 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 .pdf est ajoutée automatiquement. Format par défaut : {domain}_{timestamp}.pdf. |
-- |
job_id |
string |
Non | -- | ID de job fourni par le client pour la récupération après timeout. Clés publiques uniquement. Lorsqu'une conversion synchrone dépasse les limites de timeout du reverse proxy (60-120s sur les sites lourds), le client peut interroger GET /v1/convert/status/{job_id} pour récupérer le résultat après coup. Ignoré pour les clés privées. |
-- |
notification_email |
string |
Non | E-mail du propriétaire du projet | Adresse e-mail à notifier lorsqu'un job asynchrone se termine. Clés privées uniquement. | -- |
callback_url |
string |
Non | -- | URL du webhook qui reçoit 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 (viewport) du navigateur, en pixels. | -- |
viewport_height |
integer |
Non | 1080 |
Hauteur de la fenêtre d'affichage (viewport) du navigateur, en pixels. | -- |
single_page |
boolean |
Non | true |
true restitue la page entière comme une seule page PDF continue. false produit une sortie paginée utilisant la taille de page de pdf_options. |
-- |
load_media |
boolean |
Non | true |
Attend le chargement complet de toutes les images et vidéos avant la conversion. Lorsque false, la conversion est plus rapide mais les médias peuvent apparaître comme des espaces réservés. |
-- |
enable_scroll |
boolean |
Non | true |
Fait défiler la page de haut en bas pour déclencher le contenu à chargement différé (lazy loading) (chargeurs basés sur IntersectionObserver). | -- |
handle_sticky_header |
boolean |
Non | true |
Détecte les en-têtes collants/fixes et fait défiler vers le haut avant la capture afin que l'en-tête s'affiche correctement au début du PDF. | -- |
handle_cookies |
boolean |
Non | true |
Ferme automatiquement les bannières de consentement aux cookies (OneTrust, Cookiebot, Didomi, Usercentrics, et bannières génériques). | -- |
wait_for_images |
boolean |
Non | true |
Attend que tous les éléments <img> aient fini de charger (timeout de 5 secondes par image). |
-- |
wait_for_selector |
string |
Non | null |
Sélecteur CSS à attendre avant la capture. 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, ne s'affichent jamais et ne ralentissent pas la capture. | -- |
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 basique |
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 basique |
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 basique |
Options PDF#
Transmettez ces éléments dans un objet pdf_options du corps de la requête.
| Parameter | Type | Default | Description |
|---|---|---|---|
page_size |
string |
"A4" |
Taille de page nommée. Ignorée lorsque page_width et page_height sont tous deux définis. |
page_width |
float |
null |
Largeur de page personnalisée en millimètres. Doit être positive. page_width et page_height doivent être définis ensemble. |
page_height |
float |
null |
Hauteur de page personnalisée en millimètres. Doit être positive. Les deux doivent être définis ensemble. |
orientation |
string |
"portrait" |
"portrait" ou "landscape". Inverse la largeur et la hauteur lorsque défini sur landscape. |
margins |
object |
{"top": 10, "bottom": 10, "left": 10, "right": 10} |
Marges de page en millimètres. Toutes les valeurs doivent être non négatives. |
scale |
float |
1.0 |
Facteur d'échelle du contenu. Plage : 0.1 à 2.0. Appliqué uniquement en mode paginé (single_page=false). |
grayscale |
boolean |
false |
Convertit le PDF de sortie en niveaux de gris via post-traitement. |
header |
object |
null |
En-tête de page pour le mode paginé. Format : {"content": "<html>", "height": 15}. Contenu limité à 2000 caractères max. Hauteur en mm. |
footer |
object |
null |
Pied de page pour le mode paginé. Même format que l'en-tête. |
Tailles de page prises en charge : A0, A1, A2, A3, A4, A5, A6, B0, B1, B2, B3, B4, B5, Letter, Legal, Tabloid, Ledger
Variables de modèle pour en-tête/pied de page : {{page}}, {{total_pages}}, {{date}}, {{title}}, {{url}}
single_page=false). Ils n'ont aucun effet en mode continu sur une seule page.
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 "/" lorsque domain est défini. |
Réponse#
Synchrone avec téléchargement direct (direct_download=true)#
Clé privée -- renvoie les octets PDF bruts :
HTTP 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="example_20260404_123456789.pdf"
X-Object-Key: env/files/{project_id}/url-to-pdf/example_20260404_123456789.pdf
X-File-Size: 123456
X-Conversion-Time: 12.5
X-Filename: example_20260404_123456789.pdf
(binary PDF data)
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-pdf/example_20260404_123456789.pdf",
"filename": "example_20260404_123456789.pdf",
"file_size": 123456,
"conversion_time_seconds": 12.5,
"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-pdf/example_20260404_123456789.pdf",
"filename": "example_20260404_123456789.pdf",
"file_size": 123456,
"conversion_time_seconds": 12.5
}
Mode asynchrone#
Renvoie immédiatement un batch_id pour l'interrogation (polling).
HTTP 202 Accepted
{
"status": "processing",
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"url_count": 5,
"output_format": "individual"
}
Lorsque output_format=true (regroupement ZIP) :
{
"status": "processing",
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"url_count": 5,
"output_format": "zip"
}
Interrogation du statut du job (clés publiques uniquement)#
L'endpoint d'interrogation du statut est conçu pour la récupération après timeout des clés publiques. Lorsqu'une conversion synchrone prend plus de temps que le timeout du reverse proxy (généralement 60s), le client peut récupérer le résultat en interrogeant avec le job_id fourni dans la requête d'origine.
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 de lot (clés privées uniquement)#
Pour les jobs de lot asynchrones, interrogez l'endpoint de statut de lot avec le batch_id renvoyé dans la réponse 202.
GET /v1/convert/batch/{batch_id}
X-API-Key: sk_your_private_key
Réponse :
{
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"total": 5,
"completed": 3,
"failed": 1,
"in_progress": 1,
"output_mode": "individual",
"zip_download_url": null,
"items": [
{
"source_url": "https://example.com/page1",
"status": "Success",
"download_url": "https://spaces.example.com/...",
"output_file_size": 102400,
"duration": "2.34"
},
{
"source_url": "https://example.com/page2",
"status": "Failed",
"download_url": null,
"output_file_size": null,
"duration": "0.87"
},
{
"source_url": "https://example.com/page3",
"status": "In Progress",
"download_url": null,
"output_file_size": null,
"duration": null
}
]
}
Valeurs de statut de lot :
| Status | Meaning |
|---|---|
processing |
Au moins une URL est encore en cours de conversion |
completed |
Toutes les URLs ont été converties avec succès |
partial |
Toutes les URLs sont terminées, mais certaines ont échoué |
failed |
Toutes les URLs ont échoué |
Lorsque output_mode vaut "zip", une seule zip_download_url est fournie à la place des valeurs download_url par élément.
Payload du callback webhook#
Lorsqu'un callback_url est fourni, EnConvert envoie une requête POST à cette URL une fois la conversion terminée.
Job avec une seule URL :
{
"job_id": "activity_id",
"status": "success",
"batch_id": "...",
"gcs_uri": "object_key",
"filename": "example_20260404_123456789.pdf",
"file_size": 123456
}
Job de 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.pdf"},
{"url": "https://example.com/page2", "status": "failed", "filename": null}
]
}
Fonctionnalités#
Mode de capture nette#
EnConvert gère automatiquement les obstacles courants des pages web pour produire des PDF propres :
- Bannières de consentement aux cookies -- Ferme automatiquement les bannières d'OneTrust, Cookiebot, Didomi, Usercentrics, et des implémentations génériques. Opère sur la page principale et les iframes. Utilise une stratégie de fermeture d'abord, puis d'acceptation.
- Fermeture des modales et popups -- Ferme les overlays via plusieurs stratégies : touche Échap, boutons de fermeture ARIA, boutons de fermeture basés sur des classes, et boutons de dialogue basés sur des rôles.
- Révélation des animations au scroll -- Force la visibilité des éléments masqués par des bibliothèques d'animation déclenchées au scroll, notamment WOW.js, AOS, ScrollReveal et GSAP ScrollTrigger.
- Nettoyage des menus déroulants -- Ferme tous les menus déroulants ouverts et convertit les éléments de bouton de navigation en véritables liens ancre afin qu'ils restent cliquables dans le PDF.
Taille et dimensions de page#
- Mode page unique (par défaut) : la page web entière est restituée comme une seule page PDF continue. La hauteur est calculée dynamiquement à partir du contenu réel via un parcours du DOM.
- Mode paginé (
single_page=false) : la sortie utilise lespage_size,orientationetmarginsconfigurés. Prend en charge 18 tailles nommées, de A0 à Ledger, ou des dimensions personnalisées en millimètres.
Authentification HTTP Basic#
Transmettez auth avec username et password pour convertir des pages protégées par une authentification HTTP Basic. Les identifiants sont envoyés comme identifiants HTTP avec chaque requête vers la page cible.
{
"url": "https://staging.example.com/report",
"auth": {
"username": "admin",
"password": "secret"
}
}
Injection de cookies#
Injectez jusqu'à 50 cookies avant le chargement de la page. Utile pour convertir des pages nécessitant une session active ou des préférences utilisateur spécifiques.
{
"url": "https://example.com/dashboard",
"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. Utile pour transmettre des tokens API, des user agents personnalisés, ou d'autres métadonnées de requête.
{
"url": "https://example.com/report",
"headers": {
"X-Custom-Token": "my-token-value",
"Accept-Language": "en-US"
}
}
Chargement différé des images (lazy loading)#
Lorsque load_media et enable_scroll sont activés (tous deux à true par défaut), le convertisseur :
- Fait défiler toute la page lentement (120px toutes les 90ms) pour déclencher les chargeurs différés basés sur IntersectionObserver
- Attend que tous les éléments
<img>déclenchent leur événementonload(timeout de 5 secondes par image) - Attend 500ms pour la stabilisation de la mise en page après le chargement de toutes les images
Définissez load_media=false pour une conversion plus rapide si la fidélité des médias n'est pas critique -- le convertisseur utilisera un défilement rapide (300px toutes les 30ms) et ajoutera des styles d'espace réservé pour les images non chargées.
Gestion des en-têtes collants#
Lorsque handle_sticky_header est activé (true par défaut), le convertisseur détecte les éléments en position fixe et collante qui semblent être des en-têtes (via des balises sémantiques, des rôles ARIA et des motifs de noms de classe courants), puis fait défiler vers le haut de la page avant la capture afin que l'en-tête s'affiche correctement au début du PDF.
En-têtes et pieds de page#
Ajoutez des en-têtes et pieds de page répétitifs en mode paginé avec du contenu HTML et des variables de modèle :
{
"url": "https://example.com/report",
"single_page": false,
"pdf_options": {
"page_size": "A4",
"header": {
"content": "<div style='font-size:10px;text-align:center;width:100%'>Confidential Report</div>",
"height": 15
},
"footer": {
"content": "<div style='font-size:9px;text-align:center;width:100%'>Page {{page}} of {{total_pages}}</div>",
"height": 10
}
}
}
Sortie en niveaux de gris#
Définissez pdf_options.grayscale sur true pour convertir le PDF final en niveaux de gris via un post-traitement Ghostscript.
Fonctionnalités de rendu supplémentaires#
- Normalisation des unités de viewport -- Convertit les unités CSS
vh,svh,lvh,dvhen valeurs de pixels fixes pour éviter les problèmes de mise en page lors du rendu d'impression. - Mode furtif -- Utilise le masquage d'empreinte de navigateur pour éviter la détection de bots sur les pages protégées.
- Interception des popups -- Ferme automatiquement tout nouvel onglet de navigateur ou popup déclenché par la page.
- Contournement CSP -- Gère les restrictions de Content Security Policy et Trusted Types qui bloqueraient sinon la conversion.
Restrictions selon le plan d'abonnement#
| Feature | Founding | Indie | Studio | Enterprise |
|---|---|---|---|---|
| Conversion de base (URL unique, synchrone) | Oui | Oui | Oui | Oui |
pdf_options personnalisés |
Oui | Oui | Oui | Oui |
| Options de viewport et de rendu | Oui | Oui | Oui | Oui |
| Mode asynchrone | Non | Oui | Oui | Oui |
| Traitement par lot (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 plan | Selon le plan | Illimité |
| Limite de taille de lot | 0 | Selon le plan | Selon le plan | Illimité |
| Rétention des fichiers | 1 heure | Selon le plan | Selon le plan | Selon le plan |
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 transmettez plusieurs URLs, ce qui active automatiquement le mode asynchrone). - L'API renvoie immédiatement HTTP 202 avec un
batch_idet unurl_count. - Chaque URL est convertie en arrière-plan, téléversée vers le stockage, et suivie individuellement.
- Suivez l'achèvement via une notification par e-mail ou un callback webhook.
Notification par e-mail#
Par défaut, un e-mail d'achèvement est envoyé à l'adresse e-mail du propriétaire du projet lorsque le job asynchrone se termine. Vous pouvez remplacer cela 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 dans la requête pour recevoir une notification POST automatique lorsque le job se termine :
{
"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 lot 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 PDF distinct :
{
"url": [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
],
"async_mode": true
}
Sortie en archive ZIP#
Regroupez tous les PDF dans une seule archive ZIP :
{
"url": [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
],
"async_mode": true,
"output_format": true,
"output_filename": "monthly-reports"
}
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-pdf",
headers={"X-API-Key": "sk_your_private_key"},
json={
"url": "https://example.com",
"single_page": True,
"pdf_options": {
"page_size": "A4",
"margins": {"top": 15, "bottom": 15, "left": 10, "right": 10}
}
}
)
data = response.json()
print(data["presigned_url"])
PHP (clé privée)#
$ch = curl_init("https://api.enconvert.com/v1/convert/url-to-pdf");
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",
"single_page" => true,
"pdf_options" => [
"page_size" => "A4",
"margins" => ["top" => 15, "bottom" => 15, "left" => 10, "right" => 10]
]
])
]);
$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-pdf", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "sk_your_private_key"
},
body: JSON.stringify({
url: "https://example.com",
single_page: true,
pdf_options: {
page_size: "A4",
margins: { top: 15, bottom: 15, left: 10, right: 10 }
}
})
});
const data = await response.json();
console.log(data.presigned_url);
Go (clé privée)#
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"io"
)
func main() {
body, _ := json.Marshal(map[string]interface{}{
"url": "https://example.com",
"single_page": true,
"pdf_options": map[string]interface{}{
"page_size": "A4",
"margins": map[string]int{"top": 15, "bottom": 15, "left": 10, "right": 10},
},
})
req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/url-to-pdf", 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 -- 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 PDF
const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-pdf", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({
url: "https://example.com"
})
});
const data = await convertRes.json();
// Open the PDF in a new tab
window.open(data.presigned_url, "_blank");
React (clé publique)#
import { useState } from "react";
function UrlToPdf() {
const [loading, setLoading] = useState(false);
const [pdfUrl, setPdfUrl] = useState(null);
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-pdf", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({ url: "https://example.com" })
});
const data = await convertRes.json();
setPdfUrl(data.presigned_url);
} finally {
setLoading(false);
}
}
return (
<div>
<button onClick={convertUrl} disabled={loading}>
{loading ? "Converting..." : "Convert to PDF"}
</button>
{pdfUrl && <a href={pdfUrl} target="_blank" rel="noreferrer">Download PDF</a>}
</div>
);
}
export default UrlToPdf;
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 obligatoires 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-string) |
400 Bad Request |
Conflit entre auth et l'en-tête personnalisé Authorization |
400 Bad Request |
Clé publique tentant d'utiliser plusieurs URLs |
400 Bad Request |
pdf_options invalide (taille de page non reconnue, échelle hors de la plage 0.1-2.0, marges négatives, contenu d'en-tête/pied de page dépassant 2000 caractères) |
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 |
L'endpoint ne figure pas parmi les endpoints autorisés de la clé API |
403 Forbidden |
Fonctionnalité non disponible sur le plan actuel (asynchrone, webhook, ZIP, authentification basique) |
403 Forbidden |
La taille du lot dépasse la limite de lot du plan |
404 Not Found |
ID de job introuvable (lors de l'interrogation du statut) |
500 Internal Server Error |
Échec de la conversion (crash du navigateur, erreur de rendu, échec du post-traitement) |
Limites#
| Limit | Value |
|---|---|
| Timeout de navigation de page | 60 secondes |
| Timeout de chargement par image | 5 secondes |
| Timeout de fermeture des bannières de cookies | 3 secondes |
| Nombre maximum de cookies par requête | 50 |
| Nombre maximum d'en-têtes personnalisés par requête | 20 |
| Longueur du contenu d'en-tête/pied de page | 2000 caractères |
| Plage d'échelle PDF | 0.1 -- 2.0 |
| Opérations mensuelles | Selon le plan (Founding : 500) |
| Taille de lot | Selon le plan (Founding : désactivé) |
| Rétention des fichiers | Selon le plan (Founding : 1 heure) |
| Timeout de livraison webhook | 30 secondes |
Questions fréquentes#
Comment convertir une page web en PDF avec une API REST ?#
Envoyez une requête POST à /v1/convert/url-to-pdf avec un corps JSON contenant l'url à convertir, en vous authentifiant avec votre clé privée dans l'en-tête X-API-Key (ou un token Bearer JWT issu d'une clé publique). La réponse synchrone renvoie une presigned_url pour télécharger le PDF, ou des octets PDF bruts lorsque direct_download=true.
Puis-je convertir plusieurs URLs en PDF en une seule requête API ?#
Oui. Transmettez un tableau d'URLs dans le paramètre url avec async_mode=true (une clé privée est requise) ; l'API renvoie 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 PDF dans une seule archive ZIP.
Comment capturer une page web entière comme une seule page PDF continue ?#
Le mode page unique est le mode par défaut (single_page=true) : la page entière est restituée comme une seule page PDF continue dont la hauteur est calculée à partir du contenu réel. Définissez single_page=false pour une sortie paginée avec page_size, orientation, margins, et des en-têtes et pieds de page optionnels via pdf_options.
Pourquoi mon PDF affiche-t-il des bannières de cookies ou des images manquantes ?#
La fermeture des bannières de cookies (handle_cookies) et la gestion du lazy loading (enable_scroll, load_media, wait_for_images) sont toutes définies sur true par défaut, couvrant OneTrust, Cookiebot, Didomi, Usercentrics, et les bannières génériques. Si vous définissez load_media=false, la conversion est plus rapide mais les médias peuvent apparaître comme des espaces réservés.
Puis-je convertir en PDF une page protégée par une connexion ?#
Oui. Utilisez le paramètre auth pour l'authentification HTTP Basic, injectez jusqu'à 50 cookies de session avec cookies, ou envoyez jusqu'à 20 en-têtes HTTP personnalisés avec headers. Ces options nécessitent l'accès à l'authentification basique sur votre plan, et auth ne peut pas être combiné avec un en-tête Authorization personnalisé.