API Documentation
Integrate our service into your applications with a simple REST API.
Quick Start
Remove a background in three steps. Choose your language:
Get your API key
Sign up and subscribe to a paid plan to get your API key from the dashboard. Use it as a Bearer token in all requests:
Authorization: Bearer YOUR_API_TOKEN
Upload an image for background removal
curl -X POST https://www.print-ready.ai/api/images/remove-background \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "image=@photo.jpg" \ -F "quality=basic" # Returns 202 with image ID and status "pending"
import requests
response = requests.post(
"https://www.print-ready.ai/api/images/remove-background",
headers={"Authorization": f"Bearer {token}"},
files={"image": open("photo.jpg", "rb")},
data={"quality": "basic"}
)
image_id = response.json()["data"]["id"]
const form = new FormData();
form.append("image", fileInput.files[0]);
form.append("quality", "basic");
const response = await fetch("https://www.print-ready.ai/api/images/remove-background", {
method: "POST",
headers: { "Authorization": `Bearer ${token}` },
body: form
});
const imageId = (await response.json()).data.id;
$response = Http::withToken($token)
->attach('image', file_get_contents('photo.jpg'), 'photo.jpg')
->post('https://www.print-ready.ai/api/images/remove-background', [
'quality' => 'basic',
]);
$imageId = $response->json('data.id');
Poll until complete, then download
# Poll for completion
while true; do
STATUS=$(curl -s https://www.print-ready.ai/api/images/$IMAGE_ID \
-H "Authorization: Bearer YOUR_API_TOKEN" \
| jq -r '.data.status')
echo "Status: $STATUS"
[ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
sleep 3
done
# Download the result
curl -s https://www.print-ready.ai/api/images/$IMAGE_ID/download \
-H "Authorization: Bearer YOUR_API_TOKEN"
import time
# Poll for completion
while True:
result = requests.get(
f"https://www.print-ready.ai/api/images/{image_id}",
headers={"Authorization": f"Bearer {token}"}
).json()
status = result["data"]["status"]
print(f"Status: {status}")
if status in ("completed", "failed"):
break
time.sleep(3)
# Get the download URL
download = requests.get(
f"https://www.print-ready.ai/api/images/{image_id}/download",
headers={"Authorization": f"Bearer {token}"}
).json()
print(download["data"]["url"])
// Poll for completion
let result;
while (true) {
const res = await fetch(`https://www.print-ready.ai/api/images/${imageId}`, {
headers: { "Authorization": `Bearer ${token}` }
});
result = await res.json();
console.log(`Status: ${result.data.status}`);
if (["completed", "failed"].includes(result.data.status)) break;
await new Promise(r => setTimeout(r, 3000));
}
// Get the download URL
const dl = await fetch(`https://www.print-ready.ai/api/images/${imageId}/download`, {
headers: { "Authorization": `Bearer ${token}` }
});
const { data } = await dl.json();
console.log(data.url);
// Poll for completion
do {
$result = Http::withToken($token)
->get("https://www.print-ready.ai/api/images/{$imageId}")
->json();
$status = $result['data']['status'];
echo "Status: {$status}\n";
if (in_array($status, ['completed', 'failed'])) break;
sleep(3);
} while (true);
// Get the download URL
$download = Http::withToken($token)
->get("https://www.print-ready.ai/api/images/{$imageId}/download")
->json();
echo $download['data']['url'];
Overview
The Print-Ready API lets you integrate AI-powered image processing into your applications. Remove backgrounds, edit images with AI instructions, and upscale to print-ready resolution -- all via simple REST endpoints. Processing is asynchronous: submit an image, poll for completion, then download the result.
Base URL
https://www.print-ready.ai/api
Authentication
Bearer token via Sanctum
Format
Multipart upload, JSON response
Available Endpoints
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| POST | /api/images/remove-background | Remove image background | 1-2 |
| POST | /api/images/edit | AI-powered image editing | 1 |
| POST | /api/images/upscale | Upscale image resolution | 1 |
| GET | /api/images | List processed images | 0 |
| GET | /api/images/{id} | Get image details & status | 0 |
| GET | /api/images/{id}/download | Get temporary download URL | 0 |
| DELETE | /api/images/{id} | Delete an image | 0 |
| POST | /api/batches | Create a batch job | varies |
| GET | /api/batches | List batches | 0 |
| GET | /api/batches/{id} | Get batch status | 0 |
| DELETE | /api/batches/{id} | Cancel & delete batch | 0 |
| GET | /api/user | Get account info | 0 |
| GET | /api/usage | Get usage stats & remaining credits | 0 |
| GET | /api/subscription | Get subscription details | 0 |
| GET | /api/user/tokens | List API tokens | 0 |
| DELETE | /api/user/tokens/{id} | Revoke a specific API token | 0 |
| POST | /api/auth/logout | Revoke current token | 0 |
Supported Image Formats
All image processing endpoints accept the following file types via multipart form upload:
JPEG
PNG
WebP
BMP
TIFF
GIF
Maximum file size: 10 MB per image.
Authentication
All API requests must include a Bearer token in the Authorization header. Generate your API key from the dashboard.
Authorization: Bearer YOUR_API_TOKEN
API access requires a paid plan. Free-tier accounts can only use the web interface. Upgrade to Starter or higher to unlock API access.
You can also include Accept: application/json to ensure error responses are returned as JSON rather than HTML.
Account & Usage
Retrieve your account info, credit usage, subscription details, and manage API tokens. These endpoints do not consume credits.
/api/user
Get the authenticated user's profile and current plan.
{
"success": true,
"message": "User retrieved successfully",
"data": {
"id": 3,
"name": "Jane Doe",
"email": "jane@example.com",
"email_verified_at": "2026-03-11T18:22:26.000000Z",
"profile_photo_url": "https://...",
"created_at": "2026-03-11T13:59:45.000000Z",
"updated_at": "2026-03-11T23:47:20.000000Z",
"pricing_plan": {
"id": 3,
"name": "Pro",
"slug": "professional"
}
}
}
/api/usage
Get your current credit usage, remaining balance, and plan features.
{
"success": true,
"message": "Usage statistics retrieved successfully",
"data": {
"plan": { "name": "Pro", "slug": "professional" },
"usage": {
"used": 14,
"limit": 300,
"remaining": 286,
"unlimited": false,
"exceeded": false,
"percentage": 4.67
},
"features": {
"api_access": true,
"batch_processing": true
}
}
}
/api/subscription
Get your Stripe subscription status, plan details, and feature limits.
{
"success": true,
"message": "Subscription details retrieved successfully",
"data": {
"subscription": {
"id": 1,
"type": "default",
"status": "active",
"quantity": 1,
"trial_ends_at": null,
"ends_at": null,
"is_active": true,
"is_on_trial": false,
"is_cancelled": false,
"is_on_grace_period": false
},
"plan": {
"name": "Pro",
"slug": "professional",
"price": 3900,
"features": { "api_access": true, "batch_processing": true },
"limits": { "credits_per_month": 300, "max_batch_size": 20 }
}
}
}
/api/user/tokens
List all API tokens for your account, including abilities and last usage.
{
"success": true,
"message": "API tokens retrieved successfully",
"data": {
"tokens": [
{
"id": 1,
"name": "api-key",
"abilities": ["read", "write", "delete", "user:read"],
"last_used_at": "2026-03-12T22:59:31.000000Z",
"created_at": "2026-03-11T18:22:26.000000Z"
}
],
"count": 1
}
}
/api/user/tokens/{id}
Revoke a specific API token by ID. The token will immediately stop working.
/api/auth/logout
Revoke the token used to make this request. Useful for implementing logout in client applications.
Remove Background
Remove the background from an image. Choose between basic (1 credit) and plus quality (2 credits) for higher fidelity edge detection.
/api/images/remove-background
image
*
The image file to process. JPEG, PNG, WebP, BMP, TIFF, or GIF. Max 10 MB.
quality
Processing quality level. Default: basic
basic -- Standard removal, 1 credit
plus -- Higher fidelity edges, 2 credits
curl -X POST https://www.print-ready.ai/api/images/remove-background \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "image=@product-photo.jpg" \ -F "quality=plus"
response = requests.post(
"https://www.print-ready.ai/api/images/remove-background",
headers={"Authorization": f"Bearer {token}"},
files={"image": open("product-photo.jpg", "rb")},
data={"quality": "plus"}
)
print(response.json())
const form = new FormData();
form.append("image", fileInput.files[0]);
form.append("quality", "plus");
const response = await fetch("https://www.print-ready.ai/api/images/remove-background", {
method: "POST",
headers: { "Authorization": `Bearer ${token}` },
body: form
});
console.log(await response.json());
$response = Http::withToken($token)
->attach('image', file_get_contents('product-photo.jpg'), 'product-photo.jpg')
->post('https://www.print-ready.ai/api/images/remove-background', [
'quality' => 'plus',
]);
dump($response->json());
{
"success": true,
"message": "Background removal started. Your image is being processed.",
"data": {
"id": 42,
"batch_id": null,
"service": "bg_removal",
"service_variant": "plus",
"status": "pending",
"credits_charged": 2,
"original_filename": "product-photo.jpg",
"original_size": 1048576,
"original_dimensions": { "width": 1920, "height": 1080 },
"processing_params": null,
"created_at": "2026-03-08T12:00:00.000000Z",
"updated_at": "2026-03-08T12:00:00.000000Z"
}
}
Edit Image
Apply AI-powered edits to an image using natural language instructions. Costs 1 credit per image.
/api/images/edit
image
*
The image file to edit. JPEG, PNG, WebP, BMP, TIFF, or GIF. Max 10 MB.
instructions
*
Natural language editing instructions. 3-1000 characters. Be specific for best results.
Example: "Make the sky more vibrant and add warm sunset tones"
curl -X POST https://www.print-ready.ai/api/images/edit \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "image=@landscape.png" \ -F "instructions=Make the sky more vibrant and add warm sunset tones"
response = requests.post(
"https://www.print-ready.ai/api/images/edit",
headers={"Authorization": f"Bearer {token}"},
files={"image": open("landscape.png", "rb")},
data={"instructions": "Make the sky more vibrant and add warm sunset tones"}
)
print(response.json())
const form = new FormData();
form.append("image", fileInput.files[0]);
form.append("instructions", "Make the sky more vibrant and add warm sunset tones");
const response = await fetch("https://www.print-ready.ai/api/images/edit", {
method: "POST",
headers: { "Authorization": `Bearer ${token}` },
body: form
});
console.log(await response.json());
$response = Http::withToken($token)
->attach('image', file_get_contents('landscape.png'), 'landscape.png')
->post('https://www.print-ready.ai/api/images/edit', [
'instructions' => 'Make the sky more vibrant and add warm sunset tones',
]);
dump($response->json());
{
"success": true,
"message": "Image editing started. Your image is being processed.",
"data": {
"id": 43,
"batch_id": null,
"service": "image_edit",
"service_variant": null,
"status": "pending",
"credits_charged": 1,
"original_filename": "landscape.png",
"original_size": 2097152,
"original_dimensions": { "width": 3840, "height": 2160 },
"processing_params": {
"instructions": "Make the sky more vibrant and add warm sunset tones"
},
"created_at": "2026-03-08T12:01:00.000000Z",
"updated_at": "2026-03-08T12:01:00.000000Z"
}
}
Upscale Image
Upscale an image to a higher resolution using AI. Costs 1 credit per image. Choose 2x, 3x, or 4x scale factor.
/api/images/upscale
image
*
The image file to upscale. JPEG, PNG, WebP, BMP, TIFF, or GIF. Max 10 MB.
scale_factor
Upscale multiplier. Default: 4
Accepted values: 2, 3, 4
curl -X POST https://www.print-ready.ai/api/images/upscale \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "image=@low-res.jpg" \ -F "scale_factor=4"
response = requests.post(
"https://www.print-ready.ai/api/images/upscale",
headers={"Authorization": f"Bearer {token}"},
files={"image": open("low-res.jpg", "rb")},
data={"scale_factor": 4}
)
print(response.json())
const form = new FormData();
form.append("image", fileInput.files[0]);
form.append("scale_factor", "4");
const response = await fetch("https://www.print-ready.ai/api/images/upscale", {
method: "POST",
headers: { "Authorization": `Bearer ${token}` },
body: form
});
console.log(await response.json());
$response = Http::withToken($token)
->attach('image', file_get_contents('low-res.jpg'), 'low-res.jpg')
->post('https://www.print-ready.ai/api/images/upscale', [
'scale_factor' => 4,
]);
dump($response->json());
{
"success": true,
"message": "Image upscaling started. Your image is being processed.",
"data": {
"id": 44,
"batch_id": null,
"service": "upscale",
"service_variant": null,
"status": "pending",
"credits_charged": 1,
"original_filename": "low-res.jpg",
"original_size": 524288,
"original_dimensions": { "width": 640, "height": 480 },
"processing_params": {
"scale_factor": 4
},
"created_at": "2026-03-08T12:02:00.000000Z",
"updated_at": "2026-03-08T12:02:00.000000Z"
}
}
Manage Images
List, retrieve, download, and delete your processed images. These endpoints do not consume credits.
/api/images
List all your processed images, ordered by most recent first. Supports pagination and filtering.
per_page
Results per page (1-100). Default: 20
status
Filter by status: pending, processing, completed, failed
service
Filter by service type: bg_removal, image_edit, upscale
curl https://www.print-ready.ai/api/images?status=completed&per_page=10 \ -H "Authorization: Bearer YOUR_API_TOKEN"
response = requests.get(
"https://www.print-ready.ai/api/images",
headers={"Authorization": f"Bearer {token}"},
params={"status": "completed", "per_page": 10}
)
print(response.json())
const response = await fetch(
"https://www.print-ready.ai/api/images?status=completed&per_page=10",
{ headers: { "Authorization": `Bearer ${token}` } }
);
console.log(await response.json());
$response = Http::withToken($token)
->get('https://www.print-ready.ai/api/images', [
'status' => 'completed',
'per_page' => 10,
]);
dump($response->json());
/api/images/{id}
Get details and processing status of a specific image. Use this to poll for completion after submitting a processing request.
{
"success": true,
"message": "Image retrieved successfully",
"data": {
"id": 42,
"batch_id": null,
"service": "bg_removal",
"service_variant": "plus",
"status": "completed",
"credits_charged": 2,
"original_filename": "product-photo.jpg",
"original_size": 1048576,
"original_dimensions": { "width": 1920, "height": 1080 },
"processed_dimensions": { "width": 1920, "height": 1080 },
"processed_size": 892416,
"processing_time": 4.2,
"processing_params": null,
"download_url": "https://...",
"created_at": "2026-03-08T12:00:00.000000Z",
"updated_at": "2026-03-08T12:00:05.000000Z"
}
}
/api/images/{id}/download
Get a temporary download URL for a completed image. The URL expires after 30 minutes. Returns 409 Conflict if the image is not yet completed.
{
"success": true,
"message": "Download URL generated successfully",
"data": {
"url": "https://storage.example.com/processed/abc123.png?signature=...",
"expires_at": "2026-03-08T12:30:00.000000Z",
"filename": "product-photo.jpg"
}
}
/api/images/{id}
Permanently delete a processed image and its entire session. If the image belongs to a batch, the entire batch and all sibling images are deleted. This action cannot be undone.
curl -X DELETE https://www.print-ready.ai/api/images/42 \ -H "Authorization: Bearer YOUR_API_TOKEN"
response = requests.delete(
f"https://www.print-ready.ai/api/images/{image_id}",
headers={"Authorization": f"Bearer {token}"}
)
print(response.status_code) # 200
const response = await fetch(`https://www.print-ready.ai/api/images/${imageId}`, {
method: "DELETE",
headers: { "Authorization": `Bearer ${token}` }
});
console.log(response.status); // 200
$response = Http::withToken($token)
->delete("https://www.print-ready.ai/api/images/{$imageId}");
echo $response->status(); // 200
Batch Processing
Process up to 20 images in a single request. Each image in the batch is processed independently and you can track overall progress. Credit cost is per-image based on the service chosen.
Pro plan and above only. Batch processing is not available on Free or Starter plans. Max batch size varies by plan: Pro (20), Enterprise 1K (50), Enterprise 3K (100).
/api/batches
Create a batch with multiple images for processing. All images in the batch use the same service and settings. Returns a batch ID for tracking progress.
images[]
*
Array of image files. 1-20 images per batch. Each file max 10 MB. JPEG, PNG, WebP, BMP, TIFF, or GIF.
service
*
Processing service to apply. One of: remove-background, edit, upscale
quality
Required when service is remove-background. Values: basic or plus
instructions
Required when service is edit. 3-1000 characters. Applied to all images in the batch.
scale_factor
For upscale service. Values: 2, 3, 4. Default: 4
name
A name for the batch. Max 255 characters. Auto-generated if omitted.
curl -X POST https://www.print-ready.ai/api/batches \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "service=remove-background" \ -F "quality=basic" \ -F "name=Product photos batch" \ -F "images[]=@photo1.jpg" \ -F "images[]=@photo2.jpg" \ -F "images[]=@photo3.jpg"
files = [
("images[]", open("photo1.jpg", "rb")),
("images[]", open("photo2.jpg", "rb")),
("images[]", open("photo3.jpg", "rb")),
]
response = requests.post(
"https://www.print-ready.ai/api/batches",
headers={"Authorization": f"Bearer {token}"},
files=files,
data={
"service": "remove-background",
"quality": "basic",
"name": "Product photos batch"
}
)
batch_id = response.json()["data"]["id"]
const form = new FormData();
form.append("service", "remove-background");
form.append("quality", "basic");
form.append("name", "Product photos batch");
// Add multiple files
for (const file of fileInput.files) {
form.append("images[]", file);
}
const response = await fetch("https://www.print-ready.ai/api/batches", {
method: "POST",
headers: { "Authorization": `Bearer ${token}` },
body: form
});
const batchId = (await response.json()).data.id;
$response = Http::withToken($token)
->attach('images[]', file_get_contents('photo1.jpg'), 'photo1.jpg')
->attach('images[]', file_get_contents('photo2.jpg'), 'photo2.jpg')
->attach('images[]', file_get_contents('photo3.jpg'), 'photo3.jpg')
->post('https://www.print-ready.ai/api/batches', [
'service' => 'remove-background',
'quality' => 'basic',
'name' => 'Product photos batch',
]);
$batchId = $response->json('data.id');
{
"success": true,
"message": "Batch created successfully. 3 images are being processed.",
"data": {
"id": 7,
"name": "Product photos batch",
"service": "bg_removal",
"service_variant": "basic",
"status": "pending",
"total_images": 3,
"completed_images": 0,
"failed_images": 0,
"credits_charged": 3,
"images": [ ... ],
"created_at": "2026-03-08T12:05:00.000000Z",
"completed_at": null
}
}
/api/batches
List all your batches, ordered by most recent first. Supports pagination via per_page query parameter (1-100, default 20).
/api/batches/{id}
Get batch details including progress counters and the status of each individual image in the batch.
{
"success": true,
"message": "Batch retrieved successfully",
"data": {
"id": 7,
"name": "Product photos batch",
"service": "bg_removal",
"service_variant": "basic",
"status": "processing",
"total_images": 3,
"completed_images": 2,
"failed_images": 0,
"credits_charged": 3,
"images": [
{
"id": 45,
"service": "bg_removal",
"status": "completed",
"original_filename": "photo1.jpg",
"download_url": "https://...",
...
},
...
],
"created_at": "2026-03-08T12:05:00.000000Z",
"completed_at": null
}
}
/api/batches/{id}
Cancel and delete a batch. Any pending or in-progress images will be cancelled. All associated files are permanently removed.
Credits
Each image processing operation consumes credits from your monthly allowance. Credits reset at the start of each billing cycle.
| Operation | Variant | Credits |
|---|---|---|
| Background Removal | basic | 1 credit |
| Background Removal | plus | 2 credits |
| AI Image Editing | -- | 1 credit |
| Image Upscaling | -- | 1 credit |
Credit Response Headers
Every API response includes headers showing your current credit usage:
X-Credits-Limit: 300 X-Credits-Remaining: 247 X-Credits-Used: 53
| Header | Description |
|---|---|
| X-Credits-Limit | Total monthly credit allowance for your plan |
| X-Credits-Remaining | Credits remaining in the current billing period |
| X-Credits-Used | Credits consumed in the current billing period |
When you run out of credits, processing endpoints return 402 Payment Required. Upgrade your plan or wait for credits to reset at the next billing cycle.
Rate Limits
API requests are rate-limited per minute based on your subscription plan. Rate limits apply to all endpoints collectively.
| Plan | API Access | Rate Limit | Monthly Credits | Batch Processing |
|---|---|---|---|---|
| Free | No | -- | 3 (web only) | -- |
| Starter | Yes | 30 req/min | 50 credits | -- |
| Pro | Yes | 120 req/min | 300 credits | Up to 20 images |
| Enterprise 1K | Yes | 300 req/min | 1,000 credits | Up to 50 images |
| Enterprise 3K | Yes | 300 req/min | 3,000 credits | Up to 100 images |
Standard rate limit headers are included in all responses:
X-RateLimit-Limit: 120 X-RateLimit-Remaining: 107 Retry-After: 60 (only on 429 responses)
Errors
The API uses standard HTTP status codes. Errors return a consistent JSON structure:
{
"success": false,
"message": "Human-readable error description",
"errors": {
"field": ["Validation error detail"]
}
}
| Code | Meaning |
|---|---|
| 401 | Missing or invalid API token |
| 402 | Insufficient credits for the requested operation |
| 403 | Feature not available on your plan, or you do not own this resource |
| 404 | Image or batch not found |
| 409 | Image not ready for download (still processing) |
| 422 | Validation failed (missing required fields, invalid file type, etc.) |
| 429 | Rate limit exceeded -- check Retry-After header |
| 500 | Server error -- please retry or contact support |