---
seo_title: Conversion Webhook Callback API for Job Notifications | EnConvert
meta_desc: Receive a webhook POST via callback_url when async conversion jobs complete. Also supports email notifications and polling GET /v1/convert/batch/{batch_id}.
keywords: conversion webhook callback api, async job completion webhook, webhook when file conversion completes, callback_url parameter, batch status polling api, conversion completion email notification, webhook payload json example, test webhook callback api
---

# Conversion Webhook Callbacks & Job Notifications

EnConvert notifies you when asynchronous and batch conversion jobs complete through three independent mechanisms: polling `GET /v1/convert/batch/{batch_id}`, webhook callbacks via the `callback_url` parameter, and email notifications via `notification_email`. All three can be combined in a single request, and finished files are retrieved through download URLs in the batch status response. This page documents the callback payloads, delivery requirements, and plan gating for each method.

<div class="alert alert-warning">
<strong>Private Keys Only:</strong> Job notifications and batch status polling are only available when authenticating with a <strong>private API key</strong> (<code>X-API-Key: sk_...</code>). Public keys do not support async or batch processing.
</div>

---

## Overview

| Method | Parameter / Endpoint | Description |
|--------|---------------------|-------------|
| Polling | `GET /v1/convert/batch/{batch_id}` | Poll for real-time status, progress counts, and download URLs. |
| Email | `notification_email` | Sends a completion email with job status and a dashboard link. |
| Webhook | `callback_url` | Sends a POST request with the job results to your server. |

All three methods work for both single-URL async jobs and multi-URL batch jobs across the [url-to-pdf](/docs/endpoints/convert/web-pages/url-to-pdf.md), [url-to-screenshot](/docs/endpoints/convert/web-pages/url-to-screenshot.md), [website-to-pdf](/docs/endpoints/convert/web-pages/website-to-pdf.md), and [website-to-screenshot](/docs/endpoints/convert/web-pages/website-to-screenshot.md) endpoints.

---

## Batch Status Polling

The recommended way to track job progress. Poll the batch status endpoint with the `batch_id` returned in the initial 202 response.

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

### Response

```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
        }
    ]
}
```

### Status Values

| Status | Meaning |
|--------|---------|
| `processing` | At least one URL is still being converted. |
| `completed` | All URLs converted successfully. |
| `partial` | All URLs finished, but some failed. |
| `failed` | All URLs failed. |

In ZIP mode (`output_mode: "zip"`), a `zip_download_url` is provided for the entire archive when complete. In individual mode, each item has its own `download_url`.

For full response schema details, see [Batch Processing](/docs/guides/batch-processing.md#batch-status-polling).

---

## Email Notifications

Include the `notification_email` parameter in your request to receive an email when the job completes. If you omit this parameter, the email is sent to the **project owner's email address** by default.

### Example

```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",
    "async_mode": true,
    "notification_email": "team@yourcompany.com"
  }'
```

### Response (HTTP 202 Accepted)

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

### Email Content

The completion email includes:

- **Status header** with a colored banner (green for success, red for failure)
- **Job ID** and **Batch ID** (if part of a batch)
- **Status text** (success or failed)
- **Static text** directing users to download files from their dashboard
- **Tasks table** (ZIP mode batch jobs only) with columns: #, URL (truncated to 50 characters), status, and output filename

In individual mode (including multi-URL individual batches), each per-URL email contains only the job ID and status -- no tasks table. In ZIP mode, the single batch email includes the full tasks table with all URLs and their statuses.

<div class="alert alert-info">
<strong>Default behavior:</strong> If you do not include <code>notification_email</code> in your request, the completion email is sent to the project owner's email address automatically. To suppress email notifications entirely, this default cannot currently be disabled.
</div>

---

## Webhook Callbacks

Include the `callback_url` parameter in your request to receive a webhook POST when the job completes. Requires a plan with webhook access.

### Example

```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",
    "async_mode": true,
    "callback_url": "https://yourapp.com/webhooks/enconvert"
  }'
```

### Response (HTTP 202 Accepted)

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

### Single URL / Individual Mode Callback Payload

In individual mode, a **separate POST is sent for each URL** as it completes:

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

For a failed conversion:

```json
{
    "job_id": "12345",
    "status": "failed",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

### ZIP Mode Callback Payload

In ZIP mode, a **single POST is sent when the entire batch completes**:

```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-url.example", "status": "failed", "error": "Page load timeout"}
    ]
}
```

<div class="alert alert-warning">
<strong>Individual vs ZIP notification behavior:</strong> In individual mode, you receive <strong>N separate webhook POSTs</strong> (one per URL) and <strong>N separate emails</strong>. In ZIP mode, you receive <strong>one webhook POST</strong> and <strong>one email</strong> for the entire batch. Design your webhook handler accordingly.
</div>

---

## Using Multiple Notification Methods Together

You can combine polling, email, and webhook in the same request. All three work independently.

```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"
    ],
    "notification_email": "team@yourcompany.com",
    "callback_url": "https://yourapp.com/webhooks/enconvert"
  }'
