API de Capture d'Écran de Site Web#

Le point de terminaison POST /v1/convert/website-to-screenshot découvre chaque page d'un site web (via l'analyse du sitemap ou un crawl complet en largeur d'abord), prend une capture d'écran PNG pleine page de chaque page, et regroupe les résultats dans une seule archive ZIP. Les jobs s'exécutent toujours de manière asynchrone : l'API renvoie immédiatement un HTTP 202 avec un batch_id, la fin du job est signalée par l'interrogation du statut du batch, un callback webhook, ou une notification par email, et la réponse de statut du batch inclut une URL de téléchargement présignée pour le ZIP terminé. Nécessite un plan payant et une clé API privée.


Point de terminaison#

POST /v1/convert/website-to-screenshot

Content-Type: application/json

Format de sortie : archive ZIP contenant une capture d'écran PNG par page découverte.

Mode : Toujours asynchrone. Renvoie HTTP 202 immédiatement.


Authentification#

Ce point de terminaison nécessite une clé API privée. Les clés publiques ne sont pas prises en charge pour la capture de site web.

X-API-Key: sk_your_private_key

Paramètres de la requête#

Paramètres de découverte du site web#

Parameter Type Required Default Description Plan Gating
url string Oui -- L'URL de base du site web (par ex. https://example.com). Utilisée comme racine pour la découverte des pages. --
crawl_mode string Non "auto" Méthode de découverte des URL. L'une des valeurs "auto", "sitemap", ou "full". Voir Modes de crawl ci-dessous. Sitemap nécessite Indie ou supérieur, Full nécessite Studio ou supérieur
include_patterns string[] Non null Motifs regex pour mettre en liste blanche les URL découvertes. Utilisé uniquement en mode de crawl full. --
exclude_patterns string[] Non Valeurs par défaut du système Motifs regex pour mettre en liste noire des URL. Utilisé uniquement en mode de crawl full. Lorsqu'il est omis, utilise les valeurs par défaut intégrées qui excluent les ressources statiques, les pages de connexion/admin/panier, et la pagination profonde. --

Paramètres de notification#

Parameter Type Required Default Description Plan Gating
output_filename string Non Généré automatiquement Nom de base personnalisé pour le fichier ZIP de sortie. L'horodatage est ajouté automatiquement. --
notification_email string Non Email du propriétaire du projet Adresse email à notifier lorsque le job se termine. --
callback_url string Non -- URL webhook pour recevoir une requête POST à la fin du job. Nécessite l'accès webhook

Paramètres de navigateur et de rendu#

Ces paramètres s'appliquent à la capture de chaque page individuelle du site web.

Parameter Type Required Default Description Plan Gating
viewport_width integer Non 1920 Largeur de la fenêtre du navigateur en pixels. La largeur de la capture d'écran correspond à cette valeur. --
viewport_height integer Non 1080 Hauteur de la fenêtre 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 la capture. --
enable_scroll boolean Non true Fait défiler chaque page pour déclencher le contenu à chargement différé (lazy-loading). --
handle_sticky_header boolean Non true Détecte les en-têtes collants/fixes et les gère avant la capture. --
handle_cookies boolean Non true Ferme automatiquement les bannières de consentement aux cookies. --
wait_for_images boolean Non true Attend que tous les éléments <img> finissent de se charger. --
wait_for_selector string Non null Sélecteur CSS à attendre avant la capture, appliqué à chaque page. 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 appliqués à chaque page. Format : {"username": "...", "password": "..."}. Nécessite l'accès basic auth
cookies array Non null Tableau d'objets cookie injectés avant chaque chargement de page. Maximum 50 cookies. Nécessite l'accès basic auth
headers object Non null En-têtes HTTP personnalisés envoyés avec chaque requête. Maximum 20 en-têtes. Nécessite l'accès basic auth
Non pris en charge : Les paramètres single_page et pdf_options ne s'appliquent pas aux captures d'écran. Chaque page est toujours capturée sous la forme d'une seule image PNG pleine page.

