PhotoCen API
Generate, personalize, search, and serve AI images through one simple API. Base URL https://api.photocen.com. New accounts start with 10 free credits.
Authentication
Send a bearer token. Normal-user tokens look like pc_live_…; partner tokens look like pc_partner_….
Authorization: Bearer pc_live_xxxxxxxx
Idempotency
All chargeable POSTs accept an Idempotency-Key header (a UUID). Replaying the same key with the same body returns the original response and never double-charges.
Pricing
- Image generation — 2 credits
- Visual (vector) search — 1 credit
- Private / not-searchable image — +1 credit
- On-demand image delivery (placeholder) — 1 credit per request
On-demand image delivery
Serve any image from your searchable catalog at any size through a single GET — the role a stock-photo source plays for a placeholder service, but backed by your generated library. The image is center-cropped to exactly fill the requested box. Each delivery is metered (1 credit) and requires a bearer token.
| Endpoint | Returns |
|---|---|
| GET /{width}/{height} | A random catalog image. A single edge (/{width}) is square. |
| GET /id/{id}/{width}/{height} | A specific catalog image (id from /v2/list or /info). |
| GET /seed/{seed}/{width}/{height} | Deterministic — the same seed always resolves to the same image. |
| GET /id/{id}/info | JSON metadata: id, author, width, height, url, download_url. Free. |
| GET /v2/list?page=&limit= | Paginated catalog as a JSON array (Link + X-Total-Count headers). Free. |
Modifiers — append ?grayscale for black & white, ?blur=1..10 to blur, and a format suffix .jpg (default) / .webp / .png on the last path segment. Dimensions above 5000px per edge are clamped. ?random=N is accepted as a cache-buster. Random responses send a Link: …; rel="canonical" pointing at the resolved /id/… URL so you can pin it.
# random image, 400×300, as a file curl -L -H "Authorization: Bearer pc_live_..." \ "https://api.photocen.com/400/300" -o out.jpg # specific image, grayscale + blur, WebP curl -H "Authorization: Bearer pc_live_..." \ "https://api.photocen.com/id/123/800/600.webp?grayscale&blur=3" -o out.webp # deterministic from a seed curl -H "Authorization: Bearer pc_live_..." \ "https://api.photocen.com/seed/homepage-hero/1200/630" -o hero.jpg # catalog + metadata (free) curl -H "Authorization: Bearer pc_live_..." "https://api.photocen.com/v2/list?page=1&limit=10" curl -H "Authorization: Bearer pc_live_..." "https://api.photocen.com/id/123/info"
Because each delivery is metered, requests are authenticated with a bearer token rather than embedded as anonymous public URLs. For server-rendered pages, fetch through your backend (which holds the token) or proxy/cache the bytes.
Generate an image
curl https://api.photocen.com/v1/images/generate \
-H "Authorization: Bearer pc_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"prompt": "a seaside cafe at golden hour",
"negative_prompt": "blurry, watermark",
"region": "jp",
"settings": { "width":1024, "height":1024, "steps":30, "seed":null, "cfg":7 },
"style": { "use_style_memory": true, "style_override": null },
"options": { "not_searchable": false }
}'Response includes job_id, estimated_cost, credits_reserved, and applied_region. Poll GET /v1/images/jobs/{job_id} for the result; the first URL returned is the APP local cache (instant), then searchable images migrate to object storage.
$ch = curl_init("https://api.photocen.com/v1/images/generate");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer pc_live_...",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["prompt" => "a red bicycle"]),
]);
$res = json_decode(curl_exec($ch), true);const r = await fetch("https://api.photocen.com/v1/images/generate", {
method: "POST",
headers: {
"Authorization": "Bearer pc_live_...",
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({ prompt: "a red bicycle", options: { not_searchable: false } }),
});
const data = await r.json();Visual search
POST https://api.photocen.com/v1/images/search
{ "query": "seaside cafe", "limit": 20, "filters": { "same_region_only": false, "own_images_only": false } }
Returns only searchable images already migrated to object storage, as signed URLs. Private images are never returned to other users.
Searchable vs private
By default images are searchable: moved to object storage hourly and indexed for visual search. A not_searchable image is private: it stays only in APP local cache for 24h, is never indexed, and is deleted by the daily cleanup job.
Region behavior
Region priority for normal users: request → profile default → billing country → IP geo (if enabled) → system default (global). The applied region is returned in every generation response and influences prompt localization only.
Partner API
White-label B2B partner systems provision and bill their own end users through a dedicated key set. Partner onboarding, keys, and the full endpoint reference are handled directly by the platform team — contact us to become a partner.
Errors
{ "error": { "code": "insufficient_credits", "message": "...", "request_id": "..." } }