---
seo_title: API conversione batch file: URL in PDF e ZIP | EnConvert
meta_desc: Converti più URL in PDF o screenshot con un'unica richiesta POST /v1/convert/url-to-pdf. API di conversione batch con output ZIP, webhook e polling dello stato.
keywords: api conversione batch file, convertire più url in pdf con api, api per convertire url in massa in pdf, output zip conversione batch api, polling stato batch conversione, webhook notifica conversione completata, api screenshot multipli url, conversione asincrona file api
---

# API di Conversione Batch File

L'API batch di EnConvert converte più URL in un'unica richiesta: passa un array di URL a `/v1/convert/url-to-pdf` o `/v1/convert/url-to-screenshot` e ricevi una risposta HTTP 202 con un `batch_id`. Ogni URL viene convertito in modo asincrono in background e i risultati vengono consegnati come URL di download presigned, uno per file oppure raggruppati in un unico archivio ZIP. Tieni traccia dell'avanzamento facendo polling su `GET /v1/convert/batch/{batch_id}`, oppure ricevi una notifica via webhook callback o email al completamento.

<div class="alert alert-warning">
<strong>Solo chiavi private:</strong> L'elaborazione batch è disponibile solo autenticandoti con una <strong>chiave API privata</strong> (<code>X-API-Key: sk_...</code>). Le chiavi pubbliche sono limitate a richieste sincrone su singolo URL.
</div>

---

## How It Works

1. Invia una richiesta con un **array di URL** nel parametro `url` a `/v1/convert/url-to-pdf` oppure a `/v1/convert/url-to-screenshot`.
2. L'API convalida il batch rispetto ai limiti del tuo piano e restituisce **HTTP 202** con un `batch_id`.
3. Ogni URL viene convertito in background e addebita una op. Il numero totale del batch viene verificato in anticipo rispetto alla quota mensile di ops rimanente, prima che inizi qualsiasi elaborazione.
4. Tieni traccia dell'avanzamento tramite `GET /v1/convert/batch/{batch_id}`, oppure ricevi un webhook callback o una notifica email al completamento.
5. Scarica i risultati tramite URL presigned nella risposta di stato del batch.

---

## Output Modes

### Modalità Individuale (Predefinita)

Ogni URL produce un file separato. Ogni file riceve il proprio URL di download presigned nella risposta di stato del batch.

**Richiesta:**

```bash
curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": [
      "https://example.com/page-1",
      "https://example.com/page-2",
      "https://example.com/page-3"
    ]
  }'
```

**Risposta (HTTP 202 Accepted):**

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

<div class="alert alert-info">
<strong>Nota:</strong> Quando passi più URL, <code>async_mode</code> viene impostato automaticamente su <code>true</code>, indipendentemente dal fatto che tu lo includa esplicitamente nella richiesta.
</div>

### Modalità Bundle ZIP

Imposta `output_format` su `true` per ricevere tutti i file convertiti raggruppati in un unico archivio ZIP. Richiede un piano con accesso all'output ZIP.

**Richiesta:**

```bash
curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": [
      "https://example.com/page-1",
      "https://example.com/page-2",
      "https://example.com/page-3"
    ],
    "output_format": true,
    "output_filename": "monthly-reports"
  }'
```

**Risposta (HTTP 202 Accepted):**

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

In modalità ZIP, tutti gli URL vengono elaborati in sequenza e i risultati riusciti vengono raggruppati in un unico archivio ZIP denominato `{output_filename}_{timestamp}.zip` (oppure `batch_{timestamp}.zip` se non viene fornito un nome personalizzato).

---

## Parametri Batch

