Public API
Diese Seite ergänzt die OpenAPI UI um sofort nutzbare Requests, Beispiel-Responses und Hinweise zu stabilen Bild-URLs.
Schnellstart
Für die meisten Integrationen reichen diese vier Endpunkte.
Liefert Profil, Limits und Nutzungswerte des Users.
Erstellt Upload-URL, Token und maximale Dateigröße.
Zeigt, ob die Verarbeitung abgeschlossen oder fehlgeschlagen ist.
Liefert die finalen Bild- und Varianten-URLs.
1) Authentifizierung
Erstelle zuerst in den Benutzereinstellungen einen API-Schlüssel und sende ihn pro Request im Header X-API-Key.
export BASE_URL="https://pixelfox.cc"
export API_KEY="DEIN_API_KEY"
curl -sS "$BASE_URL/api/v1/user/profile" \
-H "X-API-Key: $API_KEY" | jqAlternative Header-Variante: Authorization: Bearer DEIN_API_KEY.
2) Upload-Session erzeugen
Vor jedem Upload wird ein zeitlich begrenztes Token ausgestellt. Zusätzlich kannst du pro Upload festlegen, welche Derivate erzeugt werden sollen. Das Original bleibt immer erhalten.
export FILE="./beispiel.jpg"
export FILE_SIZE=$(wc -c < "$FILE")
SESSION_JSON=$(curl -sS -X POST "$BASE_URL/api/v1/upload/sessions" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d "{
\"file_size\": $FILE_SIZE,
\"processing\": {
\"profile\": \"custom\",
\"derivatives\": [
{ \"family\": \"webp\", \"size\": \"small\" },
{ \"family\": \"avif\", \"size\": \"small\" }
]
}
}")
echo "$SESSION_JSON" | jq
UPLOAD_URL=$(echo "$SESSION_JSON" | jq -r '.upload_url')
UPLOAD_TOKEN=$(echo "$SESSION_JSON" | jq -r '.token')Lasse processing weg, wenn du die aktuellen User-Defaults verwenden willst. Mit profile=original_only wird nur das Original gespeichert.
Processing-Profile
| Profil | Verhalten |
|---|---|
| default | Verwendet die aktuellen User-Defaults aus den Einstellungen und friert sie für genau diese Upload-Session ein. |
| original_only | Speichert nur das hochgeladene Original. Es werden keine zusätzlichen WebP-, AVIF- oder Original-Thumbnails erzeugt. |
| custom | Erzeugt exakt die in derivatives angeforderten Derivate, sofern Plan und Admin-Settings sie erlauben. |
// Gleichbedeutend mit den aktuellen User-Defaults
{ "file_size": 1837421 }
// Nur das Original behalten
{
"file_size": 1837421,
"processing": {
"profile": "original_only"
}
}
// Exakt kleine WebP- und AVIF-Varianten anfordern
{
"file_size": 1837421,
"processing": {
"profile": "custom",
"derivatives": [
{ "family": "webp", "size": "small" },
{ "family": "avif", "size": "small" }
]
}
}In Antworten kann bei älteren Bildern zusätzlich profile=legacy auftauchen. Das ist nur ein Rückwärtskompatibilitätswert für Uploads vor der neuen per-Request-Policy.
3) Bild hochladen und Resource abrufen
Lade die Datei per Multipart-Form an die upload_url aus Schritt 2 hoch. Anschließend prüfst du den Status und holst dir die finale Resource.
UPLOAD_RESULT=$(curl -sS -X POST "$UPLOAD_URL" \
-H "Authorization: Bearer $UPLOAD_TOKEN" \
-F "file=@$FILE")
echo "$UPLOAD_RESULT" | jq
IMAGE_UUID=$(echo "$UPLOAD_RESULT" | jq -r '.image_uuid')
curl -sS "$BASE_URL/api/v1/images/$IMAGE_UUID/status" \
-H "X-API-Key: $API_KEY" | jq
curl -sS "$BASE_URL/api/v1/images/$IMAGE_UUID" \
-H "X-API-Key: $API_KEY" | jqWiederhole den Status-Request, bis complete=true und failed=false zurückkommt.
Direkt nach dem Upload sind oft erst Original-Datei und ein Teil der Varianten verfügbar. Zusätzliche Derivate werden asynchron erzeugt.
Beispiel: GET /api/v1/user/profile
{
"id": 42,
"username": "pixelpete",
"email": "[email protected]",
"status": "active",
"plan": "premium",
"created_at": "2026-03-16T08:30:00Z",
"last_login_at": "2026-03-16T09:12:44Z",
"api_key_last_used_at": "2026-03-16T09:15:02Z",
"stats": {
"images": {
"count": 128,
"storage_used_bytes": 734003200,
"storage_remaining_bytes": 2415919104
},
"albums": {
"count": 7
}
},
"limits": {
"max_upload_bytes": 52428800,
"storage_quota_bytes": 3149926400,
"can_multi_upload": true,
"image_upload_enabled": true,
"direct_upload_enabled": true,
"allowed_thumbnail_formats": ["original", "webp", "avif"]
},
"preferences": {
"thumbnail_original": true,
"thumbnail_webp": true,
"thumbnail_avif": true
}
}Account-Daten, Limits und aktuelle Nutzung des authentifizierten Users.
Beispiel: POST /api/v1/upload/sessions
{
"upload_url": "https://pixelfox.cc/api/v1/upload",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"pool_id": 2,
"expires_at": 1773655200,
"max_bytes": 52428800,
"processing": {
"profile": "custom",
"keep_original": true,
"derivatives": [
{ "family": "webp", "size": "small" },
{ "family": "avif", "size": "small" }
]
}
}Das Token ist nur kurz gültig, auf die Dateigröße begrenzt und trägt die konkrete Processing-Policy dieser Session.
Beispiel: Upload-Antwort
{
"image_uuid": "fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8",
"view_url": "/i/a1b2c3d4e5f6g7h8",
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"stable_url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"storage_url": "https://cdn.pixelfox.cc/uploads/original/2026/03/16/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8.jpg",
"available_variants": ["original"],
"processing": {
"profile": "custom",
"keep_original": true,
"derivatives": [
{ "family": "webp", "size": "small" },
{ "family": "avif", "size": "small" }
]
},
"variants": {
"original": {
"original": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg"
}
}
},
"stable_variants": {
"original": {
"original": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"ready": true
}
},
"webp": {
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/webp/small.webp",
"ready": false
}
},
"avif": {
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/avif/small.avif",
"ready": false
}
}
},
"planned_variants": ["original", "webp", "avif"],
"duplicate": false
}Direkt nach dem Upload ist die Resource bereits adressierbar. Fertige Varianten erscheinen schrittweise in variants.
Beispiel: Status und finale Image-Resource
// GET /api/v1/images/{uuid}/status
{
"complete": true,
"failed": false,
"view_url": "/i/a1b2c3d4e5f6g7h8"
}
// GET /api/v1/images/{uuid}
{
"image_uuid": "fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8",
"view_url": "/i/a1b2c3d4e5f6g7h8",
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"stable_url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"storage_url": "https://cdn.pixelfox.cc/uploads/original/2026/03/16/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8.jpg",
"available_variants": ["original", "webp", "avif"],
"processing": {
"profile": "custom",
"keep_original": true,
"derivatives": [
{ "family": "webp", "size": "small" },
{ "family": "avif", "size": "small" }
]
},
"variants": {
"original": {
"original": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg"
}
},
"webp": {
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/webp/small.webp"
}
},
"avif": {
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/avif/small.avif"
}
}
},
"stable_variants": {
"original": {
"original": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/original.jpg",
"ready": true
},
"medium": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/medium.jpg",
"ready": true
},
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/original/small.jpg",
"ready": true
}
},
"webp": {
"original": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/webp/original.webp",
"ready": true
},
"medium": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/webp/medium.webp",
"ready": true
},
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/webp/small.webp",
"ready": true
}
},
"avif": {
"medium": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/avif/medium.avif",
"ready": false
},
"small": {
"url": "https://pixelfox.cc/f/fd6b0a44-c4bb-4c95-8f48-31d5ec9cc4d8/avif/small.avif",
"ready": false
}
}
},
"planned_variants": ["original", "webp", "avif"]
}/status ist bewusst klein gehalten. Für alle fertigen URLs und Varianten verwendest du danach GET /api/v1/images/{uuid}.
PHP Beispiele
Für einfache Server-Integrationen reicht das PHP cURL-Extension vollkommen aus. Das erste Beispiel zeigt einen authentifizierten JSON-Request, das zweite den vollständigen Upload-Flow.
GET /api/v1/user/profile
<?php
$baseUrl = 'https://pixelfox.cc';
$apiKey = 'DEIN_API_KEY';
$ch = curl_init($baseUrl . '/api/v1/user/profile');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'X-API-Key: ' . $apiKey,
],
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException('API request failed: ' . $raw);
}
$profile = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
echo $profile['username'] . PHP_EOL;
echo $profile['limits']['max_upload_bytes'] . PHP_EOL;Upload Flow mit Status-Polling
<?php
$baseUrl = 'https://pixelfox.cc';
$apiKey = 'DEIN_API_KEY';
$file = __DIR__ . '/beispiel.jpg';
function apiJson(string $method, string $url, string $apiKey, ?array $payload = null): array
{
$headers = [
'Accept: application/json',
'X-API-Key: ' . $apiKey,
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
]);
if ($payload !== null) {
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_THROW_ON_ERROR));
}
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
return [
'status' => $status,
'body' => json_decode($raw, true, 512, JSON_THROW_ON_ERROR),
];
}
$session = apiJson('POST', $baseUrl . '/api/v1/upload/sessions', $apiKey, [
'file_size' => filesize($file),
]);
$upload = curl_init($session['body']['upload_url']);
curl_setopt_array($upload, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $session['body']['token'],
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile($file),
],
]);
$uploadRaw = curl_exec($upload);
curl_close($upload);
$uploadResult = json_decode($uploadRaw, true, 512, JSON_THROW_ON_ERROR);
$imageUuid = $uploadResult['image_uuid'];
do {
sleep(1);
$status = apiJson('GET', $baseUrl . '/api/v1/images/' . $imageUuid . '/status', $apiKey);
} while (!$status['body']['complete'] && !$status['body']['failed']);
if ($status['body']['failed']) {
throw new RuntimeException('Image processing failed');
}
$image = apiJson('GET', $baseUrl . '/api/v1/images/' . $imageUuid, $apiKey);
echo $image['body']['url'] . PHP_EOL;Konsistente Bild-URLs verstehen
PixelFox liefert bewusst zwei URL-Typen aus. Damit kannst du wahlweise stabile öffentliche Links verwenden oder direkt auf die aktuelle Storage-Adresse zugreifen.
| Feld | Bedeutung |
|---|---|
| view_url | Relative URL zur HTML-Ansicht der Bildseite, zum Beispiel /i/abc123.... |
| url | Primäre öffentliche Bild-URL. In der Regel identisch zu stable_url und für Embeds, Hotlinks und API-Consumer die beste Standardwahl. |
| stable_url | Stabile /f/{uuid}/...-Adresse. Diese URL bleibt konsistent, auch wenn sich die interne Storage-Struktur oder das Zielsystem später ändert. |
| variants | Nur die aktuell fertigen Varianten mit stabilen öffentlichen URLs. |
| processing | Die effektive Processing-Policy dieses Uploads. Dort siehst du, ob der Upload mit default, original_only oder custom erstellt wurde und welche Derivate konkret dazugehören. |
| stable_variants | Vorhersagbare stabile Variant-URLs inklusive ready-Flag. Damit kannst du feste URLs vorhalten und trotzdem erkennen, ob die Datei schon existiert. |
| storage_url | Direkte aktuelle Storage-URL der Originaldatei. Praktisch für Debugging oder interne Tools, aber weniger zukunftssicher als stable_url. |
| storage_variants | Direkte Storage-URLs aller bereits erzeugten Varianten. Gleiches Prinzip wie storage_url. |
| planned_variants | Welche Variant-Familien für dieses Bild laut gespeicherter Processing-Policy grundsätzlich vorgesehen sind. |
Empfehlung für Integrationen
Verwende standardmäßig url oder die Einträge aus variants. Wenn du mit noch nicht fertigen Derivaten planst, nimm stable_variants und prüfe das jeweilige ready-Flag.
Wichtiger Unterschied
/f/... ist eine stabile öffentliche Adresse, die auf die aktuelle Datei weiterleitet. /uploads/... oder CDN-Pfade können sich dagegen mit Storage-Pools, Migrationen oder künftigen Infrastruktur-Änderungen ändern.
