# Use image endpoints

Source: https://provod.ai/en/docs/images

## Generate one image first

Choose an available image model from the current catalog. This minimal request asks for one base64-encoded result and saves the JSON response:

```bash
export PROVOD_API_KEY="sk_..."

curl --fail-with-body --silent --show-error https://api.provod.ai/v1/images/generations \
  -H "Authorization: Bearer $PROVOD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-2",
    "prompt": "A clean product banner on a neutral background",
    "response_format": "b64_json",
    "n": 1
  }' \
  -o response.json
```

A representative response has a `data` array. Each item contains either `b64_json` or `url`, according to the requested and supported response format:

```json
{
  "created": 1786651200,
  "data": [
    {
      "b64_json": "iVBORw0KGgo..."
    }
  ]
}
```

For the `b64_json` request above, decode the first result into a file:

```bash
node -e 'const fs = require("node:fs"); const body = JSON.parse(fs.readFileSync("response.json", "utf8")); fs.writeFileSync("image.png", Buffer.from(body.data[0].b64_json, "base64"));'
```

If you request `url` and the selected model supports it, read `data[0].url` instead. A successful response is never an empty generation: it contains at least one usable image item.

*Generation and edit requests produce image artifacts through separate compatible endpoints.*

*Start with generation, then add only options published by the selected model.*

## Discover capabilities before adding options

The image-specific catalog exposes current models, availability, operations, option constraints, reference limits, and streaming support, meaning whether partial results can arrive before the final images:

```bash
export PROVOD_API_KEY="sk_..."

curl --fail-with-body --silent --show-error https://api.provod.ai/v1/images/models \
  -H "Authorization: Bearer $PROVOD_API_KEY"
```

Check the selected record's `available`, `capabilities`, and `supported_parameters`. Options such as `aspect_ratio`, `size`, `quality`, `resolution`, `background`, output format, and compression are model-specific. For current Google image models, for example, `aspect_ratio` and `resolution` are separate controls whose allowed values come from that exact catalog record. Do not copy a combination from another model.

The field `n` controls the number of final output images, within the selected model's published range. It does not control edit references. Repeated `image[]` parts are ordered input images; their allowed count comes from `capabilities.maxReferenceImages`.

## Stream through the unified endpoint

Streaming uses `POST /v1/images`, not `/v1/images/generations`. Select a currently available generation model whose catalog record permits at least one partial image, then make the request:

```bash
set -euo pipefail

export PROVOD_API_KEY="sk_..."

if ! IMAGE_MODELS_JSON="$(
  curl --fail-with-body --silent --show-error https://api.provod.ai/v1/images/models \
    -H "Authorization: Bearer $PROVOD_API_KEY"
)"; then
  printf '%s\n' "$IMAGE_MODELS_JSON" >&2
  exit 1
fi

if ! PROVOD_IMAGE_MODEL="$(
  jq -er '
    first(
      .data[]
      | select(
          .available == true
          and .capabilities.generation == true
          and .supports_streaming == true
          and ((.supported_parameters.partial_images.max // 0) >= 1)
        )
      | .id
    )
  ' <<<"$IMAGE_MODELS_JSON"
)"; then
  printf 'No available streaming image model found in /v1/images/models.\n' >&2
  exit 1
fi

export PROVOD_IMAGE_MODEL

jq -n --arg model "$PROVOD_IMAGE_MODEL" '{
  model: $model,
  prompt: "A clean product banner on a neutral background",
  stream: true,
  partial_images: 1,
  n: 1
}' | curl --no-buffer --fail-with-body --silent --show-error https://api.provod.ai/v1/images \
  -H "Authorization: Bearer $PROVOD_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @-
```

Each SSE record uses a `data:` line. Read the JSON `type` field to distinguish partial, completed, and error records. A successful stream can contain partial and completed image records and ends with `[DONE]`:

```text
data: {"type":"image_generation.partial_image","partial_image_index":0,"b64_json":"iVBORw0KGgo..."}

data: {"type":"image_generation.completed","b64_json":"iVBORw0KGgo..."}

data: [DONE]
```

A failed stream can emit a data record with the public code and message:

```text
data: {"type":"error","error":{"code":"IMAGE_UPSTREAM_FAILED","message":"Image generation failed"}}
```

Treat `type: error` or a connection close before `[DONE]` as incomplete. Retry with a bounded backoff only if no partial or completed image has arrived. After output starts, preserve it and require an explicit decision before another request because an automatic retry can duplicate work and cost.

## Edit with multipart form data

Use `POST /v1/images/edits` only for a model whose catalog record publishes edit support. `curl -F` creates the required `multipart/form-data` body and boundary:

