---
seo_title: HEIC to WebP API: Convert HEIC Images to WebP | EnConvert
meta_desc: Convert HEIC to WebP via POST /v1/convert/heic-to-webp. Alpha channel preserved, maximum quality output, raw WebP bytes or a presigned download URL.
keywords: heic to webp api, convert heic to webp, heic to webp converter api, heif to webp api, heic to webp rest api, convert heic to webp programmatically, heic to webp with alpha channel
---

# HEIC to WebP API

Convert HEIC to WebP with the `POST /v1/convert/heic-to-webp` endpoint, which converts a HEIC/HEIF image to a high-quality WebP file. If the HEIC has an alpha channel, it is preserved in the WebP output. Responses return raw WebP bytes by default, or JSON metadata with a presigned download URL when `direct_download=false`.

---

## Endpoint

```
POST /v1/convert/heic-to-webp
```

**Content-Type:** `multipart/form-data`

**Accepted input:** `.heic or .heif` files

**Output format:** `.webp` (`image/webp`)

---

## Authentication

Requires either a private API key or a JWT token from a public key.

```
X-API-Key: sk_your_private_key
```

Or:

```
Authorization: Bearer <jwt_token>
```

---

## Request Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `file` | file | Yes | -- | The `.heic or .heif` image file to convert. |
| `output_filename` | `string` | No | Input filename | Custom output filename. The `.webp` extension is added automatically. |
| `direct_download` | `boolean` | No | `true` | When `true`, returns raw image bytes. When `false`, returns JSON metadata with a presigned download URL. |

---

## Conversion Details

- Uses **pillow-heif** for HEIC decoding and **Pillow** for WebP encoding
- If the HEIC has an alpha channel, it is preserved in the WebP output
- Output quality is set to maximum (100)
- WebP typically achieves smaller file sizes than JPEG at equivalent quality


---

## Response

### Direct Download (`direct_download=true`, default)

```
HTTP 200 OK
Content-Type: image/webp
Content-Disposition: inline; filename="photo_20260405_123456789.webp"
```

Returns raw image bytes.

### Metadata Response (`direct_download=false`)

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/heic-to-webp/photo_20260405_123456789.webp",
    "filename": "photo_20260405_123456789.webp",
    "file_size": 45678,
    "conversion_time_seconds": 0.5
}
```

---

## Code Examples

### Python

```python
import requests

with open("photo.heic", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/heic-to-webp",
        headers={"X-API-Key": "sk_your_private_key"},
        files={"file": ("photo.heic", f)}
    )

with open("photo_20260405_123456789.webp", "wb") as out:
    out.write(response.content)
```

### Node.js

```javascript
const form = new FormData();
form.append("file", fs.createReadStream("photo.heic"));

const response = await fetch("https://api.enconvert.com/v1/convert/heic-to-webp", {
    method: "POST",
    headers: { "X-API-Key": "sk_your_private_key" },
    body: form
});

fs.writeFileSync("photo_20260405_123456789.webp", Buffer.from(await response.arrayBuffer()));
```

### PHP

```php
$ch = curl_init("https://api.enconvert.com/v1/convert/heic-to-webp");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_your_private_key"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("photo.heic")]
]);
$output = curl_exec($ch);
curl_close($ch);
file_put_contents("photo_20260405_123456789.webp", $output);
```

### Go

```go
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "photo.heic")
file, _ := os.Open("photo.heic")
io.Copy(part, file)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/heic-to-webp", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_your_private_key")
resp, _ := http.DefaultClient.Do(req)
```

---

## Error Responses

| Status | Condition |
|--------|-----------|
| `400 Bad Request` | File is not a `.heic or .heif` file |
| `400 Bad Request` | Image conversion failed (corrupt or unsupported file) |
| `401 Unauthorized` | Missing or invalid API key / JWT token |
| `402 Payment Required` | Monthly ops allowance exhausted |
| `402 Payment Required` | Storage limit reached |
| `413 Payload Too Large` | File exceeds plan's maximum file size |

---

## Limits

| Limit | Value |
|-------|-------|
| Max file size | Plan-dependent (Founding: 5 MB) |
| Output quality | Maximum (not configurable) |
| Monthly conversions | Plan-dependent |

---

## Frequently asked questions

### How do I convert a HEIC image to WebP with a REST API?

Send a `multipart/form-data` POST request to `/v1/convert/heic-to-webp` with the `.heic` or `.heif` file in the `file` field, authenticated via `X-API-Key` or a Bearer JWT. The response returns raw WebP bytes by default, or set `direct_download=false` to receive JSON with a presigned download URL.

### Does HEIC to WebP conversion keep the alpha channel?

Yes. If the HEIC has an alpha channel, it is preserved in the WebP output. Decoding uses pillow-heif and encoding uses Pillow.

### Is WebP smaller than JPEG for the same image?

WebP typically achieves smaller file sizes than JPEG at equivalent quality. This endpoint encodes at maximum quality (100), which is not configurable.

### Why does the HEIC to WebP endpoint return a 402 error?

`402 Payment Required` means your plan's monthly ops allowance or storage limit has been reached. Files exceeding your plan's maximum size return `413 Payload Too Large` instead.
