Vanguard AI

Images

Create pictures from a description, then edit, vary and enlarge them. Everything is priced per picture and drawn asynchronously: a request answers 202 at once with a generation in rendering, and you poll it until its pictures are drawn — usually 10–40 seconds.

QualitySizeCredits per picture
standardabout 1K (e.g. 1024×1024, 1344×768)10
pro-2kabout 2K30
pro-4kabout 4K (e.g. 6336×2688 at 21:9)50

These are the current prices; read them live from GET /v1/images/options. A request is reserved in full when you send it and charged only for the pictures that are drawn — a picture that is refused, times out or is interrupted is refunded.

Authorization

Every endpoint here needs the images scope. A key without it gets 403 SCOPE_FORBIDDEN; add the scope on the API keys page.

Options

GET /v1/images/options API key

The shapes, styles and qualities on offer, the live prices and the limits. available: false on a Pro quality means it cannot be drawn right now (Standard still works).

200
{
  "status": "success",
  "aspectRatios": ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"],
  "styles": ["none", "photo", "cinematic", "product", "portrait", "illustration", "anime",
             "watercolor", "oil-painting", "3d-render", "flat-vector", "line-art", "pixel-art"],
  "varieties": ["low", "normal", "high"],
  "qualities": [
    { "id": "standard", "credits": 10, "size": "1K", "available": true },
    { "id": "pro-2k", "credits": 30, "size": "2K", "available": true },
    { "id": "pro-4k", "credits": 50, "size": "4K", "available": true }
  ],
  "presets": [
    { "id": "id-photo", "outfits": ["suit-tie", "suit", "blazer", "own"], "backgrounds": ["white", "blue", "grey"],
      "sources": ["auto", "photo"], "aspectRatio": "3:4",
      "qualities": [{ "id": "standard", "available": true }, { "id": "pro-2k", "available": true }, { "id": "pro-4k", "available": true }] }
  ],
  "enhance": { "credits": 0, "perMinute": 10, "perDay": 200 },
  "limits": { "maxCount": 4, "maxReferences": 4, "maxInlineReferenceBytes": 7340032,
              "maxPromptChars": 4000, "maxNegativeChars": 1000, "maxActivePerOrg": 3 }
}

Create pictures

POST /v1/images/generations API key

JSON body

prompt *
string
What to draw, up to 4,000 characters. Lao, Thai and English all work.
negativePrompt
string
What to leave out, up to 1,000 characters, e.g. "people, text, blur".
aspectRatio
string
One of 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9. Default: 1:1.
count
integer
Pictures to draw, 1–4. Default: 1. Each is billed.
quality
standard | pro-2k | pro-4k
Default: standard (about 1K). Pro draws at 2K or 4K.
style
string
A preset: none, photo, cinematic, product, portrait, illustration, anime, watercolor, oil-painting, 3d-render, flat-vector, line-art, pixel-art. Default: none.
seed
integer
0–2147483647. Picture n of a request uses seed + n. Best effort — see Seeds.
variety
low | normal | high
How far pictures may stray from the most literal reading. Default: normal.
allowText
boolean
Draw the words you put in quotation marks. Default: false — no lettering at all.
references
Reference[]
Up to 4 reference pictures. See Reference pictures.
saveToFiles
boolean
Also file each picture in the person’s Files. Default: false for an API key.
202 Accepted — drawing
{
  "status": "success",
  "credits": 20,
  "generation": {
    "id": "533ea88f-bccc-4f75-a515-fc13d31bbd0c",
    "mode": "generate",
    "state": "rendering",
    "quality": "standard",
    "options": { "aspectRatio": "16:9", "count": 2, "style": "cinematic", "variety": "normal", "allowText": false },
    "credits": { "reserved": 20, "charged": 0, "refunded": 0 },
    "images": [
      { "id": "9fcb4933-…", "index": 0, "state": "pending", "seed": 1497173827, "url": null },
      { "id": "0ca5785f-…", "index": 1, "state": "pending", "seed": 1497173828, "url": null }
    ]
  }
}

Poll a generation

GET /v1/images/generations/{id} API key

?wait=N (up to 25) holds the answer while the generation is still drawing, so a script can poll without sleeping. The generation’s state ends as:

stateMeaning
renderingStill drawing.
doneEvery picture was drawn.
partialSome were drawn; the others carry an error and were refunded.
failedNone were drawn; the whole reservation was refunded.

Each picture’s state is pending, done or failed. A failed picture’s error.code is one of BLOCKED (refused by the safety filter), NO_IMAGE (nothing drawable — describe the subject, colours and setting), TIMEOUT, BUSY or INTERRUPTED (a server restart).