| Parametro | Tipo | Predefinito | Descrizione | Limitazione per Piano |
|-----------|------|---------|-------------|-------------|
| `url` | `string[]` | *(obbligatorio)* | Array di URL da convertire. | -- |
| `output_format` | `boolean` | `false` | Imposta su `true` per raggruppare tutti i risultati in un archivio ZIP. Richiede più URL. | Richiede accesso all'output ZIP |
| `output_filename` | `string` | Generato automaticamente | Nome file personalizzato per l'output. In modalità ZIP, assegna il nome all'archivio ZIP. | -- |
| `async_mode` | `boolean` | `true` (implicito) | Sempre `true` per il batch. Abilitato automaticamente quando vengono forniti più URL. | Richiede accesso asincrono |
| `notification_email` | `string` | Email del proprietario del progetto | Indirizzo email da notificare al completamento. Se omesso, viene usata di default l'email del proprietario del progetto. | -- |
| `callback_url` | `string` | `null` | URL webhook su cui ricevere una POST al completamento. | Richiede accesso webhook |
| `direct_download` | -- | -- | **Non supportato** per il batch. Restituisce un errore 400 se impostato con più URL. | -- |

### Parametri di Browser e Rendering

Queste impostazioni si applicano a ogni URL del batch:

| Parametro | Tipo | Predefinito | Descrizione |
|-----------|------|---------|-------------|
| `viewport_width` | `integer` | `1920` | Larghezza del viewport del browser in pixel. |
| `viewport_height` | `integer` | `1080` | Altezza del viewport del browser in pixel. |
| `single_page` | `boolean` | `true` | Esegue il rendering come pagina unica continua (solo url-to-pdf). |
| `load_media` | `boolean` | `true` | Attende il caricamento di immagini e media. |
| `enable_scroll` | `boolean` | `true` | Scorre le pagine per attivare i contenuti a caricamento differito (lazy-loaded). |
| `handle_sticky_header` | `boolean` | `true` | Rileva e gestisce le intestazioni sticky/fisse. |
| `handle_cookies` | `boolean` | `true` | Chiude automaticamente i banner di consenso cookie. |
| `wait_for_images` | `boolean` | `true` | Attende il completamento del caricamento di tutte le immagini. |

### Autenticazione e Richieste Personalizzate

Si applicano a ogni URL del batch. Richiedono un piano con accesso all'autenticazione basic.

| Parametro | Tipo | Predefinito | Descrizione |
|-----------|------|---------|-------------|
| `auth` | `object` | `null` | Credenziali HTTP Basic Auth: `{"username": "...", "password": "..."}`. |
| `cookies` | `array` | `null` | Array di oggetti cookie iniettati prima di ogni caricamento pagina. Massimo 50. |
| `headers` | `object` | `null` | Header HTTP personalizzati inviati con ogni richiesta. Massimo 20. |

### Opzioni PDF (solo url-to-pdf)

Passa un oggetto `pdf_options` per controllare la formattazione dell'output PDF per ogni pagina del batch:

| Parametro | Tipo | Predefinito | Descrizione |
|-----------|------|---------|-------------|
| `page_size` | `string` | `"A4"` | Formato pagina denominato. |
| `orientation` | `string` | `"portrait"` | `"portrait"` oppure `"landscape"`. |
| `margins` | `object` | `{"top": 10, "bottom": 10, "left": 10, "right": 10}` | Margini in mm. |
| `grayscale` | `boolean` | `false` | Output in scala di grigi tramite Ghostscript. |

---

## Polling dello Stato del Batch {: #batch-status-polling }

Usa l'endpoint di stato del batch per controllare l'avanzamento e recuperare gli URL di download.

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

Sostituisci `{batch_id}` con il `batch_id` restituito dalla richiesta iniziale.

### Stato di Elaborazione

Mentre le conversioni sono ancora in corso:

```json
{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "processing",
    "total": 3,
    "completed": 1,
    "failed": 0,
    "in_progress": 2,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "In Progress",
            "download_url": null,
            "output_file_size": null,
            "duration": null
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "In Progress",
            "download_url": null,
            "output_file_size": null,
            "duration": null
        }
    ]
}
```

### Stato Completato

Quando tutti gli URL sono stati convertiti con successo:

```json
{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "total": 3,
    "completed": 3,
    "failed": 0,
    "in_progress": 0,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 97280,
            "duration": "2.87"
        }
    ]
}
```

### Stato Parziale

Quando tutti gli URL hanno terminato ma alcuni sono falliti:

