---
seo_title: API de capture d'écran de site web | Page entière | EnConvert
meta_desc: Capturez des sites web en pleine page au format PNG via POST /v1/convert/url-to-screenshot. Bannières de cookies fermées, contenu différé chargé, URLs présignées.
keywords: api capture d'écran site web, api screenshot page complète, capturer une page web en image, transformer une url en capture d'écran, api screenshot png site web, alternative à puppeteer pour capture d'écran, api pour prendre une capture d'écran automatiquement, capture d'écran pleine page api
---

# API de capture d'écran de site web

Le point de terminaison `POST /v1/convert/url-to-screenshot` capture une capture d'écran en pleine page de n'importe quelle URL accessible publiquement, sous forme d'image PNG haute fidélité. Il gère automatiquement les bannières de cookies, les modales, le contenu à chargement différé, les animations déclenchées par le défilement et les en-têtes collants pour produire une capture propre et précise. Exécutez-le en mode synchrone pour obtenir une URL de téléchargement présignée ou des octets PNG bruts, ou utilisez le mode asynchrone pour capturer plusieurs URLs en une seule fois.

---

## Point de terminaison

```
POST /v1/convert/url-to-screenshot
```

**Type de contenu :** `application/json`

**Format de sortie :** PNG (toujours). Le format de sortie n'est pas configurable. Toutes les captures d'écran sont capturées sous forme d'images PNG en pleine page.

---

## Authentification

Ce point de terminaison 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 sous forme de 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...
```

<div class="alert alert-info">
<strong>Remarque :</strong> Les requêtes par clé publique sont limitées à une seule URL, au mode synchrone et au téléchargement direct. Le mode asynchrone, le traitement par lot, les webhooks et les e-mails de notification ne sont pas disponibles avec les clés publiques.
</div>

---

## Paramètres de la requête

### Paramètres de premier niveau

| Paramètre | Type | Obligatoire | Valeur par défaut | Description | Restriction par forfait |
|-----------|------|----------|---------|-------------|-------------|
| `url` | `string` ou `string[]` | Oui | -- | Chaîne URL unique ou tableau d'URLs à capturer. Plusieurs URLs nécessitent le mode asynchrone. | -- |
| `async_mode` | `boolean` | Non | `false` | Exécute la capture de manière asynchrone. Renvoie immédiatement un `batch_id`. Requis pour le traitement par lot (plusieurs URLs). | Nécessite l'accès asynchrone |
| `direct_download` | `boolean` | Non | `false` | Renvoie les octets PNG 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` | Lorsqu'il est défini sur `true` avec plusieurs URLs, regroupe tous les PNG 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 `.png` est ajoutée automatiquement. Format par défaut : `{domain}_{timestamp}.png`. | -- |
| `job_id` | `string` | Non | -- | ID de tâche fourni par le client pour la récupération en cas de timeout. **Clés publiques uniquement.** Lorsqu'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 | E-mail du propriétaire du projet | Adresse e-mail à notifier lorsqu'une tâche asynchrone se termine. Clés privées uniquement. | -- |
| `callback_url` | `string` | Non | -- | URL de webhook qui recevra une requête POST lorsque la capture se termine. Clés privées uniquement. | Nécessite l'accès aux webhooks |

### Paramètres du navigateur et du rendu

| Paramètre | Type | Obligatoire | Valeur par défaut | Description | Restriction par forfait |
|-----------|------|----------|---------|-------------|-------------|
| `viewport_width` | `integer` | Non | `1920` | Largeur de la fenêtre d'affichage du navigateur en pixels. La largeur de la capture d'écran correspond à cette valeur. | -- |
| `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 fenêtre d'affichage. La hauteur réelle de la capture d'écran est déterminée par la hauteur totale du contenu de la page. | -- |
| `load_media` | `boolean` | Non | `true` | Attend que toutes les images et vidéos soient entièrement chargées avant la capture. Lorsque défini sur `false`, la capture 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é (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 en haut de la capture d'écran. | -- |
| `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 se 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

