PixelBin Claude Skill
Turn Claude into a full media pipeline. Generate, transform, store, and deliver images & videos at scale using PixelBin.
When to use
- User wants to generate images (nanoBanana, nanoBanana 2, nanoBanana Pro)
- User wants to generate videos (Sora 2, Veo 3, Kling 3, Hailuo, Seedance, LTX-2, Wan)
- User wants to remove backgrounds, watermarks, or upscale images/videos in bulk
- User wants permanent CDN URLs for media
- User wants to build URL-based image transformations (resize, crop, format, quality, etc.)
- User wants to generate SEO content (titles, meta, FAQ schema, briefs)
- User wants to build a landing page with AI-generated images stitched together
- User mentions "PixelBin", "nano banana", "build a media pipeline", "bulk image processing"
First-run behaviour (IMPORTANT)
Read INTRO.md before responding. INTRO.md is the user-facing voice of this skill — match its tone and follow its "How Claude should respond" section.
If the user has already stated a clear goal (e.g. "generate 6 hero images for X", "remove backgrounds from these photos", "build a landing page for Y"):
- Confirm
.env and node_modules/ are ready (see Setup check below) — auto-fix silently if you can.
- Confirm model + key options in ONE friendly line (don't make them write JSON — give a default they can accept with "go"):
- Image gen: "Quick pick: nano banana 2 (default, balanced) or nano banana Pro (premium quality, slower)? Aspect: 1:1 / 16:9 / 9:16 / 4:5 (default 1:1). Resolution: 1K / 2K / 4K (default 2K). Or just say 'defaults' and I'll use nano banana 2 · 1:1 · 2K."
- Video gen: "Quick pick: Veo 3 Fast (default, balanced cost), Veo 3 (premium), Sora 2 (with audio), Kling 3 (cinematic), or Hailuo 2.3 (1080p)? Duration: 4 / 6 / 8s (default 6). Aspect: 16:9 / 9:16 / 1:1 (default 16:9)."
- Resize/format: safe to default silently →
t.resize(...)~t.toFormat(f:webp)~t.compress().
- If the user already specified everything in their prompt, skip the picker and just run.
- Run the right scripts under the hood and hand back CDN URLs.
If the user is just exploring ("hi", "what can you do?", "help"):
- Greet them and present the broad buckets from INTRO.md (image gen, image edit, transformation, AI cleanup, video, bulk, SEO, landing pages).
- Show one concrete example prompt + a sample CDN URL from INTRO.md so it feels real and easy.
- Invite them to just say what they want in plain English. No CLI talk.
Default to chat-first. Don't expose CLI flags, JOBS arrays, model names, or transform syntax unless the user asks "how does this work?". Run scripts silently; report results visually.
Handling images the user provides (CRITICAL)
When the user references an image, you must obtain it yourself — never ask them to "give me a file path" or "save it to Downloads". The image is already accessible to you in one of these forms:
| What the user did |
What you do |
| Pasted an image inline in the chat |
The image is in your conversation context. Use the Write tool to save the bytes to ./scripts/_inputs/<slug>.<ext>, then upload it via pixelbin.assets.fileUpload({ file: fs.createReadStream(...) }) to get a permanent CDN URL. Pass that URL into images: [...] for the prediction. |
Gave you a public URL (e.g. https://example.com/photo.jpg, a CDN URL, a Slack/Drive public link) |
Two options:• Quick path — pass the URL straight into images: [url] of pixelbin.predictions.createAndWait (most models accept a URL). No upload needed.• Permanent path — call pixelbin.assets.urlUpload({ url, path: '<folder>', name: '<slug>', access: 'public-read' }) to store it in PixelBin DAM, then use the resulting CDN URL. |
Gave a local path (~/Downloads/photo.jpg, ./photo.jpg) |
Use pixelbin.assets.fileUpload({ file: fs.createReadStream(absPath), ... }). |
| Mentioned an image but didn't attach or link it |
Now ask — but politely: "Drop the image into the chat or paste a URL — I'll handle the rest." |
Never say "the inline image isn't saved on disk, please paste the path" — that's a user-experience failure. Saving inline image bytes to disk is your job, not theirs.
Cost-aware path selection (CRITICAL)
Before reaching for a generation model, decide whether the task needs generation at all. Generation models are the most expensive op in the stack. For most product / e-commerce / variant tasks, you can do the same job with a cheap prediction + free URL transforms.
Decision tree
| User intent |
Cheap path (use this) |
Expensive path (avoid unless asked) |
| "Same product, white bg, marketplace-ready" (Amazon, Shopify, Flipkart, etc.) |
1. erase_bg prediction → transparent PNG2. Upload to DAM3. URL transform: t.extend(...,bc:ffffff)~t.resize(h:H,w:W)~t.toFormat(f:webp)~t.compress() |
nanoBanana regenerate (loses product fidelity, ~10× cost) |
| "Resize / reformat / compress / different aspect ratio" for an existing image |
URL transforms only — t.resize, t.toFormat, t.compress, t.extend (free, just CDN params) |
Regeneration |
| "Upscale to 4K" |
vsr_upscale prediction (or t.resize if source is large enough) |
Regeneration at higher res |
| "Remove watermark" |
wm_remove / wmrPro_remove / wmrMax_remove prediction |
Regeneration |
| "Remove background and place on new scene" |
erase_bg + composite via t.merge / generation only for the new background |
Full regeneration of the whole image |
| "Generate a NEW scene / NEW product shot / hero image from scratch" |
Generation model (nanoBanana 2 / Pro) — this is the right tool |
— |
| "Variants of the same hero (color, angle, style change)" |
Image-to-image with nanoBanana2_generate + images:[ref] (preserves identity) |
Text-only regeneration (loses identity) |
Cost ranking (rough, lower → cheaper)
- URL transforms — free, no API call
- Plugin transforms in URL (when activated) — free per request, included in plan
- Predictions:
erase_bg, wm_remove, vsr_upscale — small per-call credit cost
- Image generation —
nanoBanana_generate < nanoBanana2_generate < nanoBananaPro_generate
- Video generation — most expensive op; always confirm before spending
Worked example — "Amazon + Shopify + Instagram-ready, white bg, 4K, 1:1 + 9:16"
Wrong (what NOT to do): regenerate each variant with nanoBanana — 12 outputs × generation cost, plus product hallucination risk.
Right (default behavior):
For each source image:
1. urlUpload(source) → CDN URL
2. predictions.createAndWait({ name: 'erase_bg', input: { image: cdnUrl } }) → transparent PNG
3. urlUpload(eraseBgOutput) → CDN URL of transparent product
4. Build transform URLs (no API call):
• Amazon 1:1 t.extend(t:200,r:200,b:200,l:200,bc:ffffff)~t.resize(h:2048,w:2048)~t.toFormat(f:jpeg)~t.compress()
• Shopify 1:1 t.extend(t:150,r:150,b:150,l:150,bc:ffffff)~t.resize(h:2048,w:2048)~t.toFormat(f:webp)~t.compress()
• Instagram 9:16 t.extend(t:600,r:200,b:600,l:200,bc:ffffff)~t.resize(h:1920,w:1080)~t.toFormat(f:webp)~t.compress()
This costs ~1 prediction per source image, vs 3 generations per source. Same visual result, fraction of the credits, zero product drift.
When in doubt — ask the user
If a task is borderline (e.g. "make this look more premium" — could be a transform or a regen), say in one line: "I can either (a) clean + restyle the existing photo with bg-remove + transforms (~1 credit each, preserves the actual product) or (b) regenerate hero shots with nano banana 2 (higher cost, more creative freedom). Which do you want?"
Setup check (always do this first)
Before running any script, verify:
.env exists with PIXELBIN_API_TOKEN and PIXELBIN_CLOUD_NAME
npm install has been run (deps: @pixelbin/admin, dotenv)
If missing, walk the user through cp .env.example .env and link them to the API Token page and signup.
Core architecture
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ GENERATE │ → │ STORE (DAM) │ → │ TRANSFORM │
│ image-gen │ │ assets.upload │ │ URL params │
│ video-gen │ │ folders, tags │ │ (free, chained)│
└──────────────────┘ └──────────────────┘ └──────────────────┘
↓
┌──────────────────┐
│ DELIVER (CDN) │
│ cdn.pixelbin.io │
└──────────────────┘
Two URL patterns:
- Original (no transform):
https://cdn.pixelbin.io/v2/<CLOUD>/original/<path>/<file>.<ext>
- Transformed:
https://cdn.pixelbin.io/v2/<CLOUD>/<t.preset(args)>/<path>/<file>.<ext>
- Multiple transforms chained with
~: t.resize(h:1024,w:1024)~t.toFormat(f:webp)~t.compress()
Capabilities (high-level)
| Capability |
Script |
Reference |
| AI image generation |
scripts/generate-image.js |
apis.md#image-generation |
| AI video generation |
scripts/generate-video.js |
apis.md#video-generation |
| Upload local file / URL → CDN |
scripts/upload.js |
cdn.md |
| Build transformation URLs |
scripts/transform.js |
transformations.md |
| Generate SEO + design brief |
scripts/seo-content.js |
use-cases.md |
| Build full landing page (uses brand design tokens) |
scripts/build-page.js |
use-cases.md |
SEO + landing-page input model
When the user wants SEO content or a landing page, ALWAYS gather these before running anything:
- Target keyword (required) — what to rank for.
- Brand reference (strongly recommended) — either a
--brand-url <url> OR --brand-files "<glob>" (CSS / HTML / JSX / MD). Without this, the page won't match the user's design.
- Research reference (optional) —
--research-url <url> of a competitor or top-ranking page for SERP-intent signal.
- Voice description (optional) —
--voice "<short description>".
scripts/seo-content.js produces brief.json. It includes design_system (palette / fonts / CSS vars / max-widths) extracted from the brand reference. Claude then reads the brief and writes page-spec.json. build-page.js consumes the design block in page-spec.json and applies it as CSS variables (--fg, --bg, --accent, --font-body, --font-heading, --container).
If the user does NOT provide a brand reference, ask for one before generating the page. Don't guess colors/fonts.
SDK pattern (memorize this)
const { PixelbinConfig, PixelbinClient } = require('@pixelbin/admin');
const pixelbin = new PixelbinClient(new PixelbinConfig({
domain: 'https://api.pixelbin.io',
apiSecret: process.env.PIXELBIN_API_TOKEN,
}));
// 1. GENERATE (any AI model — image OR video — same shape)
const r = await pixelbin.predictions.createAndWait({
name: 'nanoBanana2_generate', // or veo3_generate, sora2_generate, kling3_generate, etc.
input: {
prompt: '...', // required
images: ['https://...'], // optional, image-to-image / image-to-video
aspect_ratio: '16:9', // optional, model-dependent
output_resolution: '2K', // optional, image models only
duration: 8, // optional, video models only
},
});
// r.status === 'SUCCESS' → r.output[0] is a temp URL (~30-day retention)
// 2. UPLOAD (local file → permanent CDN URL)
const up = await pixelbin.assets.fileUpload({
file: fs.createReadStream('./photo.jpg'),
path: 'my-folder',
name: 'hero',
access: 'public-read',
overwrite: true,
});
// up.path / up.format → build URL: cdn.pixelbin.io/v2/<CLOUD>/original/<up.path>/hero.<up.format>
// 3. URL UPLOAD (remote URL → permanent CDN URL)
const up2 = await pixelbin.assets.urlUpload({
url: r.output[0],
path: 'my-folder',
name: 'ai-output-1',
access: 'public-read',
overwrite: true,
});
// 4. TRANSFORM (no API call — just build the URL)
const cdn = `https://cdn.pixelbin.io/v2/${CLOUD}/t.resize(h:2048,w:2048)~t.toFormat(f:webp)~t.compress()/my-folder/hero.png`;
Models reference
Image generation
name |
Use for |
nanoBanana_generate |
Cheapest / fastest. Photo edits & fixes. |
nanoBanana2_generate |
Default. High quality, supports aspect_ratio + output_resolution. |
nanoBananaPro_generate |
Hero / showcase quality. |
Video generation (popular)
name |
Notes |
veo3_generate |
Google Veo 3 — state-of-the-art |
veo3Fast_generate |
Faster, cheaper Veo 3 |
sora2_generate |
OpenAI Sora 2 — text/image → video w/ audio |
kling3_generate |
High-quality text/image → video, optional audio |
kling26_generate |
Cinematic, fluid motion + native audio |
hailuo23_generate |
MiniMax 1080p |
seedancePro_generate |
Bytedance, high-quality |
wan25_generate |
Image-to-video |
ltx2_generate |
High-fidelity with audio from images |
Full list: references/apis.md.
Common URL transformations
Basic transforms (always available — no plugin needed):
| Transform |
Syntax |
Example |
| Resize |
t.resize(h:H,w:W) |
t.resize(h:1024,w:1024) |
| Format convert |
t.toFormat(f:FMT) |
t.toFormat(f:webp) / t.toFormat(f:jpeg) / t.toFormat(f:png) |
| Compress |
t.compress() |
— |
| Blur / sharpen |
t.blur(s:N) / t.sharpen(s:N) |
t.blur(s:5) |
| Rotate |
t.rotate(a:DEG) |
t.rotate(a:90) |
| Extract region |
t.extract(t:T,l:L,h:H,w:W) |
t.extract(t:0,l:0,h:500,w:500) |
| Extend / pad |
t.extend(t:T,r:R,b:B,l:L,bc:HEX) |
t.extend(t:20,r:20,b:20,l:20,bc:ffffff) |
AI ops via plugins (require activation in console.pixelbin.io → Plugins) — identifiers: erase_bg, wm_remove, wmrPro_remove, wmrMax_remove, af_remove, ocr_extract, pr_tag, vsr_upscale, wmv_remove, pwr_remove. For features the user hasn't activated, fall back to the predictions API (pixelbin.predictions.createAndWait) — that always works.
Chain transforms with ~. Full catalog: references/transformations.md.
Error handling
| Error |
Cause |
Action |
Insufficient credits / Usage Limit Exceeded |
Plan quota |
Surface upgrade link: https://www.pixelbin.io/pricing?utm_source=github&utm_medium=claude-skill&utm_campaign=quota-error |
Prompt is required |
Empty prompt |
Validate before submitting |
No output image received |
Transient model failure |
Retry the single job |
408 / ECONNABORTED |
Network timeout |
Retry the job (SDK polls ~10 min) |
| 429 |
Rate-limit |
Lower concurrency to 2–3 |
Invalid path |
Bad folder name in upload |
Use slug-safe names (lowercase, hyphens) |
Script conventions (when generating code)
- Use
dotenv for credentials. Never hardcode tokens.
- Batch concurrency: 4 for generation, 5 for uploads.
- Persist progress to JSON after each batch (resumable).
- Use slug-safe
name values (lowercase, hyphens, no spaces).
- Default
access: 'public-read' unless the user wants signed URLs.
What NOT to do
- ❌ Don't suggest scraping / bulk-downloading from third-party sites
- ❌ Don't generate content with real, named individuals without consent
- ❌ Don't surface the user's API token in chat or logs
- ❌ Don't claim a transformation works without checking
references/transformations.md
Files in this skill
INTRO.md — first-run user walkthrough (READ THIS WHEN INVOKED)
SKILL.md — this file
README.md — public-facing repo readme
SHOWCASE.md — sample gallery
.env.example — credentials template
package.json — deps
scripts/ — runnable scripts (generate-image, generate-video, upload, transform, seo-content, build-page)
references/ — apis.md, transformations.md, cdn.md, use-cases.md
examples/ — ready-to-run sample job files
1---2name: pixelbin3description: Use when the user wants to generate AI images or videos, transform/edit existing media, build production media pipelines, get CDN URLs for images/videos, do bulk image processing (background removal, watermark removal, upscaling, resizing), generate SEO content for pages, or build landing pages with AI-generated visuals. Powered by PixelBin's 85+ AI APIs and 60+ URL-based transformations.4---56# PixelBin Claude Skill78Turn Claude into a full media pipeline. Generate, transform, store, and deliver images & videos at scale using PixelBin.910## When to use1112- User wants to generate images (nanoBanana, nanoBanana 2, nanoBanana Pro)13- User wants to generate videos (Sora 2, Veo 3, Kling 3, Hailuo, Seedance, LTX-2, Wan)14- User wants to remove backgrounds, watermarks, or upscale images/videos in bulk15- User wants permanent CDN URLs for media16- User wants to build URL-based image transformations (resize, crop, format, quality, etc.)17- User wants to generate SEO content (titles, meta, FAQ schema, briefs)18- User wants to build a landing page with AI-generated images stitched together19- User mentions "PixelBin", "nano banana", "build a media pipeline", "bulk image processing"2021## First-run behaviour (IMPORTANT)2223Read [`INTRO.md`](INTRO.md) before responding. INTRO.md is the user-facing voice of this skill — match its tone and follow its "How Claude should respond" section.2425**If the user has already stated a clear goal** (e.g. "generate 6 hero images for X", "remove backgrounds from these photos", "build a landing page for Y"):261. Confirm `.env` and `node_modules/` are ready (see Setup check below) — auto-fix silently if you can.272. **Confirm model + key options in ONE friendly line** (don't make them write JSON — give a default they can accept with "go"):28 - **Image gen:** _"Quick pick: **nano banana 2** (default, balanced) or **nano banana Pro** (premium quality, slower)? Aspect: 1:1 / 16:9 / 9:16 / 4:5 (default 1:1). Resolution: 1K / 2K / 4K (default 2K). Or just say 'defaults' and I'll use nano banana 2 · 1:1 · 2K."_29 - **Video gen:** _"Quick pick: **Veo 3 Fast** (default, balanced cost), **Veo 3** (premium), **Sora 2** (with audio), **Kling 3** (cinematic), or **Hailuo 2.3** (1080p)? Duration: 4 / 6 / 8s (default 6). Aspect: 16:9 / 9:16 / 1:1 (default 16:9)."_30 - **Resize/format:** safe to default silently → `t.resize(...)~t.toFormat(f:webp)~t.compress()`.31 - If the user already specified everything in their prompt, skip the picker and just run.323. Run the right scripts under the hood and hand back CDN URLs.3334**If the user is just exploring** ("hi", "what can you do?", "help"):351. Greet them and present the **broad buckets** from INTRO.md (image gen, image edit, transformation, AI cleanup, video, bulk, SEO, landing pages).362. Show **one concrete example prompt + a sample CDN URL** from INTRO.md so it feels real and easy.373. Invite them to just say what they want in plain English. No CLI talk.3839**Default to chat-first.** Don't expose CLI flags, JOBS arrays, model names, or transform syntax unless the user asks "how does this work?". Run scripts silently; report results visually.4041## Handling images the user provides (CRITICAL)4243When the user references an image, **you must obtain it yourself** — never ask them to "give me a file path" or "save it to Downloads". The image is already accessible to you in one of these forms:4445| What the user did | What you do |46| --- | --- |47| **Pasted an image inline in the chat** | The image is in your conversation context. Use the `Write` tool to save the bytes to `./scripts/_inputs/<slug>.<ext>`, then upload it via `pixelbin.assets.fileUpload({ file: fs.createReadStream(...) })` to get a permanent CDN URL. Pass that URL into `images: [...]` for the prediction. |48| **Gave you a public URL** (e.g. `https://example.com/photo.jpg`, a CDN URL, a Slack/Drive public link) | Two options:<br>• **Quick path** — pass the URL straight into `images: [url]` of `pixelbin.predictions.createAndWait` (most models accept a URL). No upload needed.<br>• **Permanent path** — call `pixelbin.assets.urlUpload({ url, path: '<folder>', name: '<slug>', access: 'public-read' })` to store it in PixelBin DAM, then use the resulting CDN URL. |49| **Gave a local path** (`~/Downloads/photo.jpg`, `./photo.jpg`) | Use `pixelbin.assets.fileUpload({ file: fs.createReadStream(absPath), ... })`. |50| **Mentioned an image but didn't attach or link it** | _Now_ ask — but politely: _"Drop the image into the chat or paste a URL — I'll handle the rest."_ |5152**Never** say "the inline image isn't saved on disk, please paste the path" — that's a user-experience failure. Saving inline image bytes to disk is your job, not theirs.5354## Cost-aware path selection (CRITICAL)5556**Before reaching for a generation model, decide whether the task needs generation at all.** Generation models are the most expensive op in the stack. For most product / e-commerce / variant tasks, you can do the same job with a cheap prediction + free URL transforms.5758### Decision tree5960| User intent | Cheap path (use this) | Expensive path (avoid unless asked) |61| --- | --- | --- |62| **"Same product, white bg, marketplace-ready"** (Amazon, Shopify, Flipkart, etc.) | 1. `erase_bg` prediction → transparent PNG<br>2. Upload to DAM<br>3. URL transform: `t.extend(...,bc:ffffff)~t.resize(h:H,w:W)~t.toFormat(f:webp)~t.compress()` | nanoBanana regenerate (loses product fidelity, ~10× cost) |63| **"Resize / reformat / compress / different aspect ratio"** for an existing image | URL transforms only — `t.resize`, `t.toFormat`, `t.compress`, `t.extend` (free, just CDN params) | Regeneration |64| **"Upscale to 4K"** | `vsr_upscale` prediction (or `t.resize` if source is large enough) | Regeneration at higher res |65| **"Remove watermark"** | `wm_remove` / `wmrPro_remove` / `wmrMax_remove` prediction | Regeneration |66| **"Remove background and place on new scene"** | `erase_bg` + composite via `t.merge` / generation only for the new background | Full regeneration of the whole image |67| **"Generate a NEW scene / NEW product shot / hero image from scratch"** | Generation model (nanoBanana 2 / Pro) — this is the right tool | — |68| **"Variants of the same hero (color, angle, style change)"** | Image-to-image with `nanoBanana2_generate` + `images:[ref]` (preserves identity) | Text-only regeneration (loses identity) |6970### Cost ranking (rough, lower → cheaper)711. **URL transforms** — free, no API call722. **Plugin transforms** in URL (when activated) — free per request, included in plan733. **Predictions: `erase_bg`, `wm_remove`, `vsr_upscale`** — small per-call credit cost744. **Image generation** — `nanoBanana_generate` < `nanoBanana2_generate` < `nanoBananaPro_generate`755. **Video generation** — most expensive op; always confirm before spending7677### Worked example — "Amazon + Shopify + Instagram-ready, white bg, 4K, 1:1 + 9:16"7879**Wrong** (what NOT to do): regenerate each variant with nanoBanana — 12 outputs × generation cost, plus product hallucination risk.8081**Right** (default behavior):82```83For each source image:84 1. urlUpload(source) → CDN URL85 2. predictions.createAndWait({ name: 'erase_bg', input: { image: cdnUrl } }) → transparent PNG86 3. urlUpload(eraseBgOutput) → CDN URL of transparent product87 4. Build transform URLs (no API call):88 • Amazon 1:1 t.extend(t:200,r:200,b:200,l:200,bc:ffffff)~t.resize(h:2048,w:2048)~t.toFormat(f:jpeg)~t.compress()89 • Shopify 1:1 t.extend(t:150,r:150,b:150,l:150,bc:ffffff)~t.resize(h:2048,w:2048)~t.toFormat(f:webp)~t.compress()90 • Instagram 9:16 t.extend(t:600,r:200,b:600,l:200,bc:ffffff)~t.resize(h:1920,w:1080)~t.toFormat(f:webp)~t.compress()91```9293This costs **~1 prediction per source image**, vs **3 generations per source**. Same visual result, fraction of the credits, zero product drift.9495### When in doubt — ask the user96If a task is borderline (e.g. "make this look more premium" — could be a transform or a regen), say in one line: _"I can either (a) clean + restyle the existing photo with bg-remove + transforms (~1 credit each, preserves the actual product) or (b) regenerate hero shots with nano banana 2 (higher cost, more creative freedom). Which do you want?"_9798## Setup check (always do this first)99100Before running any script, verify:1011021. `.env` exists with `PIXELBIN_API_TOKEN` and `PIXELBIN_CLOUD_NAME`1032. `npm install` has been run (deps: `@pixelbin/admin`, `dotenv`)104105If missing, walk the user through `cp .env.example .env` and link them to the [API Token page](https://console.pixelbin.io) and [signup](https://www.pixelbin.io/?utm_source=github&utm_medium=claude-skill&utm_campaign=signup).106107## Core architecture108109```110┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐111│ GENERATE │ → │ STORE (DAM) │ → │ TRANSFORM │112│ image-gen │ │ assets.upload │ │ URL params │113│ video-gen │ │ folders, tags │ │ (free, chained)│114└──────────────────┘ └──────────────────┘ └──────────────────┘115 ↓116 ┌──────────────────┐117 │ DELIVER (CDN) │118 │ cdn.pixelbin.io │119 └──────────────────┘120```121122Two URL patterns:123124- **Original (no transform):** `https://cdn.pixelbin.io/v2/<CLOUD>/original/<path>/<file>.<ext>`125- **Transformed:** `https://cdn.pixelbin.io/v2/<CLOUD>/<t.preset(args)>/<path>/<file>.<ext>`126 - Multiple transforms chained with `~`: `t.resize(h:1024,w:1024)~t.toFormat(f:webp)~t.compress()`127128## Capabilities (high-level)129130| Capability | Script | Reference |131| --- | --- | --- |132| AI image generation | `scripts/generate-image.js` | [apis.md#image-generation](references/apis.md#image-generation) |133| AI video generation | `scripts/generate-video.js` | [apis.md#video-generation](references/apis.md#video-generation) |134| Upload local file / URL → CDN | `scripts/upload.js` | [cdn.md](references/cdn.md) |135| Build transformation URLs | `scripts/transform.js` | [transformations.md](references/transformations.md) |136| Generate SEO + design brief | `scripts/seo-content.js` | [use-cases.md](references/use-cases.md) |137| Build full landing page (uses brand design tokens) | `scripts/build-page.js` | [use-cases.md](references/use-cases.md) |138139### SEO + landing-page input model140141When the user wants SEO content or a landing page, ALWAYS gather these before running anything:1421431. **Target keyword** (required) — what to rank for.1442. **Brand reference** (strongly recommended) — either a `--brand-url <url>` OR `--brand-files "<glob>"` (CSS / HTML / JSX / MD). Without this, the page won't match the user's design.1453. **Research reference** (optional) — `--research-url <url>` of a competitor or top-ranking page for SERP-intent signal.1464. **Voice description** (optional) — `--voice "<short description>"`.147148`scripts/seo-content.js` produces `brief.json`. It includes `design_system` (palette / fonts / CSS vars / max-widths) extracted from the brand reference. Claude then reads the brief and writes `page-spec.json`. `build-page.js` consumes the `design` block in `page-spec.json` and applies it as CSS variables (`--fg`, `--bg`, `--accent`, `--font-body`, `--font-heading`, `--container`).149150If the user does NOT provide a brand reference, ask for one before generating the page. Don't guess colors/fonts.151152## SDK pattern (memorize this)153154```js155const { PixelbinConfig, PixelbinClient } = require('@pixelbin/admin');156157const pixelbin = new PixelbinClient(new PixelbinConfig({158 domain: 'https://api.pixelbin.io',159 apiSecret: process.env.PIXELBIN_API_TOKEN,160}));161162// 1. GENERATE (any AI model — image OR video — same shape)163const r = await pixelbin.predictions.createAndWait({164 name: 'nanoBanana2_generate', // or veo3_generate, sora2_generate, kling3_generate, etc.165 input: {166 prompt: '...', // required167 images: ['https://...'], // optional, image-to-image / image-to-video168 aspect_ratio: '16:9', // optional, model-dependent169 output_resolution: '2K', // optional, image models only170 duration: 8, // optional, video models only171 },172});173// r.status === 'SUCCESS' → r.output[0] is a temp URL (~30-day retention)174175// 2. UPLOAD (local file → permanent CDN URL)176const up = await pixelbin.assets.fileUpload({177 file: fs.createReadStream('./photo.jpg'),178 path: 'my-folder',179 name: 'hero',180 access: 'public-read',181 overwrite: true,182});183// up.path / up.format → build URL: cdn.pixelbin.io/v2/<CLOUD>/original/<up.path>/hero.<up.format>184185// 3. URL UPLOAD (remote URL → permanent CDN URL)186const up2 = await pixelbin.assets.urlUpload({187 url: r.output[0],188 path: 'my-folder',189 name: 'ai-output-1',190 access: 'public-read',191 overwrite: true,192});193194// 4. TRANSFORM (no API call — just build the URL)195const cdn = `https://cdn.pixelbin.io/v2/${CLOUD}/t.resize(h:2048,w:2048)~t.toFormat(f:webp)~t.compress()/my-folder/hero.png`;196```197198## Models reference199200### Image generation201| `name` | Use for |202| --- | --- |203| `nanoBanana_generate` | Cheapest / fastest. Photo edits & fixes. |204| `nanoBanana2_generate` | Default. High quality, supports `aspect_ratio` + `output_resolution`. |205| `nanoBananaPro_generate` | Hero / showcase quality. |206207### Video generation (popular)208| `name` | Notes |209| --- | --- |210| `veo3_generate` | Google Veo 3 — state-of-the-art |211| `veo3Fast_generate` | Faster, cheaper Veo 3 |212| `sora2_generate` | OpenAI Sora 2 — text/image → video w/ audio |213| `kling3_generate` | High-quality text/image → video, optional audio |214| `kling26_generate` | Cinematic, fluid motion + native audio |215| `hailuo23_generate` | MiniMax 1080p |216| `seedancePro_generate` | Bytedance, high-quality |217| `wan25_generate` | Image-to-video |218| `ltx2_generate` | High-fidelity with audio from images |219220Full list: [`references/apis.md`](references/apis.md).221222## Common URL transformations223224Basic transforms (always available — no plugin needed):225226| Transform | Syntax | Example |227| --- | --- | --- |228| Resize | `t.resize(h:H,w:W)` | `t.resize(h:1024,w:1024)` |229| Format convert | `t.toFormat(f:FMT)` | `t.toFormat(f:webp)` / `t.toFormat(f:jpeg)` / `t.toFormat(f:png)` |230| Compress | `t.compress()` | — |231| Blur / sharpen | `t.blur(s:N)` / `t.sharpen(s:N)` | `t.blur(s:5)` |232| Rotate | `t.rotate(a:DEG)` | `t.rotate(a:90)` |233| Extract region | `t.extract(t:T,l:L,h:H,w:W)` | `t.extract(t:0,l:0,h:500,w:500)` |234| Extend / pad | `t.extend(t:T,r:R,b:B,l:L,bc:HEX)` | `t.extend(t:20,r:20,b:20,l:20,bc:ffffff)` |235236AI ops via plugins (require activation in **console.pixelbin.io → Plugins**) — identifiers: `erase_bg`, `wm_remove`, `wmrPro_remove`, `wmrMax_remove`, `af_remove`, `ocr_extract`, `pr_tag`, `vsr_upscale`, `wmv_remove`, `pwr_remove`. For features the user hasn't activated, fall back to the **predictions API** (`pixelbin.predictions.createAndWait`) — that always works.237238Chain transforms with `~`. Full catalog: [`references/transformations.md`](references/transformations.md).239240## Error handling241242| Error | Cause | Action |243| --- | --- | --- |244| `Insufficient credits` / `Usage Limit Exceeded` | Plan quota | Surface upgrade link: https://www.pixelbin.io/pricing?utm_source=github&utm_medium=claude-skill&utm_campaign=quota-error |245| `Prompt is required` | Empty prompt | Validate before submitting |246| `No output image received` | Transient model failure | Retry the single job |247| 408 / `ECONNABORTED` | Network timeout | Retry the job (SDK polls ~10 min) |248| 429 | Rate-limit | Lower concurrency to 2–3 |249| `Invalid path` | Bad folder name in upload | Use slug-safe names (lowercase, hyphens) |250251## Script conventions (when generating code)252253- Use `dotenv` for credentials. Never hardcode tokens.254- Batch concurrency: 4 for generation, 5 for uploads.255- Persist progress to JSON after each batch (resumable).256- Use slug-safe `name` values (lowercase, hyphens, no spaces).257- Default `access: 'public-read'` unless the user wants signed URLs.258259## What NOT to do260261- ❌ Don't suggest scraping / bulk-downloading from third-party sites262- ❌ Don't generate content with real, named individuals without consent263- ❌ Don't surface the user's API token in chat or logs264- ❌ Don't claim a transformation works without checking [`references/transformations.md`](references/transformations.md)265266## Files in this skill267268- `INTRO.md` — first-run user walkthrough (READ THIS WHEN INVOKED)269- `SKILL.md` — this file270- `README.md` — public-facing repo readme271- `SHOWCASE.md` — sample gallery272- `.env.example` — credentials template273- `package.json` — deps274- `scripts/` — runnable scripts (generate-image, generate-video, upload, transform, seo-content, build-page)275- `references/` — `apis.md`, `transformations.md`, `cdn.md`, `use-cases.md`276- `examples/` — ready-to-run sample job files