```json
{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "partial",
    "total": 3,
    "completed": 2,
    "failed": 1,
    "in_progress": 0,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://invalid-url.example",
            "status": "Failed",
            "download_url": null,
            "output_file_size": null,
            "duration": "0.87"
        }
    ]
}
```

### Modalità ZIP Completata

In modalità ZIP, viene fornito un singolo `zip_download_url` per l'intero archivio:

```json
{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "total": 3,
    "completed": 3,
    "failed": 0,
    "in_progress": 0,
    "output_mode": "zip",
    "zip_download_url": "https://spaces.example.com/...",
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 97280,
            "duration": "2.87"
        }
    ]
}
```

### Valori di Stato del Batch

| Stato | Significato |
|--------|---------|
| `processing` | Almeno un URL è ancora in fase di conversione. |
| `completed` | Tutti gli URL sono stati convertiti con successo. |
| `partial` | Tutti gli URL hanno terminato, ma alcuni sono falliti. |
| `failed` | Tutti gli URL sono falliti. |

---

## Webhook Callback

Fornisci un `callback_url` nella richiesta per ricevere una notifica POST automatica al completamento. Il webhook viene inviato con `Content-Type: application/json` e un timeout di 30 secondi. Non viene effettuato alcun retry in caso di fallimento della consegna.

### Callback in Modalità Individuale

In modalità individuale, viene inviata una **POST webhook separata per ogni URL** man mano che si completa:

```json
{
    "job_id": "12345",
    "status": "success",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "gcs_uri": "env/files/{project_id}/url-to-pdf/page1_20260405_123456789.pdf",
    "filename": "page1_20260405_123456789.pdf",
    "file_size": 184320
}
```

### Callback in Modalità ZIP

In modalità ZIP, viene inviata una **singola POST webhook quando l'intero batch si completa**:

```json
{
    "job_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "success",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "gcs_uri": "env/files/{project_id}/url-to-pdf/batch_20260405_123456789.zip",
    "filename": "batch_20260405_123456789.zip",
    "file_size": 456789,
    "total_tasks": 3,
    "successful_tasks": 2,
    "failed_tasks": 1,
    "tasks": [
        {"url": "https://example.com/page-1", "status": "success", "filename": "page1.pdf"},
        {"url": "https://example.com/page-2", "status": "success", "filename": "page2.pdf"},
        {"url": "https://invalid.example", "status": "failed", "error": "Page load timeout"}
    ]
}
```

<div class="alert alert-info">
<strong>Differenza nel comportamento delle notifiche:</strong> In modalità individuale, ricevi N POST webhook separate (una per URL) e N email separate. In modalità ZIP, ricevi una POST webhook e una email per l'intero batch. Tienine conto quando progetti il tuo gestore webhook.
</div>

---

## Notifiche Email

Un'email di completamento viene inviata a `notification_email` quando il batch termina. Se non viene fornito alcun `notification_email`, l'email viene inviata di default all'email del proprietario del progetto.

L'email include:

- Stato del job (success/failed) con un banner colorato
- Batch ID
- Per i job batch: una tabella con l'elenco di ogni URL, il relativo stato e il nome del file di output
- Un link per scaricare i risultati dalla dashboard

---

## Limitazioni per Piano di Abbonamento

| Funzionalità | Founding | Indie | Studio | Enterprise |
|---------|------|---------|-----|------------|
| Elaborazione batch | No | Sì | Sì | Sì |
| Modalità asincrona | No | Sì | Sì | Sì |
| Raggruppamento output ZIP | No | No | Sì | Sì |
| Webhook callback | No | No | Sì | Sì |
| HTTP Basic Auth / Cookie / Header | No | Sì | Sì | Sì |
| Limite dimensione batch | 0 | In base al piano | In base al piano | Illimitato |
| Conversioni mensili | 100 | In base al piano | In base al piano | Illimitato |

---

## Esempi di Codice

### Python -- Modalità Individuale con Polling

```python
import requests
import time

# Submit batch
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/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ]
    }
)

data = response.json()
batch_id = data["batch_id"]
print(f"Batch started: {batch_id} ({data['url_count']} URLs)")

# Poll for completion
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"):
        for item in status["items"]:
            if item["download_url"]:
                print(f"  {item['source_url']} -> {item['download_url']}")
        break

    time.sleep(5)
```

