{
  "name": "app-image",
  "title": "App API - Image Generation Service",
  "description": "Image generation service for deployed apps: OpenAI, BFL/Flux, and Gemini/Nano Banana providers, aspect ratios, resolution tiers",
  "guid": "sk_plat_aimg",
  "category": "App services",
  "requiredTools": [
    "project_settings"
  ],
  "content": "# App API - Image Generation Service\n\nImage generation is available for every project with no setup needed (owner_pays billing by default).\n\nUse `project_settings` to customize (optional):\n- Switch billing mode (owner_pays ↔ user_pays)\n- Restrict allowed providers\n- Set default provider/model\n\n## Providers & Models\n- **OpenAI**: `gpt-image-1`\n- **BFL/Flux**: `flux-2-pro, flux-2-flex, flux-2-max, flux-dev`\n- **Gemini/Nano Banana**: `gemini-2.5-flash-image, gemini-3.1-flash-image-preview, gemini-3-pro-image-preview`\n\n## Endpoints\n- `GET /api/<PROJECT_GUID>/services/image/models` - list available providers and models\n- `POST /api/<PROJECT_GUID>/services/image` - generate an image\n\n## Request Format (POST /image)\n```json\n{\n  \"prompt\": \"A sunset over mountains\",\n  \"provider\": \"openai\",\n  \"model\": \"gpt-image-1\",\n  \"size\": \"1024x1024\",\n  \"quality\": \"auto\"\n}\n```\n\nFields:\n- `prompt` (required): Image description, max 4,000 chars\n- `provider`: \"openai\", \"bfl\", or \"gemini\" (default: bfl)\n- `model`: Model ID (default: provider's default)\n- `size`: \"WxH\" format (default: 1024x1024). OpenAI sizes: 1024x1024, 1024x1536, 1536x1024. BFL: any size (rounded to 32px). Gemini: mapped to nearest resolution tier\n- `quality`: OpenAI gpt-image-1: low/medium/high/auto\n- `aspect_ratio`: Gemini only. Aspect ratio: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9\n- `image_size`: Gemini only. Resolution tier: 512, 1K, 2K, 4K (default: 1K)\n\n## Response Format\n```json\n{\n  \"url\": \"https://media.gipity.ai/med_abc12345.png\",\n  \"content_type\": \"image/png\",\n  \"revised_prompt\": \"...\",\n  \"model\": \"gpt-image-1\",\n  \"provider\": \"openai\",\n  \"credits_used\": 50\n}\n```\n\nThe `url` is a permanent public CDN URL. No auth needed to fetch it.\n\n## Client Code Example\n\n**IMPORTANT:** The token endpoint is on the API server. Use `https://a.gipity.ai/api/token` (POST).\n\n```js\n// 1. Get app token\nconst tokenRes = await fetch('https://a.gipity.ai/api/token', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ app: '<PROJECT_GUID>' })\n});\nconst { data: { token } } = await tokenRes.json();\n\n// 2. Generate image\nconst res = await fetch('https://a.gipity.ai/api/<PROJECT_GUID>/services/image', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json', 'X-App-Token': token },\n  body: JSON.stringify({ prompt: 'A cat wearing a top hat' })\n});\nconst data = await res.json();\n// data.url → \"https://media.gipity.ai/med_abc12345.png\"\n\n// 3. Display\nconst img = document.createElement('img');\nimg.src = data.url;\ndocument.body.appendChild(img);\n```\n\n## Limits\n- **Rate limit**: 600 requests per 5-minute window (per IP)\n- **Max prompt length**: 4,000 chars\n- **Timeout**: 120s\n- Standard `RateLimit-*` headers included in responses"
}