```

After submitting, you can:
1. **Poll** `GET /v1/convert/batch/{batch_id}` for real-time progress
2. **Receive a webhook POST** at your callback URL when each conversion finishes
3. **Receive an email** at the specified address when each conversion finishes

---

## Notification Parameters

| Parameter | Type | Required | Default | Description | Plan Gating |
|-----------|------|----------|---------|-------------|-------------|
| `notification_email` | `string` | No | Project owner email | Email address to receive job completion notifications. | -- |
| `callback_url` | `string` | No | -- | URL to receive a webhook POST on completion. | Requires webhook access |

---

## Webhook Delivery Requirements

| Requirement | Detail |
|-------------|--------|
| **Method** | EnConvert sends a `POST` request with `Content-Type: application/json`. |
| **Timeout** | Your endpoint must respond within **30 seconds**. |
| **Success codes** | HTTP `200`, `201`, `202`, or `204` are treated as successful delivery. |
| **Retries** | No retries on failure. If the webhook delivery fails (non-success response or timeout), results are still available via batch status polling. |
| **Authentication** | No authentication headers are sent. Validate the `batch_id` against your records if needed. |

---

## Subscription Plan Gating

| Feature | Founding | Indie | Studio | Enterprise |
|---------|------|---------|-----|------------|
| Async mode | No | Yes | Yes | Yes |
| Batch status polling | No | Yes | Yes | Yes |
| Email notifications | No | Yes | Yes | Yes |
| Webhook callbacks (`callback_url`) | No | No | Yes | Yes |

<div class="alert alert-info">
<strong>Note:</strong> Email notifications are not separately feature-gated -- they are available to any private API key user with async access. The <code>notification_email</code> parameter does not require a specific plan feature. Webhook callbacks (<code>callback_url</code>) require the <code>has_webhook</code> feature, which is available on Studio plans and above.
</div>

---

## Testing Webhooks

During development, use [webhook.site](https://webhook.site) to generate a temporary callback URL for testing:

```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",
    "async_mode": true,
    "callback_url": "https://webhook.site/your-unique-id"
  }'
```

Visit your webhook.site dashboard to inspect the exact callback payload once the job completes.

## Frequently asked questions

### How do I get a webhook callback when a file conversion job completes?

Include the `callback_url` parameter in your request with a private API key. EnConvert sends a `POST` with `Content-Type: application/json` to that URL when the job completes. Webhook callbacks require a plan with webhook access (Studio, Production, or Enterprise).

### Does EnConvert retry failed webhook deliveries?

No. Your endpoint must respond within 30 seconds with HTTP `200`, `201`, `202`, or `204`. If delivery fails, results remain available via batch status polling at `GET /v1/convert/batch/{batch_id}`.

### Can I use email, webhook, and polling notifications together?

Yes. `notification_email`, `callback_url`, and status polling all work independently and can be combined in the same request. If `notification_email` is omitted, the completion email defaults to the project owner's email address.

### Why do I receive one webhook per URL instead of one for the whole batch?

In individual mode you receive N separate webhook POSTs (one per URL) and N separate emails. To receive a single webhook and email for the entire batch, use ZIP mode, which sends one POST with `total_tasks`, `successful_tasks`, `failed_tasks`, and a `tasks` array.

### How can I test webhook callbacks during development?

Use webhook.site to generate a temporary URL and pass it as `callback_url` in your request. The webhook.site dashboard shows the exact JSON payload EnConvert delivers when the job completes.
