{
  "openapi": "3.1.0",
  "info": {
    "title": "PixelForge AI API",
    "version": "1.0.0",
    "description": "Public, credit-metered REST API for generating AI images and browsing the free PixelForge stock library. Designed agentic-first: every endpoint returns a consistent JSON envelope and authenticates with a single bearer key. Generation costs credits (free daily allowance applies first); browsing and metadata are free. All gallery images are free to use under the PixelForge Free License (https://pixelforgeai.dev/license).",
    "contact": {
      "name": "PixelForge AI",
      "url": "https://pixelforgeai.dev"
    },
    "license": {
      "name": "PixelForge Free License",
      "url": "https://pixelforgeai.dev/license"
    }
  },
  "servers": [
    {
      "url": "https://pixelforgeai.dev/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Images",
      "description": "Generate and retrieve images."
    },
    {
      "name": "Discovery",
      "description": "Browse and search the stock library."
    },
    {
      "name": "Account",
      "description": "Models, credits, and key owner info."
    }
  ],
  "paths": {
    "/images/generate": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "generateImage",
        "summary": "Generate an image",
        "description": "Synchronously generate one image from a text prompt. Consumes the free daily allowance first, then credits. Premium models require an active Pro or Studio plan on the key owner's account. Typical latency is several seconds while the image is rendered and stored; the call returns when the image URL is ready.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateRequest"
              },
              "example": {
                "prompt": "A serene Swiss mountain lake at golden hour, ultra detailed",
                "model": "google/gemini-3.1-flash-image-preview",
                "aspectRatio": "16:9",
                "size": "2K"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image generated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits / daily allowance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Model requires a higher plan tier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request (e.g. missing prompt).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/images/{idOrSlug}": {
      "get": {
        "tags": [
          "Images"
        ],
        "operationId": "getImage",
        "summary": "Get image metadata",
        "description": "Retrieve full metadata for a single public (approved) image by id or SEO slug. Requires an API key for consistent metering but charges no credits.",
        "parameters": [
          {
            "name": "idOrSlug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Image id or SEO detail-page slug."
          }
        ],
        "responses": {
          "200": {
            "description": "Image metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Image not found or not public.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/images": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "listImages",
        "summary": "Browse / search images",
        "description": "List public images. Pass `q` for a relevance-ranked full-text search over titles, prompts, keywords, and tags; or filter by category, tag, or a prefixed SEO filter (e.g. style:watercolor). When `q` is present results are relevance-ordered (the `sort` parameter is ignored). Sort by recent or popular for plain browsing; paginate with an opaque cursor. No credits charged.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Full-text search query (>= 2 chars). Relevance-ranked across titles, prompts, keywords, and tags; overrides `sort` when present."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug."
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Tag slug."
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prefixed SEO filter, e.g. \"style:watercolor\"."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "recent",
                "popular"
              ]
            },
            "description": "Sort order (default recent)."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque pagination cursor from a previous response."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 24
            },
            "description": "Page size (max 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of images.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "listModels",
        "summary": "List available models",
        "description": "List active image models with their tier, credit cost, and capabilities. No credits charged.",
        "responses": {
          "200": {
            "description": "Active models.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getMe",
        "summary": "Get key owner info",
        "description": "Return the key owner's name, credit balance, today's free daily allowance, and plan tier. No credits charged.",
        "responses": {
          "200": {
            "description": "Key owner info.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Send your API key as a bearer token: `Authorization: Bearer pf_live_...`. Create and revoke keys in your dashboard."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "unauthorized",
                  "rate_limited",
                  "insufficient_credits",
                  "invalid_request",
                  "not_found",
                  "forbidden",
                  "server_error"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "GenerateRequest": {
        "type": "object",
        "required": [
          "prompt"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "description": "Text prompt to render."
          },
          "model": {
            "type": "string",
            "description": "Model id from /models. Defaults to the free tier model."
          },
          "aspectRatio": {
            "type": "string",
            "enum": [
              "1:1",
              "16:9",
              "4:3",
              "3:4",
              "9:16"
            ]
          },
          "size": {
            "type": "string",
            "enum": [
              "0.5K",
              "1K",
              "2K",
              "4K"
            ]
          }
        }
      },
      "GenerateResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "example": "completed"
              },
              "imageUrl": {
                "type": "string",
                "format": "uri"
              },
              "model": {
                "type": "string"
              },
              "aspectRatio": {
                "type": "string"
              },
              "creditsCharged": {
                "type": "number"
              },
              "creditsRemaining": {
                "type": "number"
              }
            }
          }
        }
      },
      "ImageResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Image"
          }
        }
      },
      "ImageListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ImageLean"
                }
              },
              "nextCursor": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "ImageLean": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "webDownloadUrl": {
            "type": "string",
            "format": "uri"
          },
          "prompt": {
            "type": [
              "string",
              "null"
            ]
          },
          "model": {
            "type": "string"
          },
          "aspectRatio": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "number"
          },
          "stats": {
            "$ref": "#/components/schemas/Stats"
          }
        }
      },
      "Image": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "webDownloadUrl": {
            "type": "string",
            "format": "uri"
          },
          "prompt": {
            "type": [
              "string",
              "null"
            ]
          },
          "model": {
            "type": "string"
          },
          "aspectRatio": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "number"
          },
          "seo": {
            "type": "object",
            "properties": {
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "keywords": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "categories": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "path": {
                "type": "string"
              },
              "summary": {
                "type": "string"
              }
            }
          },
          "stats": {
            "$ref": "#/components/schemas/Stats"
          }
        }
      },
      "Stats": {
        "type": "object",
        "properties": {
          "views": {
            "type": "number"
          },
          "downloads": {
            "type": "number"
          },
          "upvotes": {
            "type": "number"
          }
        }
      },
      "ModelListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Model"
                }
              }
            }
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "premium"
            ]
          },
          "creditCost": {
            "type": "number"
          },
          "capabilities": {
            "type": "object",
            "properties": {
              "aspectRatios": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "sizes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "maxReferenceImages": {
                "type": "number"
              }
            }
          }
        }
      },
      "MeResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "credits": {
                "type": "number"
              },
              "dailyAllowance": {
                "type": "object",
                "properties": {
                  "limit": {
                    "type": "number"
                  },
                  "used": {
                    "type": "number"
                  },
                  "remaining": {
                    "type": "number"
                  },
                  "resetsAt": {
                    "type": "number"
                  }
                }
              },
              "planTier": {
                "type": "string",
                "enum": [
                  "free",
                  "creator",
                  "pro",
                  "studio"
                ]
              }
            }
          }
        }
      }
    }
  }
}