# Quickstart

> Two ways in — your AI assistant, or code. Pick the one you work in.

Both ways need a Forma account. [Sign up](https://app.formalogic.io) and open the
console once — that creates your organisation. The free plan includes **20
credits a month**; an answer costs 1 credit whether it is `valid` or `invalid`,
and an `error` is free.

## In your AI assistant

A minute or two in most clients — ChatGPT needs Developer mode turned on first.

Connect an assistant: add the remote MCP server https://mcp.formalogic.io/mcp (no API key; you sign in with your Forma account). Or paste this into any agent:

```
Connect to Forma, a remote MCP server at https://mcp.formalogic.io/mcp. Add it as a remote HTTP MCP server named "forma" with no API key: it uses OAuth, so I will sign in with my Forma account in the browser when you connect. If you need the exact steps for this client, read https://docs.formalogic.io/connect. Once connected, call forma_status and tell me which account you are connected as, then call list_oracles to show what you can ask.
```

To check it is connected, ask your assistant to run `forma_status`: it answers
with your organisation and plan.

Then ask for something. This exact request came back `valid`:

```text
A right triangle with legs 3 and 4 and hypotenuse 5, each side labelled with its length, and the right angle marked with a small square.
```

What comes back is a verdict with the TikZ source and its `verified_by`
citation. Where your client can show it, the figure is drawn inline; otherwise
ask the agent to show it — see [Draw a figure](https://docs.formalogic.io/figures).

## From code

An API key and one request.

**Get a key**

Keys are shown once, when they are created. Export it for the commands below.

[Create an API key](https://app.formalogic.io/keys)

```bash
export FORMA_API_KEY=fk_live_…
```

**Ask an oracle**

Put the numbers in the intent. Forma does not fetch data: a chart request that
does not give its values is refused with `422 DATA_REQUIRED`, unbilled. To get a
sketch with illustrative values instead, send `"allow_generated_data": true`; the
answer then says `"data": "generated"`.
`format` is optional: `chart` answers in `vega-lite` unless you ask for another,
`vector-graphics` in `tikz`.

```bash curl
curl https://api.formalogic.io/v1/oracles/chart/ask \
  -H "Authorization: Bearer $FORMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"intent": "grouped bar chart of quarterly sales, Q1-Q4: North 120, 135, 150, 160; South 90, 110, 105, 130"}'
```

```python Python
import os, httpx

answer = httpx.post(
    "https://api.formalogic.io/v1/oracles/chart/ask",
    headers={"Authorization": f"Bearer {os.environ['FORMA_API_KEY']}"},
    json={"intent": "grouped bar chart of quarterly sales, Q1-Q4: North 120, 135, 150, 160; South 90, 110, 105, 130"},
    timeout=120,
).json()
```

```ts TypeScript
const answer = await fetch('https://api.formalogic.io/v1/oracles/chart/ask', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FORMA_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ intent: 'grouped bar chart of quarterly sales, Q1-Q4: North 120, 135, 150, 160; South 90, 110, 105, 130' }),
}).then((r) => r.json())
```

Allow **120 seconds**: reaching a verdict can take that long. There is no
streaming and no polling endpoint — the call returns when the verdict does.

**Read the verdict**

```json
{
  "oracle": "chart",
  "format": "vega-lite",
  "status": "valid",
  "credits": 1,
  "result": {
    "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
    "data": { "values": [{ "quarter": "Q1", "region": "North", "sales": 120 }, …] },
    "mark": "bar",
    "encoding": { "x": { "field": "quarter" }, "xOffset": { "field": "region" }, "y": { "field": "sales" }, … }
  },
  "verified_by": "chart@6baf09f0",
  "figure": { "drawable": true, "target": "vega-lite", "token": "v2.dmVnYS1saXRl…" }
}
```

Four fields carry the whole idea:

- `status` — the **verdict**: `valid`, `invalid` (refused, with `detail`) or
  `error` (ours, not billed). [Verdicts](https://docs.formalogic.io/verdicts) has what each means.
- `result` — the artifact, present only on `valid`. Here it is a Vega-Lite spec
  you can render yourself.
- `verified_by` — **the version of the rules the answer passed**. Store it next to
  the artifact.
- `credits` — what this call actually cost.

**Draw it**

Or let Forma draw it: send the `figure.token` back. It is free, returns SVG by
default (`"format": "png"` for a raster), and the token is valid for an hour.

```bash
curl --fail-with-body https://api.formalogic.io/v1/figures/render \
  -H "Authorization: Bearer $FORMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token": "v2.dmVnYS1saXRl…"}' -o chart.svg
```

**Check what it cost**

The [Usage](https://app.formalogic.io/usage) page shows the call you just made:
which oracle, which key, what verdict, what it cost.

An `invalid` verdict arrives as a `200`: the call worked, and the check said
no. Handle the HTTP status and the verdict separately — see
[Handle every verdict](https://docs.formalogic.io/handling-verdicts).

## List what you can ask

```bash
curl https://api.formalogic.io/v1/oracles \
  -H "Authorization: Bearer $FORMA_API_KEY"
```

Free. The catalogue is the contract — read it at start-up rather than hardcoding
names, and a new oracle becomes available to you without a deploy.

## Next

- [How Forma works](https://docs.formalogic.io/how-oracles-work): What a verdict promises, and what it does not.
- [Handle every verdict](https://docs.formalogic.io/handling-verdicts): Client code that branches on each outcome.
- [Connect your agent](https://docs.formalogic.io/connect): The same calls as tools, for Claude, Cursor and other MCP clients.
- [Gate CI on a verdict](https://docs.formalogic.io/gate-ci): Generate an artifact in CI; fail the build unless it comes back valid.