200 Finished, one picture refused
{
  "status": "success",
  "generation": {
    "id": "533ea88f-bccc-4f75-a515-fc13d31bbd0c",
    "mode": "generate",
    "state": "partial",
    "prompt": "Golden temple roofs of Vientiane at dawn, mist, monks walking",
    "negativePrompt": null,
    "quality": "standard",
    "options": { "aspectRatio": "16:9", "count": 2, "style": "cinematic", "variety": "normal", "allowText": false },
    "parentImageId": null,
    "references": [],
    "credits": { "reserved": 20, "charged": 10, "refunded": 10 },
    "projectId": "95cb8d98-…",
    "createdBy": { "type": "apiKey", "id": "3d1f…", "name": null },
    "mine": true,
    "images": [
      {
        "id": "9fcb4933-…", "index": 0, "state": "done",
        "width": 1344, "height": 768, "seed": 1497173827,
        "url": "/v1/images/9fcb4933-…/content",
        "thumbnailUrl": "/v1/images/9fcb4933-…/content?size=thumb",
        "fileId": null, "error": null
      },
      {
        "id": "0ca5785f-…", "index": 1, "state": "failed", "seed": 1497173828,
        "url": null, "thumbnailUrl": null, "fileId": null,
        "error": { "code": "BLOCKED", "message": "This image was not drawn: the request was refused by the safety filter. Your credits were returned." }
      }
    ],
    "createdAt": "2026-10-13T12:50:01.000Z",
    "finishedAt": "2026-10-13T12:50:13.000Z"
  }
}

Download a picture

GET /v1/images/{imageId}/content API key
QueryMeaning
size=thumbA 512px WebP preview.
format=webp · png · jpegThe full picture is stored as WebP; PNG and JPEG are converted once and kept.
download=1Sent as an attachment.

Pictures larger than 8 MB (a 4K PNG, for example) answer 302 with a link that expires in 5 minutes — let your HTTP client follow redirects. A picture’s bytes never change, so the response may be cached.

Reference pictures

Up to 4 pictures may guide a generation (an edit’s own picture counts as one). Each is one of four forms, with an optional role:

Reference

{ "imageId": "…" }
object
A picture made here before (any in your organization).
{ "fileId": "…" }
object
A picture in Files, up to 15 MB. Upload large pictures with Files first.
{ "data": "<base64>", "mediaType": "image/png" }
object
Inline PNG, JPEG or WebP, up to 7 MB decoded. The whole request must stay under 9.5 MB.
{ "url": "https://…" }
object
A public https picture, up to 10 MB, fetched once.
role
general | style | subject
Add to any form. style: match its look, not its content. subject: keep this person, product or object recognisable. Default: general.

The API Gateway in front of us accepts at most 10 MB per request: send large pictures as a fileId (upload them to Files first) or a url, and shrink inline pictures to about 1,600px before sending.

Text in pictures

By default a picture has no lettering at all. With allowText: true, only the words you put in quotation marks are drawn — "…", “…”, «…» or 「…」, at most five, each up to 120 characters — and nothing else is written. A request with allowText and nothing quoted is refused with NO_QUOTED_TEXT. Phone numbers, emails, addresses, prices and dates are never invented. Lao and Thai lettering is sometimes misspelled; check it.

Seeds

Every picture reports the seed it was drawn with, and sending the same prompt, options and seed gives a similar picture — but not always an identical one. When a seed draws nothing the picture is retried once with the next seed, and reports that one.

Edit a picture

POST /v1/images/edits API key

JSON body

image *
Reference
The picture to change (any reference form).
instruction *
string
What to change, up to 2,000 characters. Everything not mentioned stays. Optional with a preset.
preset
Preset
A ready-made edit — see ID photo. A preset takes the one picture only (no references).
references
Reference[]
Up to 3 more pictures, e.g. a product to place in it.
aspectRatio
string
Default: the listed shape nearest to the picture’s own.
count, quality, style, seed, allowText, negativePrompt, saveToFiles As for a generation.

ID photo

An edit with preset turns one photo of a person into a formal ID photo. The face, its shape and the hair are kept as they are — nothing is beautified or restyled. Only the clothes and the background change, and the photo comes out sharp. The picture is 3:4 (the 3 × 4 cm photo) unless you send aspectRatio, lettering is always off, and instruction becomes an optional note, such as “remove the glare on the glasses”.

preset

id *
"id-photo"
The preset.
outfit
suit-tie | suit | blazer | own
A dark suit, white shirt and tie; a suit with an open collar; a dark blazer over a white blouse; or the person’s own clothes, neatened. Default: suit-tie.
background
white | blue | grey
Plain white, light blue or light grey, evenly lit. Default: white.
source
auto | photo | document
auto: we look at `image` ourselves — an ordinary photo is used as it is, a passport or ID card page is refused with DOCUMENT_NOT_ACCEPTED. photo skips that look. document is refused. Default: auto.

