> ## Documentation Index
> Fetch the complete documentation index at: https://docs.naga.ac/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit an image

> Edits uploaded images against a text prompt and charges the account for what it counted. Requires an API key. `/v1/images/generations` draws from a prompt alone.



## OpenAPI

````yaml /openapi/naga-api.json post /v1/images/edits
openapi: 3.1.0
info:
  title: NagaAI API
  description: >-
    NagaAI routes inference requests to a pool of upstream providers behind one
    endpoint. Requests speak the OpenAI or the Anthropic dialect, and the
    gateway selects a provider that serves the requested model. Two credentials
    exist and they are not interchangeable. An API key reaches models. A
    provisioning key manages the account: its keys, its balance, and its usage.
    Each operation declares which one it accepts. NagaAI charges the account in
    credits for the tokens a request consumes, at the published price of the
    model that served it. One credit costs one US dollar.
  termsOfService: https://naga.ac/legal/terms
  contact:
    name: NagaAI
    url: https://naga.ac
  version: '2026-03-31'
  summary: Unified AI API with OpenAI and Anthropic compatibility layers.
servers:
  - url: https://api.naga.ac
    description: Production
  - url: http://localhost:8500
    description: Local development
security: []
tags:
  - name: Chat Completions
    description: >-
      The OpenAI Chat Completions dialect, with streaming, tools and multimodal
      input.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/chat
      description: The OpenAI reference for this dialect.
  - name: Messages
    description: >-
      The Anthropic Messages dialect, as Claude-style clients and agents speak
      it.
    externalDocs:
      url: https://docs.anthropic.com/en/api/messages
      description: The Anthropic reference for this dialect.
  - name: Responses
    description: >-
      The OpenAI Responses dialect, with structured input, tools and streamed
      output items.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/responses
      description: The OpenAI reference for this dialect.
  - name: Embeddings
    description: Vector embeddings for search, retrieval, clustering and ranking.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/embeddings
      description: The OpenAI reference for this route.
  - name: Images
    description: Image generation and editing with multimodal models.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/images
      description: The OpenAI reference for these routes.
  - name: Audio
    description: Speech from text, and text from uploaded audio.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/audio
      description: The OpenAI reference for these routes.
  - name: Moderations
    description: Safety classification of text and image input.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/moderations
      description: The OpenAI reference for this route.
  - name: Models
    description: The catalog of models, their capabilities and their prices.
    externalDocs:
      url: https://platform.openai.com/docs/api-reference/models
      description: The OpenAI reference for this route.
  - name: Startups
    description: The organizations whose models the catalog carries.
    externalDocs:
      url: https://docs.naga.ac
      description: The NagaAI documentation site.
  - name: Account
    description: The account's balance and its usage, behind a provisioning key.
    externalDocs:
      url: https://docs.naga.ac
      description: The NagaAI documentation site.
  - name: API Keys
    description: The account's API keys, behind a provisioning key.
    externalDocs:
      url: https://docs.naga.ac
      description: The NagaAI documentation site.