### Python -- Modalità ZIP con Webhook

```python
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/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ],
        "output_format": True,
        "output_filename": "monthly-reports",
        "callback_url": "https://your-server.com/webhook/enconvert",
        "pdf_options": {
            "page_size": "A4",
            "orientation": "portrait"
        }
    }
)

data = response.json()
print(f"Batch started: {data['batch_id']}")
print(f"URLs: {data['url_count']}, Format: {data['output_format']}")
# Results will be delivered to your webhook URL
```

### Node.js -- Screenshot in Batch

```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/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ],
        output_format: true,
        output_filename: "screenshots-bundle"
    })
});

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

---

## Risposte di Errore

| Stato | Condizione |
|--------|-----------|
| `400 Bad Request` | `url` è vuoto o mancante |
| `400 Bad Request` | `output_format=true` con un singolo URL (richiede più URL) |
| `400 Bad Request` | `direct_download=true` con più URL (non supportato) |
| `400 Bad Request` | `direct_download=true` con `async_mode=true` |
| `400 Bad Request` | Chiave pubblica che tenta più URL |
| `402 Payment Required` | Il batch supererebbe la quota mensile di ops rimanente |
| `402 Payment Required` | Limite di storage raggiunto |
| `403 Forbidden` | Elaborazione asincrona non disponibile sul piano attuale |
| `403 Forbidden` | Elaborazione batch non disponibile (limite batch pari a 0) |
| `403 Forbidden` | La dimensione del batch supera il limite del piano |
| `403 Forbidden` | Output ZIP non disponibile sul piano attuale |
| `403 Forbidden` | Webhook callback non disponibili sul piano attuale |
| `404 Not Found` | Batch non trovato (batch_id errato o progetto errato) |

---

## Limiti

| Limite | Valore |
|-------|-------|
| Dimensione batch | Dipende dal piano (Founding: disabilitato) |
| Conversioni mensili | Dipende dal piano (l'intero batch viene verificato in anticipo) |
| Timeout di consegna webhook | 30 secondi (nessun retry) |
| Numero massimo di cookie per richiesta | 50 |
| Numero massimo di header personalizzati per richiesta | 20 |
| Conservazione dei file | Dipende dal piano |

## Domande frequenti

### Come converto più URL in PDF con un'unica richiesta API?

Invia una POST a `/v1/convert/url-to-pdf` con un array di URL nel parametro `url`, autenticandoti con una chiave API privata (`sk_...`). L'API risponde con `HTTP 202` e un `batch_id`, e ogni URL viene convertito in background.

### Posso ottenere tutti i risultati della conversione batch in un unico file ZIP?

Sì. Imposta `output_format` su `true` per raggruppare tutti i risultati riusciti in un unico archivio ZIP denominato `{output_filename}_{timestamp}.zip` (oppure `batch_{timestamp}.zip` se non viene fornito un nome personalizzato). L'output ZIP richiede un piano con accesso all'output ZIP (Studio, Production o Enterprise) e più URL nella richiesta.

### Come controllo lo stato di un job di conversione batch?

Effettua il polling di `GET /v1/convert/batch/{batch_id}` con la tua chiave API privata. La risposta indica `processing`, `completed`, `partial`, oppure `failed`, insieme agli elementi per singolo URL contenenti `download_url`, `output_file_size` e `duration`.

### Perché la mia richiesta batch restituisce 403 Forbidden?

Un `403 Forbidden` indica che è stata raggiunta una limitazione del piano: l'elaborazione asincrona non è disponibile sul tuo piano, l'elaborazione batch è disabilitata (limite batch pari a 0), la dimensione del batch supera il limite del tuo piano, oppure una funzionalità limitata come l'output ZIP o i webhook callback non è inclusa nel tuo piano.

### Posso usare l'elaborazione batch con una chiave API pubblica?

No. L'elaborazione batch richiede una chiave API privata (`sk_...`). Le chiavi pubbliche sono limitate a richieste sincrone su singolo URL, e l'invio di più URL con una chiave pubblica restituisce `400 Bad Request`.
