API Reference

All endpoints accept and return JSON. Base path: /api/v1.

Download .md

Overview

A small REST API for galleries: artwork descriptions, artist bios, in-room mockup stills and short in-room videos. All endpoints accept and return JSON.

Base URL: https://ai.fineartfinder.co.uk/api/v1

Every successful call deducts tokens from the account that owns the API key. Pricing per endpoint is listed below.

Authentication

Every request requires a bearer token:

Authorization: Bearer aig_xxx

Your key is shown on the API Key page after sign-in. The key is revealed on first view; afterwards it is masked and can be rotated (the old key stops working immediately).

Accounts have per-minute and per-day rate limits (defaults 100/min, 10,000/day) configurable by admins. Suspended accounts and IP-restricted keys return 403.

POST /connection

Returns the current state of your account. Does not consume tokens.

{
  "account_id": "uuid",
  "account_name": "...",
  "tokens": 50,
  "total_tokens_used": 0,
  "active": true
}

POST /generate

Generates a structured artwork description JSON. Cost: 1 token.

Request:

{
  "input_text": "Title: ... Artist: ... Medium: ...",
  "base64_of_image": "iVBORw0KG..."
}

Response shape depends on the account's prompt_profile (FAF profile shown):

{
  "title": "...",
  "intro": "...",
  "description": "...",
  "artist_bio": "...",
  "image_desc": "...",
  "meta_desc": "...",
  "meta_title": "...",
  "keywords": ["..."],
  "colours": ["..."],
  "image_prompt": "..."
}

Powered by google/gemini-3-flash-preview.

POST /generate-artist-bio

Writes a structured artist bio JSON. Cost: 1 token.

{ "artist": "Jane Doe", "current_bio": "" }
{
  "intro": "...",
  "short_desc": "...",
  "artist_bio": "...",
  "keywords": ["..."],
  "meta_desc": "...",
  "meta_title": "...",
  "key_facts": [{ "title": "...", "fact": "..." }]
}

POST /generate-image

Creates a photorealistic in-room mockup PNG of the artwork in a described or uploaded scene. Cost: 5 tokens (quality: "standard", default) or 15 tokens (quality: "pro" — slower, best scale & frame fidelity).

Request — describe a scene:

{
  "scene_source": "describe",
  "scene": "A bright modern living room with oak floors...",
  "dimensions": "80cm x 60cm",
  "position": "above a grey sofa",
  "artwork_type": "framed",          // or "sculpture"
  "base64_of_image": "...",          // the artwork
  "extra_reference_images_base64": ["...", "..."],  // optional extra views
  "artwork_context": "Oil on canvas, deep red palette",  // optional
  "quality": "standard"              // or "pro" (15 tokens)
}

Request — upload a real room photo:

{
  "scene_source": "upload",
  "scene_image_base64": "...",
  "scene_scale_reference": "the sofa is ~200cm wide",
  "dimensions": "80cm x 60cm",
  "position": "centred on the back wall",
  "base64_of_image": "...",
  "quality": "pro"
}

Iterate on a previous render:

{
  "previous_image_base64": "...",
  "tweak_instruction": "warmer evening lighting, slightly larger frame",
  "base64_of_image": "..."
}

Response:

{
  "image_base64": "iVBORw0KG...",
  "mime_type": "image/png",
  "tokens_used": 5,
  "quality": "standard",
  "model": "google/gemini-3.1-flash-image"
}

POST /generate-scene-video

Generates a short, locked in-room video of the artwork. The first frame is composed exactly like /generate-image and is then animated with a chosen camera move via Google Veo. Returns a job_id to poll.

Cost: round(base × duration / 4) + 5 tokens, where base = 25 for fast and 60 for standard/preview. The +5 is the locked first-frame composition.

Request:

{
  "scene_source": "describe",          // or "upload"
  "scene": "A minimal gallery wall...",
  "dimensions": "80cm x 60cm",
  "position": "centred at eye level",
  "base64_of_image": "...",            // the artwork
  "artwork_type": "framed",            // or "sculpture"
  "camera_move": "slow_push_in",       // see list below
  "mood_preset": "match_first_frame",
  "duration": 4,                       // 4 | 6 | 8 seconds
  "aspect_ratio": "16:9",              // or "9:16"
  "resolution": "720p",                // or "1080p"
  "quality": "fast"                    // "fast" | "standard" | "preview"
}

Camera moves (framed): locked_off, breathing, slow_push_in, slow_pull_back, pan_left_to_right, pan_right_to_left. Sculpture-only: quarter_orbit_left, quarter_orbit_right, tilt_up.

Response (202):

{
  "job_id": "uuid",
  "status": "pending",
  "first_frame_base64": "...",
  "first_frame_mime_type": "image/png"
}

GET /video-status/:job_id

Polls a video job. Tokens are only deducted once when the job completes successfully.

While running:

{ "status": "pending", "job_id": "uuid", "tokens_used": 35 }

On completion:

{
  "status": "complete",
  "job_id": "uuid",
  "video_base64": "...",
  "mime_type": "video/mp4",
  "tokens_used": 35
}

On failure:

{ "status": "failed", "job_id": "uuid", "error": "..." }

Errors

  • 400 — invalid request body
  • 401 — missing or invalid API key
  • 402 — out of tokens (top up to continue)
  • 403 — account suspended or IP not allowed
  • 429 — rate limit exceeded (per-minute or per-day)
  • 500 / 502 — upstream AI failure (visible on your Logs page)

Logs & usage

Every call is logged with endpoint, status, latency, token cost and the full request/response payload. Use the Logs page to search and filter; click any entry for the full detail panel. The Dashboard shows layered usage charts (calls, tokens, errors) for the last 14 days.