paths:
  /v1/images/edits:
    post:
      tags:
        - Images
      summary: Edit an image
      description: >-
        Edits uploaded images against a text prompt and charges the account for
        what it counted. Requires an API key. `/v1/images/generations` draws
        from a prompt alone.
      operationId: create_image_edit
      requestBody:
        description: >-
          The images to edit, one per part named `image`, beside the prompt to
          edit them against and the fields `POST /v1/images/generations` takes
          in JSON.
        content:
          multipart/form-data:
            schema:
              type: object
              description: >-
                The `multipart/form-data` body of `POST /v1/images/edits` — the
                images to edit, the prompt to edit them against, and the fields
                `POST /v1/images/generations` takes in JSON.
              required:
                - model
                - prompt
                - image
              properties:
                model:
                  type: string
                  description: The model to edit with, named by its id or alias.
                prompt:
                  type: string
                  description: What to change, in words. One to 32000 characters.
                image:
                  type: array
                  items:
                    type: string
                    description: One uploaded image, as the bytes of the file itself.
                    contentMediaType: application/octet-stream
                  description: >-
                    The images to edit, one per part named `image`; `image[]`
                    merges into the same list.
                background:
                  type:
                    - string
                    - 'null'
                  description: >-
                    The provider's background knob, passed through unchecked. A
                    provider without one drops it.
                mask:
                  type:
                    - string
                    - 'null'
                  description: >-
                    A single image whose transparent area marks what the model
                    may repaint.
                  contentMediaType: application/octet-stream
                'n':
                  type:
                    - integer
                    - 'null'
                  format: int64
                  description: >-
                    How many images to ask for. Absent means one; a value above
                    what the model declares draws a refusal.
                quality:
                  type:
                    - string
                    - 'null'
                  description: >-
                    The provider's quality knob, passed through unchecked. A
                    provider without one drops it.
                response_format:
                  oneOf:
                    - allOf:
                        - $ref: '#/components/schemas/ImageResponseFormat'
                      description: >-
                        Whether each image comes back as a link (`url`) or as
                        inline base64 (`b64_json`).
                  default: url
                size:
                  type:
                    - string
                    - 'null'
                  description: >-
                    The requested image size, written `{width}x{height}`; any
                    other shape draws a refusal.
            examples:
              basic:
                summary: Edit one uploaded image
                value:
                  model: gpt-image-1
                  prompt: Put a red scarf on the fox
                  image:
                    - fox.png
        required: true
      responses:
        '200':
          description: >-
            The edited images, in the same body `POST /v1/images/generations`
            answers with.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImagesResponse'
              examples:
                basic:
                  summary: The edited image, as a link
                  value:
                    created: 1774000000
                    data:
                      - url: https://cdn.naga.ac/images/1d7e8b02.png
                    usage:
                      input_tokens: 274
                      output_tokens: 1024
                      total_tokens: 1298
          x-retry-safe: false
        '400':
          description: >-
            The request is malformed: a field failed its constraint, the body is
            not valid JSON, or the model name is unknown.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: false
        '401':
          description: >-
            The API key is missing, malformed, disabled, or does not belong to
            an account that may call this route.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                invalid-api-key:
                  summary: 401 — the key is not one this gateway serves
                  value:
                    error:
                      type: invalid_api_key
                      message: >-
                        The provided API key is invalid. Please ensure your API
                        key is correct and active. You can find more information
                        about obtaining a key on our website: https://naga.ac If
                        you just created this key, wait a few minutes and try
                        again.
          x-retry-safe: false
        '402':
          description: The account has run out of credits. Top up the balance and retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                insufficient-credits:
                  summary: 402 — the account has no credits left
                  value:
                    error:
                      type: insufficient_quota
                      message: >-
                        More credits required to process this request. Visit
                        https://naga.ac/dashboard/credits to add credits.
          x-retry-safe: false
        '403':
          description: >-
            The account may not use this model, or the content was blocked by
            the moderation policy.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: false
        '408':
          description: >-
            The request body did not finish arriving within 15 minutes, or
            stalled for 60 seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: true
        '410':
          description: The model is deprecated and no longer served. Pick a current one.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: false
        '413':
          description: The request body is larger than the 32 MiB this gateway accepts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: false
        '422':
          description: >-
            The request was understood but its usage could not be metered, so it
            was not served.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: false
        '429':
          description: >-
            The account exceeded its rate limit. `Retry-After` carries the wait
            in seconds.
          headers:
            Retry-After:
              schema:
                type: string
              description: How long to wait before retrying, in seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                rate-limited:
                  summary: 429 — too many requests; `Retry-After` carries the wait
                  value:
                    error:
                      type: rate_limit_exceeded
                      message: Rate limit reached. Please try again in 3s.
          x-retry-safe: true
        '500':
          description: >-
            The gateway failed for a reason of its own. Report it — this status
            marks NagaAI's own bugs, never an upstream verdict.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: true
        '503':
          description: >-
            No upstream is available, or the gateway is shedding load.
            `Retry-After` carries the suggested wait.
          headers:
            Retry-After:
              schema:
                type: string
              description: How long to wait before retrying, in seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          x-retry-safe: true
      security:
        - bearerAuth: []
        - xApiKeyAuth: []
      externalDocs:
        url: https://platform.openai.com/docs/api-reference/images
        description: The OpenAI reference for these routes.
      x-codeSamples:
        - lang: bash
          label: curl
          source: |-
            curl https://api.naga.ac/v1/images/edits \
              -H "Authorization: Bearer $NAGA_API_KEY" \
              -F 'model=gpt-image-1' \
              -F 'prompt=Put a red scarf on the fox' \
              -F 'image=@fox.png'
        - lang: python
          label: openai-python
          source: |
            import os
            from openai import OpenAI

            client = OpenAI(
                api_key=os.environ["NAGA_API_KEY"],
                base_url="https://api.naga.ac/v1",
            )

            result = client.images.edit(
                model="gpt-image-1",
                prompt="Put a red scarf on the fox",
                image=[open("fox.png", "rb")],
            )
            print(result)
        - lang: javascript
          label: openai-node
          source: |
            import fs from "node:fs";
            import OpenAI from "openai";

            const client = new OpenAI({
              apiKey: process.env.NAGA_API_KEY,
              baseURL: "https://api.naga.ac/v1",
            });

            const result = await client.images.edit({
              model: "gpt-image-1",
              prompt: "Put a red scarf on the fox",
              image: [fs.createReadStream("fox.png")],
            });
            console.log(result);
