API Reference
Integrate UltraPixx image intelligence directly into your applications. Analyze, optimize, convert, and run the full processing pipeline via a simple REST API.
Authentication
All authenticated endpoints require an API key. You can obtain your API key from your account settings page.
Pass the key using either of these headers:
Authorization: Bearer <your_api_key>
-- or --
X-API-Key: <your_api_key>
Keep your API key secret. Never expose it in client-side JavaScript or public repositories.
Rate Limits
Requests are limited to 60 requests per minute per API key. When the limit is exceeded, the API returns:
{
"message": "Too Many Attempts.",
"retry_after": 30
}
Base URL
https://ultrapixx.com/api/v1
All endpoints below are relative to this base URL.
/languages
No auth required
Returns the list of languages supported for AI-generated SEO metadata (filenames & alt-text).
Success Response β 200 OK
{
"data": [
{ "code": "de", "name": "German", "native_name": "Deutsch" },
{ "code": "en", "name": "English", "native_name": "English" },
{ "code": "fr", "name": "French", "native_name": "FranΓ§ais" }
]
}
Code Samples
curl https://ultrapixx.com/api/v1/languages
$response = Http::get("https://ultrapixx.com/api/v1/languages");
$languages = $response->json("data");
/images/analyze
API Key required
Upload an image. The API dispatches an AI job to generate an SEO-optimized filename and descriptive alt-text. Returns immediately with a job_id β poll GET /jobs/{id} for results.
Request β multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| image | file | Yes | Image file (max 10 MB). Accepted: JPEG, PNG, GIF, WebP. |
| languages | string[] | No | ISO 639-1 codes, e.g. ["en","de"]. Defaults to ["en"]. |
| project_id | string | No | Existing project ULID. Creates an "API Uploads" project if omitted. |
| project_name | string | No | Custom project name (used when project_id is not provided). |
Success Response β 202 Accepted
{
"data": {
"job_id": "01hwz3p4kj0000000000000000",
"status": "pending",
"message": "Analysis dispatched. Poll GET /api/v1/jobs/01hwz3p4kj0000000000000000 for results."
}
}
Code Samples
curl -X POST https://ultrapixx.com/api/v1/images/analyze \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.jpg" \ -F "languages[]=en" \ -F "languages[]=de"
$response = Http::withToken($apiKey)
->attach("image", file_get_contents("photo.jpg"), "photo.jpg")
->post("https://ultrapixx.com/api/v1/images/analyze", [
"languages" => ["en", "de"],
]);
$jobId = $response->json("data.job_id");
/images/optimize
API Key required
Upload an image and dispatch a TinyPNG compression job. Once complete, download the result via GET /images/{id}/optimized.
Request β multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| image | file | Yes | Image file (max 10 MB). |
| project_id | string | No | Existing project ULID. |
| project_name | string | No | Custom project name. |
Success Response β 202 Accepted
{
"data": {
"job_id": "01hwz3p4kj0000000000000000",
"status": "pending",
"message": "Optimization dispatched. Poll GET /api/v1/jobs/01hwz3p4kj0000000000000000 for results."
}
}
Code Samples
curl -X POST https://ultrapixx.com/api/v1/images/optimize \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.jpg"
$response = Http::withToken($apiKey)
->attach("image", file_get_contents("photo.jpg"), "photo.jpg")
->post("https://ultrapixx.com/api/v1/images/optimize");
$jobId = $response->json("data.job_id");
/images/convert
API Key required
Upload an image and dispatch a format conversion job (PNG/JPEG β WebP or AVIF).
Request β multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| image | file | Yes | Image file (max 10 MB). |
| format | string | No | Target format: webp (default) or avif. |
| project_id | string | No | Existing project ULID. |
| project_name | string | No | Custom project name. |
Success Response β 202 Accepted
{
"data": {
"job_id": "01hwz3p4kj0000000000000000",
"status": "pending",
"message": "Conversion dispatched. Poll GET /api/v1/jobs/01hwz3p4kj0000000000000000 for results."
}
}
Code Samples
curl -X POST https://ultrapixx.com/api/v1/images/convert \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.jpg" \ -F "format=avif"
$response = Http::withToken($apiKey)
->attach("image", file_get_contents("photo.jpg"), "photo.jpg")
->post("https://ultrapixx.com/api/v1/images/convert", [
"format" => "avif",
]);
$jobId = $response->json("data.job_id");
/images/process
API Key required
Full pipeline: analyze + optimize + convert in a single call. The API dispatches all three jobs concurrently. Poll GET /jobs/{id} until status is completed.
Request β multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| image | file | Yes | Image file (max 10 MB). |
| languages | string[] | No | ISO 639-1 codes. Defaults to ["en"]. |
| format | string | No | Target format: webp (default) or avif. |
| project_id | string | No | Existing project ULID. |
| project_name | string | No | Custom project name. |
Success Response β 202 Accepted
{
"data": {
"job_id": "01hwz3p4kj0000000000000000",
"status": "pending",
"message": "Processing dispatched. Poll GET /api/v1/jobs/01hwz3p4kj0000000000000000 for results."
}
}
Code Samples
curl -X POST https://ultrapixx.com/api/v1/images/process \ -H "Authorization: Bearer $API_KEY" \ -F "image=@photo.jpg" \ -F "languages[]=en" \ -F "languages[]=de" \ -F "format=webp"
$response = Http::withToken($apiKey)
->attach("image", file_get_contents("photo.jpg"), "photo.jpg")
->post("https://ultrapixx.com/api/v1/images/process", [
"languages" => ["en", "de"],
"format" => "webp",
]);
$jobId = $response->json("data.job_id");
/credits/afford
API Key required
Lightweight pre-flight check: will the authenticated user have enough credits to run the full pipeline on N images? No image upload required. Useful for surfacing "not enough credits" messaging before the user commits to the upload.
Query Parameters
| Name | Type | Description |
|---|---|---|
| images | integer (1β100) | Required. Number of images you intend to process. |
| languages | integer (1β10) | Optional. How many alt-text languages per image. Defaults to 1. |
| format | string | Optional. Conversion target: webp (default) or avif. |
Success Response β 200 OK
{
"data": {
"can_afford": true,
"required": 50,
"balance": 1200,
"shortfall": 0
}
}
Code Samples
curl "https://ultrapixx.com/api/v1/credits/afford?images=5&languages=2&format=webp" \ -H "Authorization: Bearer $API_KEY"
$response = Http::withToken($apiKey)
->get("https://ultrapixx.com/api/v1/credits/afford", [
"images" => 5,
"languages" => 2,
"format" => "webp",
]);
if (! $response->json("data.can_afford")) {
throw new RuntimeException("Short " . $response->json("data.shortfall") . " credits");
}
/credits/balance
API Key required
Returns the current credit balance for the authenticated account. Primarily used by the bundled WordPress plugin to show live credits on its settings page, but available to any integration that wants to display balance.
Success Response β 200 OK
{
"data": {
"balance": 1200
}
}
Code Samples
curl https://ultrapixx.com/api/v1/credits/balance \ -H "Authorization: Bearer $API_KEY"
$balance = Http::withToken($apiKey)
->get("https://ultrapixx.com/api/v1/credits/balance")
->json("data.balance");
/jobs/{id}
API Key required
Poll the status of an async image processing job. Use the job_id returned by any of the dispatch endpoints. When status is "completed", all results are included in the response.
Job Status Values
pendingQueued
analyzingAI running
optimizingTinyPNG running
convertingFormat conversion
completedAll jobs done
failedError
Note: /images/process fans out three concurrent jobs (analyze / optimize / convert) that race to set status. Poll until you see completed or failed; intermediate values (analyzing/optimizing/converting) indicate work is still in flight.
Success Response β 200 OK
{
"data": {
"job_id": "01hwz3p4kj0000000000000000",
"status": "completed",
"image": {
"id": "01hwz3p4kj0000000000000000",
"status": "completed",
"original_filename": "photo.jpg",
"original_size": 2048000,
"optimized_size": 142336,
"converted_format": "webp",
"converted_size": 98304,
"compression_percentage": 93,
"translations": [
{
"language_code": "en",
"seo_filename": "sustainable-leather-hiking-shoes",
"seo_alt_text": "Sustainable hand-stitched leather shoes for urban hiking"
},
{
"language_code": "de",
"seo_filename": "nachhaltige-leder-wanderschuhe",
"seo_alt_text": "Nachhaltige handgenΓ€hte Lederschuhe fΓΌr das Wandern in der Stadt"
}
]
}
}
}
Error Responses
{ "message": "No query results for model [App\\Models\\Image]." }
Code Samples
curl https://ultrapixx.com/api/v1/jobs/01hwz3p4kj0000000000000000 \ -H "Authorization: Bearer $API_KEY"
// Poll until completed or failed
do {
sleep(2);
$response = Http::withToken($apiKey)
->get("https://ultrapixx.com/api/v1/jobs/" . $jobId);
$status = $response->json("data.status");
} while (! in_array($status, ["completed", "failed"], true));
$image = $response->json("data.image");
/images/{id}/optimized
API Key required
Download the TinyPNG-compressed binary of a completed optimization job. Returns the raw image file with the original MIME type. Ensure the job status is done before calling this endpoint.
Success Response β 200 OK
Content-Type: image/jpeg Content-Disposition: attachment; filename="photo-optimized.jpg"
Response body is the binary image data.
Error Responses
{ "error": "Optimized file not available. Ensure the optimization job has completed." }
Code Samples
curl -o optimized.jpg \ -H "Authorization: Bearer $API_KEY" \ https://ultrapixx.com/api/v1/images/01hwz3p4kj0000000000000000/optimized
$response = Http::withToken($apiKey)
->get("https://ultrapixx.com/api/v1/images/" . $imageId . "/optimized");
file_put_contents("optimized.jpg", $response->body());