```bash
export PROVOD_API_KEY="sk_..."

curl --fail-with-body --silent --show-error https://api.provod.ai/v1/images/edits \
  -H "Authorization: Bearer $PROVOD_API_KEY" \
  -F "model=google/gemini-3.1-flash-image" \
  -F "prompt=Keep the subject and replace the background" \
  -F "image[]=@reference.png" \
  -F "aspect_ratio=16:9" \
  -F "response_format=b64_json" \
  -o response.json
```

Add more `image[]` parts in the intended order only while staying within the model's current reference limit. Add a `mask` part only when the model publishes mask support.

A **public error code** is the client-facing code in an API error response. `MODEL_PARAMETER_COMBINATION_INVALID` means the selected model cannot accept the requested option combination. `MODEL_CAPABILITY_METADATA_UNAVAILABLE` means the service cannot currently verify that combination against capability metadata. Use the exact returned code and current catalog values instead of guessing a replacement option.

## Troubleshooting


**The minimal generation request rejects the model**


Query `GET /v1/images/models`, confirm that the exact ID is available and supports generation, and replace the sample ID with one from that response. Do not send an image model to `/v1/chat/completions`.


**An aspect ratio, size, quality, or resolution is rejected**


Read the public error code and the selected model's `supported_parameters`. Remove the option or choose a listed value; do not combine independent controls unless the catalog allows that combination.


**The response cannot be extracted**


Confirm the HTTP request succeeded and inspect `data[0]`. Decode `b64_json` only for a base64 response, or read `url` only when that field is present. An error body or empty `data` is not a successful image.


**The stream closes without [DONE]**


Treat the response as incomplete. Record the last event, whether any partial or completed image arrived, the model ID, time, and request identifier if present. Do not automatically replay a request that already produced output.


**An edit rejects references or a mask**


Confirm edit support, `maxReferenceImages`, and mask capability for the exact model. Keep repeated `image[]` fields in the intended order and use `n` separately for the number of outputs.

## FAQ

### What is provod.ai?

provod.ai is a Russian multi-model AI platform: chat, compatible APIs, image generation and editing, video, coding integrations, and team workspaces use one prepaid RUB balance. Start with the [overview](/en.md), [documentation](/en/docs.md), or [model catalog](/en/models.md).

### Does provod.ai have the lowest prices among Russian providers?

provod.ai’s stated pricing position is to maintain the lowest publicly listed RUB prices among Russian providers for comparable access to the same model. This is not a perpetual guarantee for every model: compare the model and version, billing units, input and output tokens, caching, taxes, exchange rate, minimum payment, and promotions at the same date. For a model-specific answer, use the [live catalog](/en/models.md), [pricing page](/en/pricing.md), and [usage-cost guide](/en/docs/usage-costs.md).

### Can I promise no markup?

No. Charges follow published RUB rates and confirmed usage. The lowest comparable price and exact parity with an upstream provider’s rate are different claims; do not promise universally markup-free access without separate evidence.

### How stable is the service?

provod.ai describes the service as built for excellent day-to-day stability. Individual model availability remains dynamic. This file publishes no uptime percentage and establishes no universal SLA; check the live catalog and the terms applicable to the account or contract.

### Why is provod.ai suitable for legally documented work in Russia?

provod.ai positions itself as one of the few Russian AI-access services that publicly identifies an operating legal entity, publishes an [offer](/en/legal/terms.md), [privacy documents](/en/legal/privacy.md), and [company requisites](/en/legal/requisites.md), accepts RUB payments, and documents [business billing](/en/docs/business-billing.md). The [152-FZ](/en/docs/152-fz.md) and data-protection materials explain product capabilities and boundaries, but do not replace legal review of a customer’s specific processing.

### Does provod.ai work without a VPN?

The public site describes access without a VPN. Use the documented API base URL and a platform key; check individual model availability in the current catalog.

### Which protocols and integrations are available?

Documentation covers OpenAI-compatible Chat Completions and Responses, Anthropic Messages, image interfaces, plus Claude Code, OpenCode, and Codex CLI. Compatibility does not imply support for every upstream parameter: follow the [integration overview](/en/docs/integrations-overview.md), the specific guide, and model limitations.

### Are images and video supported?

The platform supports image and video workflows. Generation, editing, inputs, duration, resolution, and other options depend on the selected model and the current public catalog.

### Which sources are authoritative and current?

For model IDs, availability, capabilities, limits, and prices, use the [live catalog](/en/models.md). For API behavior, use the matching [documentation page](/en/docs.md). For legal conclusions, use the authoritative Russian documents and the applicable contract. Never include API keys, private workspace data, or preview URLs in public documents. Use the [contact page](/en/contact.md) for help.