Send an ordinary photo of the person — a phone photo against a plain wall works; sideways is fine, we turn it upright. We look at it first (source: "auto", the default): a passport or ID card page is refused with DOCUMENT_NOT_ACCEPTED (the image model will not edit an identity document), and a picture with no person with NO_PERSON_FOUND — both before anything is charged. A photo of the person holding a document is cut to the person. Prices are the usual ones per picture; which qualities can draw an ID photo right now is listed under presets in GET /v1/images/options.

Variations

POST /v1/images/variations API key

JSON body

imageId *
string
The picture to vary.
strength
subtle | strong
subtle keeps the composition and changes details; strong keeps the subject and style and re-composes. Default: subtle.
count
integer
1–4. Default: 1.
quality
string
Default: the original’s quality.
seed, saveToFiles As for a generation.

Upscale

POST /v1/images/upscales API key

JSON body

imageId *
string
The picture to enlarge.
size *
2k | 4k
Billed as Pro 2K or Pro 4K. Refused with ALREADY_THAT_SIZE when the picture is already that large.
saveToFiles
boolean
As for a generation.

An upscale redraws the picture at the larger size, keeping its content, colours and any text; very fine detail may change. Edits, variations and upscales all answer 202 with a generation (its mode says which) and are polled the same way.

Improve a prompt

POST /v1/images/enhance-prompt API key

Rewrites a short idea — in Lao, Thai or English — as a full English prompt. Quoted words are kept exactly. Free; limited to 10 per minute per key and 200 per day per organization. Body: prompt (required), style, mode (generate or edit), allowText.

200
{
  "status": "success",
  "prompt": "A graceful young Lao woman in a traditional silk sinh stands before the golden spires of Pha That Luang in Vientiane, holding a wooden sign that reads \"ສະບາຍດີ\" …",
  "original": "ຮູບນາງສາວລາວນຸ່ງສິ້ນ ຢືນຢູ່ພະທາດຫຼວງ ມີປ້າຍ \"ສະບາຍດີ\"",
  "credits": 0
}

List generations

GET /v1/images/generations API key

Newest first. owner=me (default: what this key made) or owner=team (the whole organization), in=<projectId> to narrow to a project, kind= to one kind (generate, edit, id-photo, variation, upscale — id-photo is the ID photo preset, edit the other edits; mode= still works and counts both as edit), q= for words in the prompt, limit (up to 50, default 24) and cursor — pass the nextCursor of the previous page.

Delete

DELETE /v1/images/generations/{id} API key
DELETE /v1/images/{imageId} API key

Removes a generation, or one picture, from the gallery (a key may delete what it made). Copies in Files stay. Deleted pictures are purged after 30 days.

Limits

LimitValue
Pictures per request4
Generations drawing at once per organization3 (more answer 429 TOO_MANY_GENERATIONS)
Request body9.5 MB
Prompt / leave-out / edit instruction4,000 / 1,000 / 2,000 characters

Errors

HTTPCodeWhen
400INVALID_REQUESTA field is missing or out of range.
400NO_QUOTED_TEXTallowText is on but nothing is in quotation marks.
400IMAGE_NOT_READYA referenced picture has not finished drawing.
400ALREADY_THAT_SIZEAn upscale to a size the picture already has.
400NO_PERSON_FOUNDAn ID photo from a picture with no person in it.
400DOCUMENT_NOT_ACCEPTEDAn ID photo from a passport or ID card page: send an ordinary photo of the person.
400INVALID_REFERENCE · REFERENCE_UNREACHABLEA reference is not a readable picture, or its URL could not be fetched.
402QUOTA_EXCEEDEDNot enough credits for the whole request.
403SCOPE_FORBIDDEN · SERVICE_DISABLED · VERIFICATION_REQUIREDThe key lacks images, the service is switched off, or identity verification is required.
404NOT_FOUNDNo such generation or picture in your organization.
409RENDERINGDeleting what is still drawing.
413PAYLOAD_TOO_LARGE · STORAGE_QUOTA_EXCEEDEDThe body is over 9.5 MB, or your storage is full.
429TOO_MANY_GENERATIONS · RATE_LIMITED · USAGE_LIMIT_REACHEDThree already drawing, too many requests, or a spending ceiling.
503IMAGES_UNAVAILABLE · PRO_UNAVAILABLEDrawing is unavailable right now (Pro only, for the second).

See Errors for the shared envelope.