REST API

anystudio API documentation

Upload files, create image generations, poll status, receive customer webhooks, and keep retries idempotent with one stable REST API.

Base URL

https://anystudio.ru/v1

Authentication

Authorization: Bearer <key>

Upload limit

20 MB

curl -X POST https://anystudio.ru/v1/generations \
  -H "Authorization: Bearer $ANYSTUDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: client-job-123" \
  -d '{
    "model": "nano-banana-pro-2k",
    "mode": "txt2img",
    "prompt": "A cinematic portrait",
    "parameters": { "aspect_ratio": "1:1", "output_format": "png" }
  }'

Authentication

API requests use a personal API key in the Bearer token header. Store keys server-side only. A regenerated key revokes the previous active key.

Authorization: Bearer any_live_...

Endpoints

MethodPathPurpose
GET/v1/modelsList active models and prices.
POST/v1/generationsCreate an image generation.
GET/v1/generations/{id}Get one generation with outputs and timestamps.
GET/v1/generationsList your generations.
POST/v1/generations/{id}/retryCreate a new generation from previous parameters.
POST/v1/filesUpload an input file up to 20 MB.
GET/v1/files/{id}Read a stored file through an anystudio URL.
POST/v1/webhooks/testSend a test customer webhook payload.

List models

Returns active image models, supported modes, compatible parameters, and the user-facing USD price.

curl -H "Authorization: Bearer $ANYSTUDIO_API_KEY" \
  https://anystudio.ru/v1/models

Create a generation

The request body is unified across txt2img, img2img, edit, and upscale. If the account balance is insufficient, anystudio returns HTTP 402 before a job is created.

{
  "model": "nano-banana-pro-2k",
  "mode": "txt2img",
  "prompt": "A cinematic portrait...",
  "input_images": ["https://example.com/input.jpg"],
  "parameters": {
    "aspect_ratio": "1:1",
    "output_format": "png",
    "quality": "standard"
  },
  "webhook_url": "https://customer.com/webhooks/anystudio",
  "metadata": { "external_id": "client-job-123" }
}
{
  "id": "gen_xxx",
  "status": "queued",
  "model": "nano-banana-pro-2k",
  "mode": "txt2img",
  "price_usd": "0.0525",
  "created_at": "2026-05-29T12:00:00Z"
}

Upload files

Use uploaded file URLs in input_images. Returned file URLs are always anystudio URLs.

curl -X POST https://anystudio.ru/v1/files \
  -H "Authorization: Bearer $ANYSTUDIO_API_KEY" \
  -F "file=@input.png"

Polling and statuses

Poll every 2 to 3 seconds while a generation is queued or processing. Terminal statuses are succeeded, failed, cancelled, refunded.

curl -H "Authorization: Bearer $ANYSTUDIO_API_KEY" \
  https://anystudio.ru/v1/generations/gen_xxx

Customer webhooks

Pass webhook_url when creating a generation to receive a terminal status payload. Your endpoint should return a 2xx status.

{
  "id": "gen_xxx",
  "status": "succeeded",
  "model": "nano-banana-pro-2k",
  "mode": "txt2img",
  "outputs": [
    {
      "type": "image",
      "url": "https://anystudio.ru/v1/files/file_xxx",
      "width": 2048,
      "height": 2048,
      "format": "png"
    }
  ],
  "metadata": { "external_id": "client-job-123" }
}

Idempotency

Send an Idempotency-Key header when retrying a create request from your system. Reusing the same key for the same account returns the original generation and prevents duplicate charging.

Idempotency-Key: client-job-123

Examples

JavaScript

const response = await fetch('https://anystudio.ru/v1/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ANYSTUDIO_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'client-job-123'
  },
  body: JSON.stringify({
    model: 'nano-banana-pro-2k',
    mode: 'txt2img',
    prompt: 'Clean product photo on a neutral background'
  })
})

const generation = await response.json()
Python

import os
import requests

generation = requests.post(
    "https://anystudio.ru/v1/generations",
    headers={
        "Authorization": f"Bearer {os.environ['ANYSTUDIO_API_KEY']}",
        "Idempotency-Key": "client-job-123",
    },
    json={
        "model": "nano-banana",
        "mode": "txt2img",
        "prompt": "Modern kitchen interior"
    },
    timeout=30,
).json()
Go

body := strings.NewReader(`{
  "model":"nano-banana",
  "mode":"txt2img",
  "prompt":"Editorial portrait"
}`)

req, err := http.NewRequest("POST", "https://anystudio.ru/v1/generations", body)
if err != nil {
  return err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("ANYSTUDIO_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "client-job-123")
Polling loop

const terminal = new Set(['succeeded', 'failed', 'cancelled', 'refunded'])

while (!terminal.has(generation.status)) {
  await new Promise(resolve => setTimeout(resolve, 2500))
  generation = await fetch(`https://anystudio.ru/v1/generations/${generation.id}`, {
    headers: { Authorization: `Bearer ${process.env.ANYSTUDIO_API_KEY}` }
  }).then(response => response.json())
}

Errors

400 invalid_request

The request body, mode, model, parameters, or upload payload is invalid.

401 unauthorized

The API key is missing, malformed, revoked, or unknown.

402 insufficient_balance

Insufficient balance. Please top up your account.

404 not_found

The requested generation or file was not found for this account.

413 file_too_large

Uploaded files must be 20 MB or smaller.

500 internal_error

The request failed. Public errors never expose internal provider details.