Photo Restoration API
Restore old, damaged, and faded photos programmatically with a single API call. AI-powered scratch removal, color restoration, face enhancement, and automatic colorization.
Why Use This API
Scratch Removal
AI detects and removes scratches, tears, creases, and other physical damage from scanned photos automatically.
Color Restoration
Restore faded colors, fix discoloration, and bring old photographs back to their original vibrancy.
Face Enhancement
Sharpen and restore facial features in old portraits. Recover fine details while preserving the original likeness.
Colorization
Automatically add realistic colors to black-and-white photos using AI that understands historical context and image content.
Quick Start
Start restoring photos in under a minute. Here's how:
- Get your API key — Sign up free to receive your key
- Send a request — POST an image to the endpoint with your desired restoration type
- Get the result — Receive a restored image in the response
curl -X POST https://precisioncounter.com/api/v1/restore-photo \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "image=@old_photo.jpg" \
-F "restore_type=auto" \
-o restored.png
import requests
response = requests.post(
"https://precisioncounter.com/api/v1/restore-photo",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"image": open("old_photo.jpg", "rb")},
data={"restore_type": "auto"}
)
with open("restored.png", "wb") as f:
f.write(response.content)
const fs = require("fs");
const FormData = require("form-data");
const form = new FormData();
form.append("image", fs.createReadStream("old_photo.jpg"));
form.append("restore_type", "auto");
const response = await fetch(
"https://precisioncounter.com/api/v1/restore-photo",
{
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
...form.getHeaders()
},
body: form
}
);
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("restored.png", buffer);
API Reference
Base URL
https://precisioncounter.com/api/v1
Authentication
All requests require an API key passed in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Restore Photo
Restores an old or damaged photo using AI, removing scratches, restoring colors, enhancing faces, and optionally colorizing.
Request Parameters
| Parameter | Type | Description |
|---|---|---|
| image required | file | The image file to restore. Accepted formats: PNG, JPG, JPEG, WebP. Max size: 10 MB. |
| restore_type optional | string | Restoration mode. Default: auto. Options: auto, scratch, color, face. |
| colorize optional | boolean | Colorize black-and-white photos. Default: false. Set to true to add realistic colors. |
Response
200 OK — Returns the restored image as binary data with Content-Type: image/png.
Response Headers
| Header | Value |
|---|---|
| Content-Type | image/png or image/webp |
| X-Credits-Remaining | Number of API credits remaining |
| X-Processing-Time | Processing time in milliseconds |
Code Examples
Full Examples with Error Handling
import requests
import sys
API_KEY = "YOUR_API_KEY"
API_URL = "https://precisioncounter.com/api/v1/restore-photo"
def restore_photo(input_path, output_path="restored.png", restore_type="auto", colorize=False):
"""Restore an old or damaged photo."""
with open(input_path, "rb") as img:
response = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
files={"image": img},
data={"restore_type": restore_type, "colorize": str(colorize).lower()}
)
if response.status_code == 200:
with open(output_path, "wb") as f:
f.write(response.content)
print(f"Saved to {output_path}")
print(f"Credits remaining: {response.headers.get('X-Credits-Remaining')}")
else:
print(f"Error {response.status_code}: {response.json()['error']}")
restore_photo("old_photo.jpg", colorize=True)
const fs = require("fs");
const FormData = require("form-data");
const fetch = require("node-fetch");
const API_KEY = "YOUR_API_KEY";
const API_URL = "https://precisioncounter.com/api/v1/restore-photo";
async function restorePhoto(inputPath, outputPath = "restored.png", restoreType = "auto", colorize = false) {
const form = new FormData();
form.append("image", fs.createReadStream(inputPath));
form.append("restore_type", restoreType);
form.append("colorize", colorize.toString());
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
...form.getHeaders()
},
body: form
});
if (response.ok) {
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync(outputPath, buffer);
console.log(`Saved to ${outputPath}`);
console.log(`Credits: ${response.headers.get("x-credits-remaining")}`);
} else {
const error = await response.json();
console.error(`Error ${response.status}: ${error.error}`);
}
}
restorePhoto("old_photo.jpg", "restored.png", "auto", true);
<?php
$api_key = "YOUR_API_KEY";
$url = "https://precisioncounter.com/api/v1/restore-photo";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $api_key"
],
CURLOPT_POSTFIELDS => [
"image" => new CURLFile("old_photo.jpg"),
"restore_type" => "auto",
"colorize" => "true"
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
file_put_contents("restored.png", $response);
echo "Photo restored successfully\n";
} else {
echo "Error $httpCode: $response\n";
}
?>
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func restorePhoto(inputPath, outputPath, restoreType string, colorize bool) error {
file, _ := os.Open(inputPath)
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("image", inputPath)
io.Copy(part, file)
writer.WriteField("restore_type", restoreType)
if colorize {
writer.WriteField("colorize", "true")
}
writer.Close()
req, _ := http.NewRequest("POST",
"https://precisioncounter.com/api/v1/restore-photo", body)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
out, _ := os.Create(outputPath)
defer out.Close()
io.Copy(out, resp.Body)
fmt.Printf("Saved to %s\n", outputPath)
}
return nil
}
func main() {
restorePhoto("old_photo.jpg", "restored.png", "auto", true)
}
require "net/http"
require "uri"
api_key = "YOUR_API_KEY"
uri = URI("https://precisioncounter.com/api/v1/restore-photo")
form_data = [
["image", File.open("old_photo.jpg", "rb")],
["restore_type", "auto"],
["colorize", "true"]
]
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{api_key}"
req.set_form(form_data, "multipart/form-data")
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
if res.code == "200"
File.binwrite("restored.png", res.body)
puts "Photo restored successfully"
else
puts "Error #{res.code}: #{res.body}"
end
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");
using var form = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(File.ReadAllBytes("old_photo.jpg"));
imageContent.Headers.ContentType = new("image/jpeg");
form.Add(imageContent, "image", "old_photo.jpg");
form.Add(new StringContent("auto"), "restore_type");
form.Add(new StringContent("true"), "colorize");
var response = await client.PostAsync(
"https://precisioncounter.com/api/v1/restore-photo", form);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("restored.png", result);
Console.WriteLine("Photo restored successfully");
}
Error Handling
The API returns standard HTTP status codes with JSON error bodies:
| Status | Meaning | Description |
|---|---|---|
| 200 | Success | Photo restored successfully. Response body is the output image. |
| 400 | Bad Request | Missing image file, unsupported format, invalid restore type, or file too large. |
| 401 | Unauthorized | Missing or invalid API key. |
| 429 | Rate Limited | Too many requests. Wait and retry with exponential backoff. |
| 500 | Server Error | Internal processing error. Retry the request. |
Error Response Format
{
"error": "Invalid restore_type. Accepted: auto, scratch, color, face",
"code": "INVALID_PARAMETER",
"status": 400
}
Rate Limits
| Plan | Requests / Minute | Max File Size | Max Resolution |
|---|---|---|---|
| Free | 10 | 10 MB | 4096 x 4096 px |
| Pro | 60 | 25 MB | 8192 x 8192 px |
Rate limit headers are included in every response:
X-RateLimit-Limit: 10 X-RateLimit-Remaining: 7 X-RateLimit-Reset: 1708646400
Use Cases
- Family photo restoration
- Historical archive digitization
- Museum collection preservation
- Genealogy and ancestry platforms
- Vintage photo digitization
- Damaged photo recovery services
Pricing
Get free API credits when you sign up. No credit card required.
Frequently Asked Questions
colorize parameter to true to automatically add realistic colors to black-and-white or sepia-toned photographs. The AI model analyzes the image content and applies historically accurate colorization.auto (automatically detects and fixes all issues), scratch (focuses on scratch and tear removal), color (restores faded colors and fixes discoloration), and face (enhances and restores facial features).