Endpoints

Draw a figure

Turn an answer into a picture. Free, and only for answers we vouched for.

POSThttps://api.formalogic.io/v1/figures/render

Draw a figure this API already vouched for.

Request

tokenstringbody, requiredThe figure.token from an answer.

min length 1

formatstringbodysvg or png.
curl -X POST https://api.formalogic.io/v1/figures/render \
  -H "Authorization: Bearer $FORMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token":"…"}' \
  --fail-with-body -o figure.svg

Response 200

The drawn figure: image/svg+xml, or image/png when you ask for png.

Errors

401KEY_MISSINGKEY_UNKNOWNKEY_REVOKEDKEY_EXPIREDThe key is missing, unknown, revoked or expired — see Authentication
403ORG_DISABLEDThe key is fine and its organisation is not active — see Authentication
400SIGNATURE_INVALIDThe token is malformed, altered or expired
422VALIDATION_FAILEDThe body is missing token, the format is unknown, the answer names data it does not carry, or the figure contains something Forma does not produce
501UNSUPPORTEDNothing draws this target
503UPSTREAM_UNAVAILABLEA figure could not be drawn because of a problem on our side, or drawing is briefly unavailable. The answer is unaffected; retry after a short wait

Every code, and what to do about it, is on Errors.

The request is generated from the API's OpenAPI document; the response and errors are held to real responses and to the Errors page.

Some answers can be drawn. When one can, its response carries a figure block:

json
{
  "status": "valid",
  "result": { "mark": "bar", "data": { "values": [] } },
  "figure": {
    "drawable": true,
    "target": "vega-lite",
    "token": "v2.dmVnYS1saXRlADE3OTAx…"
  }
}

Send that token here and you get the picture back.

Why a token and not an id

Nothing is stored. The token carries the artifact — it is the answer plus a signature proving we produced it — so there is no record to look up and no copy of your output kept on our side. It expires an hour after the answer.

It also means you never have to rebuild anything. Pass the token through unchanged; reconstructing the source yourself would have to match the signed bytes exactly, and a single space in the wrong place is indistinguishable from a forgery.

Formats

format
svg the default vector — what a browser or a document wants
png raster what a model can look at; SVG is not something an agent can read

The MCP show_figure tool defaults to png for that reason: its reader is a model.

What draws

vega-lite, tikz, pictex, metapost and gnuplot. TeX-family figures come back with their text as outlines, so the picture needs no fonts. Anything else is a 501 naming the target.

What a figure may contain

A figure is not a document you author — it is output Forma returned, handed back to us. So the renderer checks that it is that: every command in it has to be one Forma's own output can contain. Anything else is refused by name rather than run.

That is stricter than it may sound, and deliberately so. TeX is a programming language, MetaPost can read files, and gnuplot will run a shell command given a backtick in a chart title. Rather than scan for dangerous constructs — which fails, because TeX can build any command out of characters — the renderer starts from the short list of things Forma's output contains and refuses the rest.

The practical consequence: figures Forma returned draw, and hand-written TeX does not. If you want to typeset your own document, take the source from the answer and run it yourself — the tikz output is a fragment that drops straight into a tikzpicture environment.

Three states, not two

drawable answers a question with three honest outcomes, and the reason says which:

drawable: true there is a picture, and the token draws it
no renderer nothing can draw this target — some targets produce data, not pictures
not drawn, with a reason the answer names data it does not carry

That last one is deliberate. A chart whose data is {"url": "sales.csv"} is pointing at a file we have never seen, so there is nothing truthful to draw — and we do not go and fetch it. The same applies to a chart that generates its own rows rather than carrying them. Put the numbers in your intent and the chart carries them, and draws.

Free

Drawing costs no credits. You already paid for the answer; what you display it with should not change the price.