| Paramètre | Type | Obligatoire | Valeur par défaut | Description | Restriction par forfait |
|-----------|------|----------|---------|-------------|-------------|
| `auth` | `object` | Non | `null` | Identifiants d'authentification HTTP Basic pour l'URL cible. Format : `{"username": "...", "password": "..."}`. Ne peut pas être utilisé conjointement avec un en-tête `Authorization` personnalisé. | 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 |

<div class="alert alert-warning">
<strong>Non pris en charge :</strong> Les paramètres <code>single_page</code> et <code>pdf_options</code> du point de terminaison <a href="/fr/docs/endpoints/convert/web-pages/url-to-pdf">url-to-pdf</a> ne s'appliquent pas aux captures d'écran. Les captures d'écran capturent toujours la page entière sous forme d'une seule image continue.
</div>

---

## Schéma de l'objet cookie

Chaque élément du tableau `cookies` doit suivre cette structure :

| Champ | Type | Obligatoire | Valeur par défaut | 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 sur `"/"` lorsque `domain` est défini. |

---

## Réponse

### Synchrone avec téléchargement direct (`direct_download=true`)

**Clé privée** renvoie les octets PNG bruts :

```
HTTP 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="example_20260405_123456789.png"
X-Object-Key: env/files/{project_id}/url-to-screenshot/example_20260405_123456789.png
X-File-Size: 456789
X-Conversion-Time: 8.2
X-Filename: example_20260405_123456789.png

(binary PNG data)
```

**Clé publique** renvoie du JSON avec une URL présignée :

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/url-to-screenshot/example_20260405_123456789.png",
    "filename": "example_20260405_123456789.png",
    "file_size": 456789,
    "conversion_time_seconds": 8.2,
    "job_id": "client-provided-id"
}
```

### Synchrone sans téléchargement direct (`direct_download=false`)

Disponible uniquement avec les clés privées.

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/url-to-screenshot/example_20260405_123456789.png",
    "filename": "example_20260405_123456789.png",
    "file_size": 456789,
    "conversion_time_seconds": 8.2
}
```

### Mode asynchrone

Renvoie immédiatement un `batch_id` pour le suivi.

```
HTTP 202 Accepted
```

```json
{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 5,
    "output_format": "individual"
}
```

Lorsque `output_format=true` (regroupement ZIP) :