Modes de crawl#

"auto" (par défaut)#

Utilise le mode de crawl le plus élevé autorisé par votre plan. Si votre plan prend en charge le crawl complet, il exécute un crawl complet. Si votre plan ne prend en charge que le sitemap, il exécute une découverte par sitemap.

"sitemap"#

Découvre les pages en analysant le sitemap.xml du site web :

  1. Récupère {base_url}/sitemap.xml (délai d'expiration de 30 secondes)
  2. Si l'élément racine est <sitemapindex>, récupère récursivement chaque sitemap enfant
  3. Extrait toutes les entrées <url><loc> des éléments <urlset>
  4. Renvoie la liste complète des URL découvertes

Renvoie une erreur si le sitemap est absent, renvoie un statut différent de 200, contient un XML invalide, ou ne contient aucune URL.

"full"#

Effectue un crawl complet en deux phases :

Phase 1 -- Découverte des URL de départ :

  1. Analyse robots.txt pour les directives de sitemap et les règles de crawl
  2. Vérifie les chemins de sitemap standards (/sitemap.xml, /wp-sitemap.xml, /sitemap_index.xml, etc.)
  3. Découvre les flux RSS/Atom à partir des balises <link> et des chemins de flux courants
  4. Extrait les URL de départ de toutes les sources découvertes

Phase 2 -- Crawl de liens en largeur d'abord :

  1. Démarre à partir de l'URL de base et de toutes les URL de départ
  2. Visite chaque page et met en file d'attente les liens du même domaine
  3. Applique include_patterns et exclude_patterns pour filtrer les liens
  4. Respecte les règles de robots.txt
  5. Détecte et évite les pièges à URL infinis (pages de calendrier, filtres à facettes, etc.)
  6. Déduplique les URL en normalisant le schéma, l'hôte, les paramètres de requête, et en supprimant les paramètres de suivi (utm_*, fbclid, gclid, etc.)

Motifs d'exclusion par défaut (lorsque exclude_patterns n'est pas fourni) :

  • Ressources statiques : *.pdf, *.zip, *.jpg, *.png, *.gif, *.svg, *.css, *.js, *.xml, *.json, *.mp4, *.webm, *.woff, *.woff2
  • Chemins protégés : /login, /admin, /cart, /checkout
  • Pagination profonde : URL avec des paramètres page= dépassant 3 chiffres

Réponse#

202 Accepted (immédiat)#

{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 42,
    "total_discovered": 42,
    "discovery_method": "sitemap",
    "output_format": "zip"
}
Field Description
batch_id UUID pour suivre le job via l'interrogation du statut du batch ou le webhook.
url_count Nombre de pages qui seront capturées.
total_discovered Nombre total de pages découvertes par le crawl.
discovery_method "sitemap" ou "full_crawl" selon le mode de crawl effectif.

Interrogation du statut du batch#

Interrogez avec le batch_id de la réponse 202 :

GET /v1/convert/batch/{batch_id}
X-API-Key: sk_your_private_key

Renvoie le statut global, les statuts par URL, et une URL de téléchargement présignée pour le ZIP une fois terminé. Voir Interrogation du statut du batch pour le schéma complet de la réponse.

Charge utile du callback webhook#

Lorsque callback_url est fourni, EnConvert envoie une requête POST à la fin du job :

{
    "job_id": "batch-uuid",
    "status": "success",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "gcs_uri": "env/files/{project_id}/url-to-screenshot/website_20260405_123456789.zip",
    "filename": "website_20260405_123456789.zip",
    "file_size": 12345678,
    "total_tasks": 42,
    "successful_tasks": 40,
    "failed_tasks": 2,
    "tasks": [
        {"url": "https://example.com/", "status": "success", "filename": "example_20260405_001.png"},
        {"url": "https://example.com/about", "status": "success", "filename": "example_20260405_002.png"},
        {"url": "https://example.com/broken", "status": "failed", "error": "Timeout"}
    ]
}

