1 creditImage to PDF API — photos to documents
HEIC, PNG, JPG — one API, one PDF out.
Image to PDF combines one or more images into a single PDF, in the order you supply them. Each image becomes a page, or several can be fitted per page. The two settings that determine whether the result looks right are page sizing — whether images are scaled to fit or the page adapts to the image — and orientation, which is frequently wrong because of EXIF rotation data.
How does the Image to PDF API work?
One HTTP request from any language. Every ASHDOCS endpoint uses the same X-API-Key header.
curl -X POST https://www.ashdocs.com/api/v1/tools/image-to-pdf \ -H "X-API-Key: ash_live_..." \ -F "files=@photo-1.jpg" \ -F "files=@photo-2.jpg"
import requests
r = requests.post(
"https://www.ashdocs.com/api/v1/tools/image-to-pdf",
headers={"X-API-Key": "ash_live_..."},
files=[("files", open("photo-1.jpg", "rb")), ("files", open("photo-2.jpg", "rb"))],
)
job = r.json()
print(job["status"], job["output_files"][0]["url"])import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("files", new Blob([await readFile("photo-1.jpg")]), "photo-1.jpg");
form.append("files", new Blob([await readFile("photo-2.jpg")]), "photo-2.jpg");
const res = await fetch("https://www.ashdocs.com/api/v1/tools/image-to-pdf", {
method: "POST",
headers: { "X-API-Key": "ash_live_..." },
body: form,
});
const job = await res.json();
console.log(job.status, job.output_files[0].url);using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "ash_live_...");
using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(await File.ReadAllBytesAsync("photo-1.jpg")), "files", "photo-1.jpg");
form.Add(new ByteArrayContent(await File.ReadAllBytesAsync("photo-2.jpg")), "files", "photo-2.jpg");
var res = await client.PostAsync("https://www.ashdocs.com/api/v1/tools/image-to-pdf", form);
var job = await res.Content.ReadAsStringAsync();
Console.WriteLine(job);import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class Sample {
static final String BOUNDARY = "AshdocsBoundary7MA4YWxkTrZu0gW";
public static void main(String[] args) throws Exception {
ByteArrayOutputStream body = new ByteArrayOutputStream();
addFile(body, "files", "photo-1.jpg");
addFile(body, "files", "photo-2.jpg");
body.write(("--" + BOUNDARY + "--\r\n").getBytes(StandardCharsets.UTF_8));
HttpRequest req = HttpRequest.newBuilder(URI.create("https://www.ashdocs.com/api/v1/tools/image-to-pdf"))
.header("X-API-Key", "ash_live_...")
.header("Content-Type", "multipart/form-data; boundary=" + BOUNDARY)
.POST(HttpRequest.BodyPublishers.ofByteArray(body.toByteArray()))
.build();
HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
static void addFile(ByteArrayOutputStream body, String name, String path) throws Exception {
body.write(("--" + BOUNDARY + "\r\nContent-Disposition: form-data; name=\"" + name + "\"; filename=\""
+ Path.of(path).getFileName() + "\"\r\nContent-Type: application/octet-stream\r\n\r\n").getBytes(StandardCharsets.UTF_8));
body.write(Files.readAllBytes(Path.of(path)));
body.write("\r\n".getBytes(StandardCharsets.UTF_8));
}
static void addField(ByteArrayOutputStream body, String name, String value) throws Exception {
body.write(("--" + BOUNDARY + "\r\nContent-Disposition: form-data; name=\"" + name + "\"\r\n\r\n"
+ value + "\r\n").getBytes(StandardCharsets.UTF_8));
}
}#include <stdio.h>
#include <curl/curl.h>
int main(void) {
CURL *curl = curl_easy_init();
if (!curl) return 1;
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "X-API-Key: ash_live_...");
curl_mime *mime = curl_mime_init(curl);
curl_mimepart *part;
part = curl_mime_addpart(mime);
curl_mime_name(part, "files");
curl_mime_filedata(part, "photo-1.jpg");
part = curl_mime_addpart(mime);
curl_mime_name(part, "files");
curl_mime_filedata(part, "photo-2.jpg");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
curl_easy_setopt(curl, CURLOPT_URL, "https://www.ashdocs.com/api/v1/tools/image-to-pdf");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
CURLcode rc = curl_easy_perform(curl);
printf("\n");
curl_mime_free(mime);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return rc == CURLE_OK ? 0 : 1;
}How do I use Image to PDF API in Make, Zapier or n8n?
Add an HTTP "Make a request" module, POST the images, and turn off Parse response so the PDF binary arrives intact.
Make setup guide →Use Webhooks by Zapier with a POST action and map the returned file URL into a Drive upload or an email attachment.
Zapier setup guide →Trigger on a record with multiple image attachments, combine them, and write the PDF back to a separate attachment field.
Airtable setup guide →Common problems and fixes
| Symptom | Cause | Fix |
|---|---|---|
| Photographs appear rotated | EXIF orientation data is being ignored | Enable EXIF-aware processing, or strip and apply the rotation before conversion. Phone photographs are stored in sensor orientation with a rotation flag, and ignoring that flag turns portrait shots sideways. |
| Images look stretched | Aspect ratio not preserved when fitting to a fixed page size | Use fit-to-page with aspect ratio preserved, or let the page size follow the image dimensions. |
| The PDF is very large | Full-resolution photographs embedded without compression | Downscale before conversion, or run compression afterwards. A twelve-megapixel photo per page produces an unusable file size quickly. |
| Images appear blurry in print | Source resolution too low for the printed size | Use images at 150 DPI minimum for the intended print dimensions, 300 DPI for anything detailed. |
| Pages come out in the wrong order | Filename sorting is alphabetical, not numeric | Zero-pad your filenames — img-001 rather than img-1 — or supply an explicit ordering. |
| HEIC files are rejected | HEIC needs a specific decoder | Convert to JPEG or PNG first if HEIC is not supported. Check the accepted formats before building around iPhone photographs. |
Common use cases
- →Scan bundling
- →Camera-roll to receipts
- →Mobile document capture
Frequently asked questions
How do I combine multiple images into one PDF?+
Send the images to the endpoint in the order you want them. Each becomes a page, or several can be fitted per page depending on your layout option.
Which image formats are supported?+
JPEG, PNG and WebP are handled universally. HEIC — the iPhone default — requires a specific decoder, so verify support before building a workflow around phone photographs.
How do I stop images being rotated incorrectly?+
Enable EXIF-aware processing. Phone cameras store photographs in sensor orientation with a rotation flag, and ignoring that flag turns portrait images sideways.
Can I set the page size when converting images to PDF?+
Yes. Either fix the page size and scale images to fit, preserving aspect ratio, or let each page take the dimensions of its image. Fixed size suits printing; image-sized pages suit screen viewing.
How do I reduce the file size of an image PDF?+
Downscale the source images before conversion, or run PDF compression afterwards. Full-resolution photographs embedded directly produce very large files.