```json
{
    "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 récupération en cas de timeout avec une clé publique :

```
GET /v1/convert/status/{job_id}
Authorization: Bearer <jwt_token>
```

| Statut | Réponse |
|--------|----------|
| 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 par lot asynchrones, 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 global, les statuts par URL et les URLs de téléchargement présignées. Voir [Interrogation du statut du lot](/fr/docs/endpoints/convert/web-pages/url-to-pdf.md#batch-status-polling-private-keys-only) pour le schéma complet de la réponse.

### Payload du callback webhook

Lorsqu'un `callback_url` est fourni, EnConvert envoie une requête POST à cette URL à la fin du traitement.

**Tâche avec une seule URL :**

```json
{
    "job_id": "activity_id",
    "status": "success",
    "batch_id": "...",
    "gcs_uri": "object_key",
    "filename": "example_20260405_123456789.png",
    "file_size": 456789
}
```

**Tâche par lot :**

```json
{
    "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.png"},
        {"url": "https://example.com/page2", "status": "failed", "filename": null}
    ]
}
```

---

## Fonctionnalités

### Capture en pleine page

Chaque capture d'écran capture **l'intégralité du contenu de la page**, et pas seulement la zone visible. Le convertisseur :

1. Effectue le rendu de la page avec les valeurs `viewport_width` et `viewport_height` spécifiées
2. Fait défiler la page pour déclencher tout le contenu à chargement différé
3. Calcule la hauteur réelle du contenu à l'aide d'un parcours de l'arbre DOM qui mesure la position basse maximale de tous les éléments visibles
4. Redimensionne la fenêtre d'affichage pour englober la hauteur totale du contenu
5. Capture la capture d'écran avec `full_page=true`

Le résultat est une seule image PNG haute de la page complète.

### Mode de capture nette

EnConvert gère automatiquement les obstacles courants des pages web pour produire des captures d'écran propres :

- **Bannières de consentement aux cookies** : fermeture automatique des bannières de OneTrust, Cookiebot, Didomi, Usercentrics et des implémentations génériques. Fonctionne sur la page principale et dans les iframes.
- **Fermeture des modales et popups** : les overlays sont fermés à l'aide de plusieurs stratégies, à savoir la touche Échap, les boutons de fermeture ARIA, les boutons de fermeture basés sur des classes (`"Close"`, `"Not now"`, `"No thanks"`, `"Skip"`), et les boutons de dialogue basés sur les rôles. Les effets résiduels de flou, d'arrière-plan et d'inertie sont supprimés après fermeture.
- **Révélation des animations au défilement** : force la visibilité des éléments masqués par des bibliothèques d'animation déclenchées au défilement, notamment WOW.js, AOS, ScrollReveal, GSAP ScrollTrigger, et des classes d'animation génériques (`.fadeIn`, `.slideIn`, etc.). Révèle également toutes les diapositives Swiper.
- **Nettoyage des menus déroulants** : ferme tous les menus déroulants ouverts, convertit les éléments de bouton de navigation en véritables liens d'ancrage pour qu'ils restent visuellement propres, masque les éléments `role="menu"`, et repositionne les en-têtes fixes en position statique.

### Normalisation des unités de fenêtre d'affichage

Les captures d'écran nécessitent un traitement particulier des unités de fenêtre d'affichage CSS (`vh`, `svh`, `lvh`, `dvh`) car la fenêtre d'affichage est redimensionnée à la hauteur totale de la page. Sans normalisation, les éléments dimensionnés avec des unités de fenêtre d'affichage s'étireraient de façon démesurée. Le convertisseur :

- Convertit toutes les unités relatives à la fenêtre d'affichage en valeurs de pixels fixes basées sur la hauteur de fenêtre d'affichage d'origine
- Limite les images et vidéos anormalement hautes à 1,5 fois la hauteur de fenêtre d'affichage d'origine
- Gère les particularités de hauteur spécifiques à Elementor (conteneurs flex, effets de mouvement, conteneurs d'arrière-plan)
- Préserve les dimensions vidéo tout au long du processus de normalisation

### Authentification HTTP Basic

Transmettez `auth` avec `username` et `password` pour capturer des pages protégées par une authentification HTTP Basic.

```json
{
    "url": "https://staging.example.com/dashboard",
    "auth": {
        "username": "admin",
        "password": "secret"
    }
}
```

### Injection de cookies

Injectez jusqu'à 50 cookies avant le chargement de la page. Utile pour capturer des pages nécessitant une session active.

```json
{
    "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.

```json
{
    "url": "https://example.com/report",
    "headers": {
        "X-Custom-Token": "my-token-value",
        "Accept-Language": "en-US"
    }
}
```

### Chargement différé des images

Lorsque `load_media` et `enable_scroll` sont activés (les deux sont définis par défaut sur `true`), le convertisseur fait défiler la page lentement (120px toutes les 90 ms) pour déclencher les chargeurs différés, puis attend que toutes les images aient fini de se charger, avec une période de stabilisation de la mise en page de 500 ms.

Définissez `load_media=false` pour une capture plus rapide. Le convertisseur utilise alors un défilement rapide (300px toutes les 30 ms) avec une stabilisation plus courte de 100 ms, mais les médias peuvent apparaître comme des espaces réservés.

### Gestion des en-têtes collants

Lorsque cette option est activée (par défaut `true`), le convertisseur détecte les éléments en position fixe et collante qui semblent être des en-têtes, les repositionne en position statique pour une capture d'écran propre, et fait défiler jusqu'en haut de la page avant la capture.

### Fonctionnalités de rendu supplémentaires

- **Émulation du média d'écran** : la page est rendue en utilisant le média CSS `screen` (et non `print`), afin que la capture d'écran corresponde à ce que les utilisateurs voient dans leur navigateur.
- **Mode furtif** : utilise le masquage d'empreinte du navigateur pour éviter la détection de bots sur les pages protégées.
- **Interception des popups** : ferme automatiquement tout nouvel onglet ou popup de navigateur déclenché par la page.
- **Contournement CSP** : gère les restrictions de Content Security Policy et de Trusted Types qui bloqueraient autrement la manipulation de la page.
- **Préservation des ombres** : les éléments avec `box-shadow` et `text-shadow` sont marqués pour garantir que les ombres s'affichent correctement dans la capture d'écran de sortie.

---

## Restrictions par forfait d'abonnement

| Fonctionnalité | Founding | Indie | Studio | Enterprise |
|---------|------|---------|-----|------------|
| Capture de base (URL unique, synchrone) | Oui | Oui | Oui | Oui |
| Dimensionnement de la fenêtre d'affichage | 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 |
| Authentification HTTP Basic | 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é |
| Conservation des fichiers | 1 heure | Selon le forfait | Selon le forfait | Selon le forfait |

---

## Mode asynchrone

Le mode asynchrone est utile pour les captures de longue durée ou lors de la capture de plusieurs URLs.

### Fonctionnement

1. Envoyez une requête avec `async_mode=true` (ou transmettez plusieurs URLs, ce qui active automatiquement le mode asynchrone).
2. L'API renvoie immédiatement un HTTP 202 avec un `batch_id` et un `url_count`.
3. Chaque URL est capturée en arrière-plan, téléversée vers le stockage, et suivie individuellement.
4. Surveillez l'achèvement via l'**interrogation du statut du lot**, la **notification par e-mail**, ou le **callback webhook**.

### Notification par e-mail

Par défaut, un e-mail de fin de traitement est envoyé à l'adresse e-mail du propriétaire du projet. Remplacez-la avec `notification_email` :

```json
{
    "url": ["https://example.com/page1", "https://example.com/page2"],
    "async_mode": true,
    "notification_email": "team@example.com"
}
```

### Callback webhook

Fournissez un `callback_url` pour recevoir une notification POST automatique à la fin du traitement :

```json
{
    "url": ["https://example.com/page1", "https://example.com/page2"],
    "async_mode": true,
    "callback_url": "https://your-server.com/webhook/enconvert"
}
```

---

## Traitement par lot et en masse

Capturez 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 PNG distinct :

```json
{
    "url": [
        "https://example.com/page1",
        "https://example.com/page2",
        "https://example.com/page3"
    ],
    "async_mode": true
}
```

### Sortie en archive ZIP

Regroupez toutes les captures d'écran dans une seule archive ZIP :

```json
{
    "url": [
        "https://example.com/page1",
        "https://example.com/page2",
        "https://example.com/page3"
    ],
    "async_mode": true,
    "output_format": true,
    "output_filename": "monthly-screenshots"
}
```

---

## Exemples de code

### Python (clé privée)

```python
import requests

response = requests.post(
    "https://api.enconvert.com/v1/convert/url-to-screenshot",
    headers={"X-API-Key": "sk_your_private_key"},
    json={
        "url": "https://example.com",
        "viewport_width": 1440,
        "viewport_height": 900
    }
)

data = response.json()
print(data["presigned_url"])
```

### PHP (clé privée)

```php
$ch = curl_init("https://api.enconvert.com/v1/convert/url-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",
        "viewport_width" => 1440,
        "viewport_height" => 900
    ])
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo $data["presigned_url"];
```

### Node.js (clé privée)

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

const data = await response.json();
console.log(data.presigned_url);
```

### Go (clé privée)

```go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]interface{}{
        "url":             "https://example.com",
        "viewport_width":  1440,
        "viewport_height": 900,
    })

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

