You are already generating images with OpenAI (DALL·E 3 or gpt-image-1). PixelFireman is a standard REST image API with Bearer auth, so for most integrations you change the base URL and one response-reading line. This page maps every request parameter and response field, calls out what is different, and gives you a working before/after example.
The short version: keep your prompt, point at https://pixelfireman.com/v1/images, send your pf_live_ key, and read data.image instead of data.data[0].url. Branch on format (url vs svg) and read creditsUsed to track spend.
POST with a JSON body. Any HTTP client works.mode: "draw", something the OpenAI image API does not return.OpenAI’s POST /v1/images/generations maps to PixelFireman’s POST /v1/images:
| OpenAI | PixelFireman | Notes |
|---|---|---|
prompt | prompt | Same. Keep your prompt text as-is. |
model (e.g. "dall-e-3", "gpt-image-1") | , (omit) | PixelFireman picks the engine. The model field here means your own trained style model id, not an OpenAI model name. Drop the OpenAI model string. |
size ("1024x1024", "1024x1792", "1792x1024") | size ("1024x1024", "1024x1536", "1536x1024") | Same WIDTHxHEIGHT string format. Use PixelFireman’s nearest ratio. Max 2048×2048. Credits scale with megapixels. |
n | , (not supported) | One image per call. Loop the request n times client-side. |
quality ("standard"/"hd") | , (not supported for photos) | No photo quality switch. (draw mode accepts quality: "high" for richer SVG only.) |
style ("vivid"/"natural") | , (fold into the prompt) | Express style in the prompt text, e.g. “natural lighting, muted colours”. |
response_format ("url"/"b64_json") | , (always a URL or SVG) | No base64 option. Read format + image (see below) and download the URL if you need bytes. |
| , (none) | mode ("auto"/"generate"/"draw") | New. generate = photo, draw = flat SVG vector, auto = server picks. Defaults to auto. |
Both use a Bearer header, so this line barely changes:
| OpenAI | PixelFireman |
|---|---|
Authorization: Bearer sk-... | Authorization: Bearer pf_live_... |
OpenAI-Organization header | , (not used) |
PixelFireman also accepts x-api-key: pf_live_... as an alternative. Get your key in the account dashboard.
OpenAI nests the result under data[]. PixelFireman returns a flat object, read image directly and lead on creditsUsed for billing.
| OpenAI | PixelFireman | Notes |
|---|---|---|
data[0].url | image (when format === "url") | Flat, not an array. One image per call. |
data[0].b64_json | , (none) | No base64. Fetch the image URL to get bytes. |
data[0].revised_prompt | , (none) | Not returned. |
| , (billed on your OpenAI invoice) | creditsUsed | What this call cost you, in credits. Read this to track spend. |
| , (none) | usage.creditsLeft | Your remaining balance after the call. |
| , (none) | format ("url"/"svg") | Always branch on this before using image. |
| , (none) | engine, cost | Informational. cost is our internal provider cost in USD, not your price, you pay in credits. Safe to ignore. |
The same “generate and save a PNG” task, in Node 18+ fetch.
import fs from "node:fs";
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const r = await openai.images.generate({
model: "dall-e-3",
prompt: "a red fox sitting in autumn leaves",
size: "1024x1024",
n: 1,
});
const url = r.data[0].url;
const img = await fetch(url);
const buf = Buffer.from(await img.arrayBuffer());
fs.writeFileSync("output.png", buf);
console.log("Saved output.png");
import fs from "node:fs";
const API_KEY = process.env.PF_API_KEY;
const res = await fetch(
"https://pixelfireman.com/v1/images", {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: "a red fox sitting in autumn leaves",
mode: "generate",
size: "1024x1024",
}),
});
if (!res.ok) {
const e = await res.json().catch(() => ({}));
throw new Error(`HTTP ${res.status}: ${e.error}`);
}
const data = await res.json();
console.log("credits used:", data.creditsUsed,
"left:", data.usage.creditsLeft);
if (data.format === "url") {
const img = await fetch(data.image);
const buf = Buffer.from(await img.arrayBuffer());
fs.writeFileSync("output.png", buf);
} else {
fs.writeFileSync("output.svg", data.image);
}
console.log("Saved output");
The real changes: no SDK, the endpoint URL, read data.image (not data.data[0].url), and branch on data.format. Everything else is your existing prompt and size.
| OpenAI feature | On PixelFireman | What to do |
|---|---|---|
n > 1 (batch) | Not supported | Loop the request. Respect the limits: 120 requests/min and 6 concurrent per key. |
b64_json response | Not supported | Fetch the returned image URL to get bytes. |
Image edits / inpainting (/images/edits) | Different endpoint | Use POST /v1/images/edit with images[] (data URIs or https URLs). Costs more credits per megapixel. See the API docs. |
Variations (/images/variations) | Not supported | Re-prompt, or train a custom style model for a consistent look. |
quality: "hd", style | Not supported for photos | Fold intent into the prompt text. |
| Streaming / partial images | Not supported | Single response per call. |
Both return a JSON body on error. OpenAI nests it under error.message; PixelFireman returns a flat { "error": "..." }. Status codes line up closely:
| Status | OpenAI | PixelFireman | Handling |
|---|---|---|---|
400 | Invalid request | Missing prompt or size over 2048×2048 cap | Fix the body. Do not retry unchanged. |
401 | Bad API key | Invalid or missing key | Check the Authorization header. No credits charged. |
402 | , (billing via plan) | Out of credits (noCredits: true) | Top up in the dashboard. May include creditsNeeded. |
429 | Rate limit | Rate (120/min) or concurrency (6) limit | Back off and retry; a Retry-After header is set. |
400/451 | Content policy (content_policy_violation) | Moderation block, 451 (moderated: true) | Reword the prompt and retry. The message starts with Blocked:. |
500 | Server error | Server error | Retry with exponential backoff. No credits charged on failure. |
A migration-friendly read: OpenAI code that checks res.ok and reads err.error.message should read err.error (a string) on PixelFireman. Billing never happens on a failed, blocked, or unauthorised request.
PixelFireman photo generation runs on FLUX.1 [schnell], a different model from DALL·E 3 / gpt-image-1. Honest expectations:
mode: "draw" returns clean SVG, which OpenAI’s image API does not do.The goal is not “identical output”, it is generating images for the same publishing workload at a lower cost.
| Pack | Price | Image credits | Per 1,000 |
|---|---|---|---|
| Starter | $10 | 1,400 | ~$7.14 |
| Plus | $25 | 3,750 | ~$6.67 |
| Pro | $50 | 8,000 | ~$6.25 |
A 1024×1024 image is 1 credit; credits scale with megapixels (rounded up, min 1). Best rate ($0.00625 / image) is on the $50 Pro pack. Prepaid, no subscription, credits never expire. The 6× comparison is against OpenAI’s standard $0.04 image rate (DALL·E 3, 1024×1024, standard quality, as of October 2026).
Grab a pf_live_ key, change your base URL to https://pixelfireman.com/v1/images, and read data.image. The full reference, including async video and custom models, is in the API docs.