# Easy Pro Design (EPD) - AI Agent Skill > **App:** Easy Pro Design (EPD) > **Description:** AI-powered product photography & brand visuals generation > **Base URL:** `https://my.easyprodesign.com` ## Authentication (Headless SSO) EPD supports headless authentication for AI agents using GFAVIP Wallet tokens. **Protocol:** 1. **Get PowerLobster Identity Token** * Endpoint: `POST https://powerlobster.com/api/agent/identity-token` * Auth: `Authorization: Bearer ` 2. **Exchange for GFAVIP SSO Token** * Endpoint: `POST https://wallet.gfavip.com/api/auth/powerlobster` * Body: `{"token": ""}` * Response: `{"sso_token": "gfavip-session-..."}` 3. **Authenticate with EPD** * Pass the SSO token in the Authorization header for all API requests: * `Authorization: Bearer ` **Agent Identity Check:** * **Endpoint:** `GET /api/me` ## Quick Start ```bash # 1. Verify your connection curl -H "Authorization: Bearer epd_sk_..." https://my.easyprodesign.com/api/me # 2. List available models curl -H "Authorization: Bearer epd_sk_..." https://my.easyprodesign.com/api/models # 3. Generate an image curl -X POST https://my.easyprodesign.com/api/generate \ -H "Authorization: Bearer epd_sk_..." \ -H "Content-Type: application/json" \ -d '{"prompt": "Professional product photo on white background", "brand_id": 1}' # 4. Poll for result curl -H "Authorization: Bearer epd_sk_..." https://my.easyprodesign.com/api/requests/42/status ``` ## API Endpoints All endpoints require `Authorization: Bearer ` unless noted. ### Identity & Health | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/api/me` | Required | Verify token, get account info (id, username, email, tier, teams) | | `GET` | `/api/health` | None | Service health check → `{"status": "ok"}` | ### Brands | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/brands` | List all brands → `{brands: [{id, name, brand_type, logo_url, created_at}]}` | | `GET` | `/api/brands/` | Get brand details (name, type, logos, colors, voice, avatar, product_images) | | `GET` | `/api/brands//requests` | List generation requests for brand → `[{id, title, prompt_preview, status, created_at}]` | | `GET` | `/api/brands//product-images` | Get brand's product photos for image generation → `{brand_id, brand_name, product_images: [{url, name, notes}], count}` | | `POST` | `/api/brands/import` | Import brand from JSON → `{id, name, status: "imported"}` | | `PATCH` | `/api/brands/` | Update brand fields (requires admin+ on team) | ### Image Types (Templates) | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/image-types` | List available image type templates with prompt templates, categories, and aspect ratios | **Response:** ```json { "image_types": [ { "id": 1, "name": "Amazon Main Image", "slug": "amazon-main", "category": "amazon", "prompt_template": "Create a clean Amazon main image: pure white background, product fills 85%+...", "aspect_ratio": "1:1", "pixel_width": 2000, "pixel_height": 2000, "creative_brief": "...", "is_global": true } ] } ``` Use `image_type_id` in `/api/generate` to leverage these templates instead of writing prompts from scratch. The template's prompt and aspect ratio are applied automatically. ### Image Generation | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | `/api/generate` | Create generation request (async for fal.ai models, sync for Gemini) | | `GET` | `/api/requests//status` | Poll generation status | | `POST` | `/api/requests//regenerate` | Generate new version | #### `POST /api/generate` **Request (freeform prompt):** ```json { "prompt": "Professional product photo on white background", "brand_id": 1, "model": "seedream-4.5", "image_size": "square_hd", "image_urls": [], "model_config": {} } ``` **Request (using image type template):** ```json { "image_type_id": 1, "prompt": "organic coffee beans in a kraft paper bag", "brand_id": 1 } ``` When using `image_type_id`, the template's `prompt_template` is prepended to your `prompt`. If no `prompt` is provided, the template is used verbatim. The template's `aspect_ratio` is also applied as the default `image_size` unless you override it. **Response (201):** ```json { "request_id": 42, "job_id": 99, "title": "Professional product photo...", "status": "pending", "status_url": "/api/requests/42/status" } ``` **Note:** Gemini (`model: "gemini"`) runs synchronously — the response will already have `status: "completed"` with the image URL. All fal.ai models are async and require polling. #### `GET /api/requests//status` Poll until `status` is `"completed"` or `"failed"`. **Response (completed):** ```json { "request_id": 42, "status": "completed", "version": 1, "prompt": "...", "image_url": "https://media.easyprodesign.com/...", "thoughts": "AI analysis...", "total_cost": 0.04, "all_versions": [{"version": 1, "url": "...", "cost": 0.04, "model": "seedream-4.5"}], "created_by": "username", "source": "api" } ``` #### `POST /api/requests//regenerate` **Request (all fields optional):** ```json { "prompt": "Updated prompt...", "image_urls": ["https://..."], "resolution": "2k" } ``` ### Image Tools | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | `/api/remove-bg` | Remove background from image → `{"image_url": "..."}` | | `POST` | `/api/upscale` | Upscale image resolution → `{"image_url": "..."}` | #### `POST /api/remove-bg` ```json {"image_url": "https://media.easyprodesign.com/..."} ``` #### `POST /api/upscale` ```json {"image_url": "https://media.easyprodesign.com/...", "scale_factor": 2} ``` ### Upload | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | `/api/upload-image` | Upload image (multipart form, field: `image`) → `{url, key}` | ### Models | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/models` | List available AI models with pricing and capabilities | **Response:** ```json { "seedream-4.5": {"name": "Seedream 4.5", "cost_per_image": 0.04, "quality_tier": "high", "supports_image_to_image": true}, "nano-banana-pro": {"name": "Nano Banana Pro", "cost_per_image": 0.15, "quality_tier": "premium", "supports_image_to_image": true}, "flux-dev": {"name": "Flux.1 Dev", "cost_per_image": 0.025, "quality_tier": "high", "supports_image_to_image": true}, "recraft-v3": {"name": "Recraft V3", "cost_per_image": 0.04, "quality_tier": "high", "supports_image_to_image": false}, "ideogram-v3": {"name": "Ideogram V3", "cost_per_image": 0.06, "quality_tier": "high", "supports_image_to_image": true}, "flux-kontext": {"name": "FLUX Kontext Pro", "cost_per_image": 0.04, "quality_tier": "high", "supports_image_to_image": true}, "gemini": {"name": "Imagen 4", "cost_per_image": 0.04, "quality_tier": "high", "supports_image_to_image": false} } ``` ### Request Management | Method | Endpoint | Description | |--------|----------|-------------| | `PATCH` | `/api/requests//title` | Update request title → `{"title": "New Title"}` | | `DELETE` | `/api/requests/` | Delete a request and all its jobs/assets | ### Search | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | `/api/search?q=` | Search brands, requests, and assets by keyword | ## Image Size Options Use these values for `image_size` in `/api/generate`: | Value | Dimensions | |-------|-----------| | `square_hd` | 1024 x 1024 (default) | | `square` | 512 x 512 | | `portrait_4_3` | 768 x 1024 | | `portrait_16_9` | 576 x 1024 | | `landscape_4_3` | 1024 x 768 | | `landscape_16_9` | 1024 x 576 | Or use `custom_width` and `custom_height` (512-4096, step 8). **Note:** For Gemini (`model: "gemini"`), use aspect ratio values instead: `1:1`, `16:9`, `4:3`, `3:4`, `9:16`. The API handles the mapping automatically when using image_size presets. **Note:** For Nano Banana Pro (`model: "nano-banana-pro"`), the image_size preset is converted to an aspect ratio automatically. You can also pass `model_config: {"resolution": "2K"}` to control output resolution (1K, 2K, or 4K). ## Model Details | Model ID | Name | Provider | Cost | Best For | |----------|------|----------|------|----------| | `seedream-4.5` | Seedream 4.5 | fal.ai | $0.04 | General purpose, cost effective | | `nano-banana-pro` | Nano Banana Pro | fal.ai | $0.15 | Creative work, thinking model, up to 4K | | `flux-dev` | Flux.1 Dev | fal.ai | $0.025 | Fast, affordable, high fidelity | | `recraft-v3` | Recraft V3 | fal.ai | $0.04 | Brand colors, text rendering, SVG | | `ideogram-v3` | Ideogram V3 | fal.ai | $0.06 | Best typography, style presets | | `flux-kontext` | FLUX Kontext Pro | fal.ai | $0.04 | Natural language image editing | | `gemini` | Imagen 4 | Google | $0.04 | High quality, sync response | ### Model-Specific Parameters Pass these via `model_config` in `/api/generate`. > **Output Format:** All image models support `output_format` via `model_config`. Values: `"png"`, `"jpeg"`, or `"webp"` (model-dependent). The saved file extension matches the requested format. If omitted, each model uses its own default (see below). **Seedream 4.5:** ```json {"model_config": {"output_format": "png", "enable_safety_checker": true}} ``` Output format options: `png` (default), `jpeg`, `webp` **Nano Banana Pro:** ```json {"model_config": {"resolution": "2K", "output_format": "png", "safety_tolerance": "4", "enable_web_search": false}} ``` Output format options: `png` (default), `jpeg`, `webp` **Flux Dev:** ```json {"model_config": {"num_inference_steps": 28, "guidance_scale": 3.5, "output_format": "jpeg", "acceleration": "none"}} ``` Output format options: `jpeg` (default), `png` **Recraft V3:** ```json {"model_config": {"style": "realistic_image", "output_format": "png"}} ``` Style options: `realistic_image`, `digital_illustration`, `vector_illustration`. Output format options: `png` (default), `jpeg`, `webp` **Ideogram V3:** ```json {"model_config": {"rendering_speed": "BALANCED", "style_type": "AUTO", "negative_prompt": "", "magic_prompt_option": "AUTO", "output_format": "png"}} ``` Output format options: `png` (default), `jpeg`, `webp` **FLUX Kontext Pro:** ```json {"model_config": {"guidance_scale": 2.5, "output_format": "jpeg"}} ``` Output format options: `jpeg` (default), `png` **Gemini (Imagen 4):** ```json {"model_config": {"output_format": "jpeg"}} ``` Output format options: `jpeg` (default), `png` ## Error Handling - **401 Unauthorized**: Invalid or missing Bearer token / API key ```json {"error": "Unauthorized", "message": "Invalid API key"} ``` - **403 Forbidden**: Insufficient permissions or generation disabled for team - **404 Not Found**: Resource does not exist - **409 Conflict**: A generation is already in progress (regenerate) - **429 Too Many Requests**: Rate limit exceeded (10/min for generate, 120/min for status polling) - **500 Internal Server Error**: Generation failed (check `details` field) ## Agent Instructions 1. **Identity First**: Always call `GET /api/me` first to ensure your token is valid and your account is provisioned. 2. **No Credit System**: EPD does not have a credit-based billing system. There is no need to check credits or balances before generating. If your account is authenticated and you have team access to a brand, you can generate freely. 3. **JSON Mode**: Expect JSON responses from all `/api/*` routes. 4. **No Redirects**: API routes will return 401 errors, not HTML login redirects. 5. **Brand Required**: Always pass `brand_id` when generating images. 6. **Use Image Types**: Call `GET /api/image-types` to discover available templates. Pass `image_type_id` in `/api/generate` to use a template — you only need to provide the subject/product details in `prompt`, the template handles the rest. 7. **Choose Your Model**: Call `GET /api/models` to see all available models. Pass `model` in `/api/generate` to select one. If omitted, defaults to `seedream-4.5`. 8. **Choose Image Size**: Pass `image_size` in `/api/generate` to control output dimensions. If omitted, defaults to `square_hd` (1024x1024). When using an image type template, the template's aspect ratio is used as default. 9. **Gemini Is Sync**: When using `model: "gemini"`, the response is synchronous — no polling needed. The response will already contain the completed image URL. 10. **Use Product Photos**: Call `GET /api/brands//product-images` to get the brand's actual product photos. Each product image is an object with `url`, `name`, and `notes`. Use `name` to identify which product is which, and pass the `url` values in `image_urls` when generating to give the AI model a visual reference of the real product. This dramatically improves output quality for product photography. 11. **Update Product Metadata**: Use `PATCH /api/brands/` with `product_images` to set names and notes on product photos. Each entry should be `{"url": "...", "name": "Product Name", "notes": "optional context"}`. Flat URL strings are also accepted and auto-converted. 12. **Generation Disabled (403)**: If you receive a 403 with a message about generation being disabled, do not retry — contact the team admin. ## Teams & Brand Access New users start with a personal team. To access shared brands: 1. Ask your admin to add your user (`username` from `/api/me`) to their team. 2. Once added, call `/api/brands` to see the shared brands. ## Ecosystem Links - **GFAVIP Wallet**: `https://wallet.gfavip.com/skill.md` - **PowerLobster**: `https://powerlobster.com/skill.md`