### JavaScript côté navigateur (clé publique)

```javascript
// 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: Capture screenshot
const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-screenshot", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${token}`
    },
    body: JSON.stringify({
        url: "https://example.com"
    })
});

const data = await convertRes.json();
// Display the screenshot
const img = document.createElement("img");
img.src = data.presigned_url;
document.body.appendChild(img);
```

### React (clé publique)

```jsx
import { useState } from "react";

function UrlToScreenshot() {
    const [loading, setLoading] = useState(false);
    const [imageUrl, setImageUrl] = useState(null);

    async function captureScreenshot() {
        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();

            // Capture screenshot
            const convertRes = await fetch("https://api.enconvert.com/v1/convert/url-to-screenshot", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer ${token}`
                },
                body: JSON.stringify({ url: "https://example.com" })
            });

            const data = await convertRes.json();
            setImageUrl(data.presigned_url);
        } finally {
            setLoading(false);
        }
    }

    return (
        <div>
            <button onClick={captureScreenshot} disabled={loading}>
                {loading ? "Capturing..." : "Take Screenshot"}
            </button>
            {imageUrl && <img src={imageUrl} alt="Screenshot" style={{ maxWidth: "100%" }} />}
        </div>
    );
}

export default UrlToScreenshot;
```

---

## Réponses d'erreur

| Statut | 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êtes bloqués, valeurs non textuelles) |
| `400 Bad Request` | Conflit entre `auth` et l'en-tête personnalisé `Authorization` |
| `400 Bad Request` | Clé publique tentant d'utiliser 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` | Point de terminaison non autorisé pour cette clé API |
| `403 Forbidden` | Fonctionnalité non disponible sur le forfait actuel (asynchrone, webhook, ZIP, authentification de base) |
| `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 capture (crash du navigateur, erreur de rendu) |

---

## Limites

| Limite | Valeur |
|-------|-------|
| Timeout de navigation de page | 60 secondes |
| Timeout de chargement par image | 5 secondes |
| Timeout de fermeture de la bannière de 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 du lot | Selon le forfait (Founding : désactivé) |
| Conservation des fichiers | Selon le forfait (Founding : 1 heure) |
| Timeout de livraison du webhook | 30 secondes |

---

## Questions fréquentes

### Comment prendre une capture d'écran en pleine page d'un site web avec une API ?

Envoyez une requête `POST` à `/v1/convert/url-to-screenshot` avec un corps JSON contenant `url`, en vous authentifiant avec votre clé privée dans l'en-tête `X-API-Key` (ou un token Bearer JWT provenant d'une clé publique). Chaque capture inclut l'intégralité du contenu de la page, pas seulement la zone visible. Le convertisseur redimensionne la fenêtre d'affichage à la hauteur totale du contenu et capture avec `full_page=true`.

### Puis-je changer le format de sortie de la capture d'écran en JPEG ou WebP ?

Non. Le format de sortie n'est pas configurable. Toutes les captures d'écran sont capturées sous forme d'images PNG en pleine page.

### Comment contrôler la largeur et la taille de la capture d'écran ?

Définissez `viewport_width` (par défaut `1920`). La largeur de la capture d'écran correspond à cette valeur. La hauteur de la capture d'écran est déterminée par la hauteur totale du contenu de la page, `viewport_height` (par défaut `1080`) étant utilisé comme référence pour le rendu et le calcul des unités de fenêtre d'affichage.

### Puis-je capturer 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 de base sur votre forfait.

### Comment l'API supprime-t-elle les bannières de cookies et les popups des captures d'écran ?

Lorsque `handle_cookies` est activé (par défaut `true`), le convertisseur ferme automatiquement les bannières de consentement de OneTrust, Cookiebot, Didomi, Usercentrics et des implémentations génériques, en agissant sur la page principale et les iframes. Les modales et popups sont fermés à l'aide de la touche Échap, de boutons de fermeture ARIA, de boutons de fermeture basés sur des classes, et de boutons de dialogue basés sur les rôles, avec suppression des effets résiduels de flou et d'arrière-plan.