Notification par email#

Un email de fin de job est envoyé à notification_email (ou à l'email du propriétaire du projet par défaut) lorsque le job se termine, que ce soit un succès ou un échec.


Limitation par plan d'abonnement#

Feature Founding Indie Studio Enterprise
Capture de site web Non Oui Oui Oui
Mode de crawl sitemap Non Oui Oui Oui
Mode de crawl complet 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
Limite de taille du batch 0 Selon le plan Selon le plan Illimité
Conversions mensuelles 100 Selon le plan Selon le plan Illimité
Plan Founding : La capture de site web n'est pas disponible sur le plan gratuit. Toute tentative d'utilisation de ce point de terminaison renvoie 403 Forbidden.

Exemples de code#

Python (clé privée)#

import requests
import time

# Start the website capture
response = requests.post(
    "https://api.enconvert.com/v1/convert/website-to-screenshot",
    headers={"X-API-Key": "sk_your_private_key"},
    json={
        "url": "https://example.com",
        "crawl_mode": "sitemap",
        "output_filename": "example-screenshots",
        "viewport_width": 1440,
        "viewport_height": 900
    }
)

data = response.json()
print(f"Batch ID: {data['batch_id']}")
print(f"Pages found: {data['url_count']}")

# Poll for completion
batch_id = data["batch_id"]
while True:
    status = requests.get(
        f"https://api.enconvert.com/v1/convert/batch/{batch_id}",
        headers={"X-API-Key": "sk_your_private_key"}
    ).json()

    print(f"Status: {status['status']} ({status['completed']}/{status['total']})")

    if status["status"] in ("completed", "partial", "failed"):
        if status.get("zip_download_url"):
            print(f"Download: {status['zip_download_url']}")
        break

    time.sleep(5)

PHP (clé privée)#

$ch = curl_init("https://api.enconvert.com/v1/convert/website-to-screenshot");
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",
        "crawl_mode" => "sitemap",
        "output_filename" => "example-screenshots",
        "viewport_width" => 1440,
        "viewport_height" => 900
    ])
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

echo "Batch ID: " . $response["batch_id"] . "\n";
echo "Pages found: " . $response["url_count"] . "\n";

Node.js (clé privée)#

const response = await fetch("https://api.enconvert.com/v1/convert/website-to-screenshot", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-API-Key": "sk_your_private_key"
    },
    body: JSON.stringify({
        url: "https://example.com",
        crawl_mode: "sitemap",
        output_filename: "example-screenshots",
        viewport_width: 1440,
        viewport_height: 900
    })
});

const data = await response.json();
console.log(`Batch ID: ${data.batch_id}`);
console.log(`Pages found: ${data.url_count}`);

// Poll for completion
const poll = async () => {
    const status = await fetch(
        `https://api.enconvert.com/v1/convert/batch/${data.batch_id}`,
        { headers: { "X-API-Key": "sk_your_private_key" } }
    ).then(r => r.json());

    console.log(`Status: ${status.status} (${status.completed}/${status.total})`);

    if (["completed", "partial", "failed"].includes(status.status)) {
        if (status.zip_download_url) console.log(`Download: ${status.zip_download_url}`);
        return;
    }
    setTimeout(poll, 5000);
};
poll();

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",
        "crawl_mode":      "sitemap",
        "output_filename": "example-screenshots",
        "viewport_width":  1440,
        "viewport_height": 900,
    })

    req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/website-to-screenshot", 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))
}

Avec callback webhook#

{
    "url": "https://example.com",
    "crawl_mode": "full",
    "callback_url": "https://your-server.com/webhook/enconvert",
    "output_filename": "example-full-site-screenshots",
    "include_patterns": [".*\\/blog\\/.*", ".*\\/docs\\/.*"]
}

Avec authentification (site protégé par mot de passe)#

{
    "url": "https://staging.example.com",
    "crawl_mode": "sitemap",
    "auth": {
        "username": "admin",
        "password": "staging-password"
    },
    "cookies": [
        {"name": "session_token", "value": "abc123", "domain": "staging.example.com"}
    ]
}