components:
  schemas:
    ImageResponseFormat:
      type: string
      description: How the produced images are handed back.
      enum:
        - url
        - b64_json
    ImagesResponse:
      allOf:
        - type: object
        - type: object
          required:
            - created
            - data
            - usage
          properties:
            created:
              type: integer
              format: int64
              description: >-
                When the gateway rendered this body, in seconds since the Unix
                epoch.
            data:
              type: array
              items:
                $ref: '#/components/schemas/ImageDataResponse'
              description: The produced images, in the order the provider returned them.
            usage:
              allOf:
                - $ref: '#/components/schemas/ImageUsageResponse'
              description: >-
                What the gateway metered, filling in where the provider reported
                nothing.
      description: The body both image routes answer with.
    ErrorEnvelope:
      type: object
      description: >-
        `{"error": {…}}` — the body of every non-2xx answer outside
        `/v1/messages`.
      required:
        - error
      properties:
        error:
          allOf:
            - $ref: '#/components/schemas/ErrorBody'
          description: The failure itself, and the envelope's only member.
    ImageDataResponse:
      allOf:
        - type: object
        - type: object
          properties:
            url:
              type:
                - string
                - 'null'
              description: >-
                A link to the image, hosted by NagaAI rather than by the
                provider. No expiry is set.
            b64_json:
              type:
                - string
                - 'null'
              description: >-
                The image bytes themselves, standard base64. This branch stores
                nothing.
      description: One produced image; exactly one of the two fields is filled.
    ImageUsageResponse:
      allOf:
        - type: object
        - type: object
          required:
            - output_tokens
            - total_tokens
          properties:
            input_tokens:
              type:
                - integer
                - 'null'
              format: int64
              description: >-
                Input tokens charged for. Zero on a model that prices no input
                text token.
            output_tokens:
              type: integer
              format: int64
              description: >-
                Output tokens charged for the produced images, 2048 apiece where
                the provider counted none.
            total_tokens:
              type: integer
              format: int64
              description: The sum of `input_tokens` and `output_tokens`.
      description: What the gateway metered, in its own numbers.
    ErrorBody:
      type: object
      description: 'The `error` member: what went wrong, in the caller''s terms.'
      required:
        - type
        - message
      properties:
        type:
          type: string
          description: >-
            The class of the failure; a provider's own class can reach you
            unchanged.
          examples:
            - invalid_request_error
            - authentication_required
            - invalid_api_key
            - invalid_provisioning_key
            - invalid_session_token
            - disabled_api_key
            - disabled_provisioning_key
            - expired_api_key
            - credit_limit_exceeded
            - rate_limit_exceeded
            - model_deprecated
            - inappropriate_content
            - billing_metering_incomplete
            - billing_request_id_invalid
            - billing_writer_missing
            - server_error
        message:
          type: string
          description: The human-readable sentence shown to the caller.
        code:
          type:
            - string
            - 'null'
          description: The finer-grained code, when the failure has one.
        param:
          type:
            - string
            - 'null'
          description: The request field the failure is about, when it is about one.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An account API key. Send it as `Authorization: Bearer <key>`.'
    xApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        An account API key. Send it as `x-api-key: <key>`, the header
        Anthropic-style clients use.

````