---
seo_title: HEIC to JPG API: Convert iPhone Photos to JPEG | EnConvert
meta_desc: Convert HEIC to JPG with a REST API. POST /v1/convert/heic-to-jpeg decodes .heic and .heif files and returns a high-quality JPEG as bytes or a presigned URL.
keywords: heic to jpg api, heic to jpeg api, convert heic to jpg programmatically, convert iphone photos api, heic converter rest api, heif to jpeg api, decode heic api, heic to jpg python
---

# HEIC to JPG API

Convert HEIC/HEIF images to JPEG programmatically with `POST /v1/convert/heic-to-jpeg`. The endpoint accepts a `.heic` or `.heif` upload, decodes it, and produces a high-quality JPEG. Responses return either raw image bytes for direct download or JSON metadata with a presigned download URL.

---

## Endpoint

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

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

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

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

---

## 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 `.jpeg` 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 JPEG encoding
- If the HEIC image has an alpha channel, transparent areas are composited onto a **white background**
- Output quality is set to maximum (100)


---

## Response

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

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

Returns raw image bytes.

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

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/heic-to-jpeg/photo_20260405_123456789.jpeg",
    "filename": "photo_20260405_123456789.jpeg",
    "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-jpeg",
        headers={"X-API-Key": "sk_your_private_key"},
        files={"file": ("photo.heic", f)}
    )

with open("photo_20260405_123456789.jpeg", "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-jpeg", {
    method: "POST",
    headers: { "X-API-Key": "sk_your_private_key" },
    body: form
});

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

### PHP

```php
$ch = curl_init("https://api.enconvert.com/v1/convert/heic-to-jpeg");
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.jpeg", $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-jpeg", 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 HEIC to JPG with a REST API?

Send a `multipart/form-data` POST request to `/v1/convert/heic-to-jpeg` with your `.heic` or `.heif` file in the `file` field, authenticated via `X-API-Key` or a `Bearer` JWT token. By default the API responds with the raw JPEG bytes.

### Does the API accept both .heic and .heif files?

Yes. The `file` parameter accepts `.heic` or `.heif` files; anything else returns `400 Bad Request`. Decoding uses pillow-heif and JPEG encoding uses Pillow.

### What happens if the HEIC image has transparency?

JPEG does not support transparency, so if the HEIC image has an alpha channel, transparent areas are composited onto a white background in the output.

### Can I get a download URL instead of raw image bytes?

Yes. Set `direct_download=false` and the API returns JSON metadata including a `presigned_url`, `object_key`, `filename`, `file_size`, and `conversion_time_seconds`.