Réponses d'erreur#

Status Condition
400 Bad Request Paramètre url manquant ou vide
400 Bad Request Aucune URL trouvée dans le sitemap
400 Bad Request Délai d'expiration lors de la récupération du sitemap (limite de 30 secondes)
400 Bad Request Réponse différente de 200 depuis l'URL du sitemap
400 Bad Request XML invalide dans le sitemap
400 Bad Request Format de sitemap non reconnu
400 Bad Request Aucune page découverte (le crawl complet n'a trouvé aucune URL)
400 Bad Request Structure auth, cookies, ou headers invalide
402 Payment Required Quota mensuel d'ops dépassé par le nombre de pages découvertes
402 Payment Required Limite de stockage atteinte
403 Forbidden Le crawl de site web n'est pas disponible sur le plan actuel (plan Founding)
403 Forbidden Le mode de crawl complet nécessite le plan Studio ou supérieur
403 Forbidden Le nombre de pages découvertes dépasse la limite de taille du batch
403 Forbidden Fonctionnalité non disponible sur ce plan (webhook, basic auth)
500 Internal Server Error Échec du crawl ou de la capture

Limites#

Limit Value
Délai d'expiration de récupération du sitemap 30 secondes
Délai d'expiration global du crawl (mode complet) 10 minutes
Profondeur de crawl maximale (mode complet) 10 niveaux
Délai d'expiration de crawl par page (mode complet) 30 secondes
Limite de mémoire du crawler 512 MB
Seuil de piège infini 20 URL par motif d'URL
Délai d'expiration de récupération de robots.txt 10 secondes
Pages maximales par crawl Limite de taille de batch du plan
Cookies maximum par requête 50
En-têtes personnalisés maximum par requête 20
Délai d'expiration de livraison webhook 30 secondes
Conversions mensuelles Selon le plan
Rétention des fichiers Selon le plan

Questions fréquentes#

Comment capturer chaque page d'un site web avec une API ?#

Envoyez une requête POST à /v1/convert/website-to-screenshot avec l'url de base du site et votre clé privée dans l'en-tête X-API-Key. L'API découvre chaque page (sitemap ou crawl complet), capture un PNG pleine page de chacune, les regroupe dans une archive ZIP, et renvoie HTTP 202 avec un batch_id que vous pouvez interroger pour obtenir le lien de téléchargement.

Puis-je contrôler la taille ou le format des captures d'écran ?#

La largeur de la capture d'écran correspond à viewport_width (par défaut 1920), et viewport_height est utilisé comme référence de rendu. Chaque page est toujours capturée sous la forme d'un seul PNG pleine page. Les paramètres single_page et pdf_options ne s'appliquent pas aux captures d'écran.

Comment télécharger les captures d'écran une fois le job terminé ?#

Interrogez GET /v1/convert/batch/{batch_id} avec votre clé privée pour obtenir le statut global, les statuts par URL, et une URL de téléchargement ZIP présignée, ou transmettez un callback_url pour recevoir un POST webhook à la fin du job. Un email de fin de job est également envoyé à notification_email (ou au propriétaire du projet par défaut).

Puis-je capturer un site protégé par mot de passe ou en staging ?#

Oui, sur les plans avec accès basic auth : transmettez auth avec username et password pour l'HTTP Basic Auth appliquée à chaque page, injectez jusqu'à 50 cookies de session, ou envoyez jusqu'à 20 headers personnalisés.

Pourquoi le point de terminaison de capture d'écran de site web renvoie-t-il 403 Forbidden ?#

Les causes les plus courantes : la capture de site web n'est pas disponible sur le plan Founding, crawl_mode: "full" nécessite Studio ou supérieur, le nombre de pages découvertes dépasse la limite de taille de batch de votre plan, ou une fonctionnalité demandée (webhook, basic auth) n'est pas incluse dans votre plan.