figviz
API Docs

API Reference

Integrate Figviz diagram generation into your applications via REST API

Figviz exposes a single synchronous endpoint. You send prompts, the request blocks while the images render, and the finished URLs come back in the same response. There is no task ID and nothing to poll.

Quickstart

curl -X POST https://figviz.com/api/v1/generate \
  -H "Authorization: Bearer fvk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "free body diagram of a block on an inclined plane", "quality": "2k"}'

Endpoint

POST https://figviz.com/api/v1/generate

Every request goes to this one URL. There are no other public routes.

Authentication

Pass your secret key as a bearer token. Keys are created and rotated under Settings > API, where each key is displayed a single time at creation. Every key begins with the fvk_ prefix.

Authorization: Bearer fvk_xxxxxxxx

A key spends real credits from your account balance. Treat it like a password: keep it server-side and never ship it in a browser or mobile bundle.

Request parameters

Send a JSON body with these fields.

FieldTypeRequiredNotes
promptstringone of the twoA single description to render
promptsstring[]one of the twoUp to 4 descriptions for a batch
qualitystringoptional"1k" (default), "2k", or "4k"
aspectRatiostringoptionalFor example "16:9", "1:1", "4:3"

Supply prompt for a single image or prompts for a batch. If you send both, prompts wins and prompt is ignored. Higher resolutions and larger batch sizes may be gated by your plan.

Successful response

A 200 returns the stored image URLs plus your updated credit balance.

{
  "images": [
    {
      "url": "https://cdn.figviz.io/generated/abc123.png",
      "prompt": "free body diagram of a block on an inclined plane"
    }
  ],
  "credits_used": 1,
  "credits_remaining": 79
}

In a batch, the images array preserves the order of your prompts.

Pricing per image

QualityCredits
1k1
2k1
4k1.5

Billing is success-only. If one prompt in a batch fails or cannot be stored, that image is refunded and never appears on your invoice. The API draws from the same pay-as-you-go balance as the web app, and images returned through the API are not watermarked.

Code samples

Python

import requests

resp = requests.post(
    "https://figviz.com/api/v1/generate",
    headers={
        "Authorization": "Bearer fvk_your_api_key",
        "Content-Type": "application/json",
    },
    json={"prompt": "labeled cross section of a leaf", "quality": "1k"},
)
resp.raise_for_status()
payload = resp.json()

for img in payload["images"]:
    print(img["url"])
print("Credits left:", payload["credits_remaining"])

TypeScript

const res = await fetch("https://figviz.com/api/v1/generate", {
  method: "POST",
  headers: {
    Authorization: "Bearer fvk_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompts: ["mitosis four-stage sequence", "labeled DNA double helix"],
    quality: "2k",
  }),
});

const data = await res.json();
data.images.forEach((img: { url: string }) => console.log(img.url));
console.log(`Spent ${data.credits_used} credits`);

Batch with cURL

curl -X POST https://figviz.com/api/v1/generate \
  -H "Authorization: Bearer fvk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompts": [
      "rock cycle diagram with arrows",
      "labeled food web for a grassland ecosystem",
      "titration setup for a high school chemistry lab"
    ],
    "quality": "1k"
  }'

Errors

Failures use conventional HTTP status codes and return a JSON body with a human-readable error and a machine-readable code.

{
  "error": "Insufficient credits. Buy a credit pack at /pricing",
  "code": "INSUFFICIENT_CREDITS",
  "credits_remaining": 0
}
StatuscodeWhen it happens
400INVALID_BODYThe body is missing or is not valid JSON
400PROMPT_REQUIREDNeither prompt nor prompts was supplied
400TOO_MANY_PROMPTSMore than 4 prompts in one call
401UNAUTHORIZEDThe Authorization header is missing or malformed
401INVALID_API_KEYThe key is unknown or has been disabled
402INSUFFICIENT_CREDITSBalance is too low; credits_remaining is included
403PLAN_LIMIT_EXCEEDEDBatch size is above your plan ceiling
403QUALITY_NOT_ALLOWEDThe requested resolution is not on your plan
500GENERATION_FAILEDEvery image in the request failed to render
504GENERATION_TIMEOUTRendering ran past the five-minute ceiling

Defensive handling

resp = requests.post(url, headers=headers, json=payload)

if resp.status_code == 402:
    print("Top up at /pricing, remaining:", resp.json().get("credits_remaining", 0))
elif not resp.ok:
    print("Request failed:", resp.json().get("error"))
else:
    for img in resp.json()["images"]:
        print(img["url"])

Operational limits

LimitValue
Prompts per request4
Active keys per account5
Render ceiling5 minutes per request
ResolutionsSubject to your plan