[{"data":1,"prerenderedAt":198},["ShallowReactive",2],{"doc-ask":3},{"blocks":4,"markdown":197},[5,188,191,195],{"kind":6,"method":7,"path":8,"operation":9,"example":51,"response":86,"errors":152,"authErrors":170},"endpoint","POST","\u002Fv1\u002Foracles\u002F{name}\u002Fask",{"method":7,"path":8,"summary":10,"description":11,"parameters":12,"body":19,"responses":47},"Ask","Ask an oracle for an artifact, and get back a verdict on it.\n\nThe answer is checked against the oracle's versioned rules before it\nis returned, so what comes back is a verdict rather than a guess. Allow 120\nseconds: reaching a verdict can take that long. There is no streaming and no\npolling endpoint — the call returns when the verdict does.",[13],{"name":14,"in":15,"type":16,"required":17,"description":18},"name","path","string",true,"An oracle `name` from `GET \u002Fv1\u002Foracles`.",[20,28,35,41],{"name":21,"type":16,"required":17,"description":22,"enum":23,"default":24,"constraints":25},"intent","What you want, in plain language. Not a template and not a specification — describe the thing, not how to build it.",[],null,[26,27],"min length 1","max length 4000",{"name":29,"type":30,"required":31,"description":32,"enum":33,"default":24,"constraints":34},"format","string | null",false,"One of the oracle's `formats`. Omit it for the oracle's `default_format`. A format the oracle cannot produce is refused with the ones it can.",[],[],{"name":36,"type":37,"required":31,"description":38,"enum":39,"default":31,"constraints":40},"allow_generated_data","boolean","Charts only. `false` (the default): a chart is drawn only from values the request gives, and a request without them is refused with 422 DATA_REQUIRED, unbilled. `true`: illustrative values are written when the request gives none, and the answer says `\"data\": \"generated\"`.",[],[],{"name":42,"type":43,"required":31,"description":44,"enum":45,"default":24,"constraints":46},"views","string[]","Views to return beside a valid answer, by name, from the format's `views` in `GET \u002Fv1\u002Foracles` (for example `summary`). Each comes back in `views` as text built from `result` alone; `result` is the same with or without them. Free. A view the format does not offer is refused with the ones it does, before anything runs.",[],[],[48],{"status":49,"description":50},"200","The verdict. `status` is `valid` (with `result` and a `verified_by` citation), `invalid` (the check refused it — billable, because the verdict is the product), or `error` (ours, unbilled, retryable).",{"path":52,"body":54,"status":56,"response":57},{"name":53},"chart",{"intent":55},"grouped bar chart of quarterly sales, Q1-Q4: North 120, 135, 150, 160; South 90, 110, 105, 130",200,{"oracle":53,"format":58,"status":59,"credits":60,"request_id":61,"result":62,"verified_by":82,"figure":83,"data":85},"vega-lite","valid",1,"req_01K…",{"$schema":63,"data":64,"mark":70,"encoding":71},"https:\u002F\u002Fvega.github.io\u002Fschema\u002Fvega-lite\u002Fv6.json",{"values":65},[66],{"quarter":67,"region":68,"sales":69},"Q1","North",120,"bar",{"x":72,"xOffset":75,"y":77,"color":80},{"field":73,"type":74},"quarter","ordinal",{"field":76},"region",{"field":78,"type":79},"sales","quantitative",{"field":76,"type":81},"nominal","chart@6baf09f0",{"drawable":17,"target":58,"token":84},"v2.dmVnYS1saXRl…","supplied",{"status":49,"description":50,"binary":31,"fields":87},[88,91,93,97,101,104,109,112,116,119,122,126,130,133,137,141,145,149],{"name":89,"type":16,"description":90},"oracle","Echoed back",{"name":29,"type":16,"description":92},"The format actually produced",{"name":94,"type":95,"description":96},"status","enum","`valid`, `invalid` or `error`",{"name":98,"type":99,"description":100},"credits","integer","What this call actually cost",{"name":102,"type":16,"description":103},"request_id","The same id as the `x-request-id` header. Quote it in feedback or to support",{"name":105,"type":106,"present":107,"description":108},"result","object","`valid` only","The artifact, in `format`",{"name":110,"type":16,"present":107,"description":111},"verified_by","The version of the rules that accepted it",{"name":113,"type":106,"present":114,"description":115},"figure","`valid`, from an oracle that draws","Whether the answer can be drawn, and the token to draw it — see Draw a figure",{"name":117,"type":37,"present":114,"description":118},"figure.drawable","Whether the token draws a picture",{"name":120,"type":16,"present":114,"description":121},"figure.target","What would draw it, such as `vega-lite` or `tikz`",{"name":123,"type":16,"present":124,"description":125},"figure.token","when `drawable`","Send it to `POST \u002Fv1\u002Ffigures\u002Frender`. Valid for an hour",{"name":127,"type":16,"present":128,"description":129},"figure.reason","when not `drawable`","Why it cannot be drawn",{"name":21,"type":106,"present":131,"description":132},"`valid`, sometimes","Whether the figure shows what was asked: `passed` (boolean), `faithful` (0–1) and `problems` (strings). `vector-graphics` only, and present only when that check ran",{"name":134,"type":95,"present":135,"description":136},"data","`valid` charts","`supplied`: every value came from the request. `generated`: Forma wrote illustrative values, which you allowed with `allow_generated_data`",{"name":138,"type":95,"present":139,"description":140},"reason","`invalid` only","`unsupported_feature`, `chart_type_mismatch` or `no_valid_answer`; `detail` says the same in a sentence",{"name":142,"type":16,"present":143,"description":144},"detail","`invalid`, `error`","Plain-language explanation",{"name":146,"type":37,"present":147,"description":148},"retryable","`error` only","Always `true` when present",{"name":42,"type":106,"present":150,"description":151},"`valid`, when `views` were asked for","Each view asked for, by name, as text built from `result` alone; `null` if it could not be built. `result` is the same with or without it",[153,157,161,164,168],{"status":154,"code":155,"when":156},404,"NOT_FOUND","No such oracle, or no organisation for this key",{"status":158,"code":159,"when":160},422,"VALIDATION_FAILED","The body is missing `intent`, or it is empty or over 4000 characters; or a `format` this oracle cannot produce (`context.available` lists the ones it can). `context.parameter` names the field",{"status":158,"code":162,"when":163},"DATA_REQUIRED","A chart request does not give the values to draw, and `allow_generated_data` is not `true`. Not billed",{"status":165,"code":166,"when":167},402,"QUOTA_EXCEEDED","Not enough credits for the call; see Limits and credits",{"status":56,"code":24,"when":169},"`status: \"error\"` — the oracle could not answer. Not billed; retry",[171,175,178,181,184],{"status":172,"code":173,"when":174},401,"KEY_MISSING","No `Authorization` header",{"status":172,"code":176,"when":177},"KEY_UNKNOWN","The key is not one we issued",{"status":172,"code":179,"when":180},"KEY_REVOKED","The key was revoked in the console",{"status":172,"code":182,"when":183},"KEY_EXPIRED","The key is past its expiry",{"status":185,"code":186,"when":187},403,"ORG_DISABLED","The key is fine; its organisation is not active",{"kind":189,"html":190},"html","\u003Ch2 id=\"example-response\">Example response\u003C\u002Fh2>\n",{"kind":192,"lang":193,"code":194},"code","json","{\n  \"oracle\": \"chart\",\n  \"format\": \"vega-lite\",\n  \"status\": \"valid\",\n  \"credits\": 1,\n  \"request_id\": \"req_01K…\",\n  \"result\": { \"$schema\": \"https:\u002F\u002Fvega.github.io\u002Fschema\u002Fvega-lite\u002Fv6.json\", \"mark\": \"bar\" },\n  \"verified_by\": \"chart@6baf09f0\",\n  \"figure\": { \"drawable\": true, \"target\": \"vega-lite\", \"token\": \"v2.dmVnYS1saXRl…\" },\n  \"data\": \"supplied\"\n}",{"kind":189,"html":196},"\u003Cp>\u003Ccode>status\u003C\u002Fcode> is a verdict, not a health check — all three arrive with HTTP \u003Ccode>200\u003C\u002Fcode>.\nSee \u003Ca href=\"\u002Fverdicts\">Verdicts\u003C\u002Fa> for which are billed and which are worth retrying.\u003C\u002Fp>\n\u003Ch2 id=\"notes\">Notes\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>A chart is drawn from the values you give.\u003C\u002Fstrong> Forma does not fetch or look up\ndata. A chart request with no values in it is refused with \u003Ccode>422 DATA_REQUIRED\u003C\u002Fcode>\nbefore anything runs; one whose chart would need values the request does not\ncontain is refused the same way. Neither is billed. Send\n\u003Ccode>&quot;allow_generated_data&quot;: true\u003C\u002Fcode> to accept illustrative values instead. Every valid\nchart says which it is in \u003Ccode>data\u003C\u002Fcode>: \u003Ccode>supplied\u003C\u002Fcode> or \u003Ccode>generated\u003C\u002Fcode>. A chart with no\nvalues at all is refused even with the flag. \u003Ccode>vector-graphics\u003C\u002Fcode> and \u003Ccode>coverage-policy\u003C\u002Fcode> ignore the flag.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Ask for a view to get the answer as text as well.\u003C\u002Fstrong> Send \u003Ccode>&quot;views&quot;: [&quot;summary&quot;]\u003C\u002Fcode>\nto an oracle format that lists \u003Ccode>summary\u003C\u002Fcode> under \u003Ccode>views\u003C\u002Fcode> in\n\u003Ca href=\"\u002Flist-oracles\">List oracles\u003C\u002Fa>, and a \u003Ccode class=\"chip chip--valid\">valid\u003C\u002Fcode> answer carries \u003Ccode>views.summary\u003C\u002Fcode>: the\nanswer written out as plain text, built from \u003Ccode>result\u003C\u002Fcode> and nothing else. \u003Ccode>result\u003C\u002Fcode>\nis the same with or without it, and it costs nothing more. A view the format\ndoes not offer is refused with \u003Ccode>422\u003C\u002Fcode> before anything runs, naming the ones it\ndoes; nothing is billed.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>\u003Ccode class=\"chip chip--valid\">valid\u003C\u002Fcode> is about the answer, not the world.\u003C\u002Fstrong> It means the output passed its\nformat's checks. It does not mean the numbers are true; \u003Ccode>data\u003C\u002Fcode> says where they\ncame from.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>A chart of a different kind is not an answer.\u003C\u002Fstrong> Ask for a candlestick and get a\nline, and the verdict is \u003Ccode class=\"chip chip--invalid\">invalid\u003C\u002Fcode> with \u003Ccode>reason: &quot;chart_type_mismatch&quot;\u003C\u002Fcode>. Billed\nlike any \u003Ccode class=\"chip chip--invalid\">invalid\u003C\u002Fcode>. Try another format: not every format can draw every kind.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>\u003Ccode>format\u003C\u002Fcode> is read from the body and from nowhere else.\u003C\u002Fstrong> The API never consults\nan environment variable, so a request sent by \u003Ccode>curl\u003C\u002Fcode> and the same request sent by\nthe \u003Ca href=\"\u002Fmcp\">MCP tools\u003C\u002Fa> mean the same thing.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Allow 120 seconds.\u003C\u002Fstrong> Reaching a verdict can take that long. No streaming, no\npolling endpoint.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>One ask is one billable unit\u003C\u002Fstrong>, however long it took.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>There is no idempotency key.\u003C\u002Fstrong> Two identical requests are two asks and two\ncharges, and because the same intent can return a different artifact they may\ndiffer — see \u003Ca href=\"\u002Fcitations#determinism\">Determinism\u003C\u002Fa>. If a retry must not\ndouble-charge, store the first verdict and check for it before asking again.\u003C\u002Fp>\n","# Ask an oracle\n\n> The one call that costs credits, and the one that returns a verdict.\n\n`POST https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Foracles\u002F{name}\u002Fask`\n\nRequest:\n\n| Field | Type | Where | Meaning |\n|---|---|---|---|\n| `name` | string | path, required | An oracle `name` from `GET \u002Fv1\u002Foracles`. |\n| `intent` | string | body, required | What you want, in plain language. Not a template and not a specification — describe the thing, not how to build it. |\n| `format` | string \\| null | body | One of the oracle's `formats`. Omit it for the oracle's `default_format`. A format the oracle cannot produce is refused with the ones it can. |\n| `allow_generated_data` | boolean | body | Charts only. `false` (the default): a chart is drawn only from values the request gives, and a request without them is refused with 422 DATA_REQUIRED, unbilled. `true`: illustrative values are written when the request gives none, and the answer says `\"data\": \"generated\"`. |\n| `views` | string[] | body | Views to return beside a valid answer, by name, from the format's `views` in `GET \u002Fv1\u002Foracles` (for example `summary`). Each comes back in `views` as text built from `result` alone; `result` is the same with or without them. Free. A view the format does not offer is refused with the ones it does, before anything runs. |\n\nResponse 200: The verdict. `status` is `valid` (with `result` and a `verified_by` citation), `invalid` (the check refused it — billable, because the verdict is the product), or `error` (ours, unbilled, retryable).\n\n| Field | Type | Present | Meaning |\n|---|---|---|---|\n| `oracle` | string | always | Echoed back |\n| `format` | string | always | The format actually produced |\n| `status` | enum | always | `valid`, `invalid` or `error` |\n| `credits` | integer | always | What this call actually cost |\n| `request_id` | string | always | The same id as the `x-request-id` header. Quote it in feedback or to support |\n| `result` | object | `valid` only | The artifact, in `format` |\n| `verified_by` | string | `valid` only | The version of the rules that accepted it |\n| `figure` | object | `valid`, from an oracle that draws | Whether the answer can be drawn, and the token to draw it — see Draw a figure |\n| `figure.drawable` | boolean | `valid`, from an oracle that draws | Whether the token draws a picture |\n| `figure.target` | string | `valid`, from an oracle that draws | What would draw it, such as `vega-lite` or `tikz` |\n| `figure.token` | string | when `drawable` | Send it to `POST \u002Fv1\u002Ffigures\u002Frender`. Valid for an hour |\n| `figure.reason` | string | when not `drawable` | Why it cannot be drawn |\n| `intent` | object | `valid`, sometimes | Whether the figure shows what was asked: `passed` (boolean), `faithful` (0–1) and `problems` (strings). `vector-graphics` only, and present only when that check ran |\n| `data` | enum | `valid` charts | `supplied`: every value came from the request. `generated`: Forma wrote illustrative values, which you allowed with `allow_generated_data` |\n| `reason` | enum | `invalid` only | `unsupported_feature`, `chart_type_mismatch` or `no_valid_answer`; `detail` says the same in a sentence |\n| `detail` | string | `invalid`, `error` | Plain-language explanation |\n| `retryable` | boolean | `error` only | Always `true` when present |\n| `views` | object | `valid`, when `views` were asked for | Each view asked for, by name, as text built from `result` alone; `null` if it could not be built. `result` is the same with or without it |\n\nErrors (plus 401 `KEY_MISSING`, `KEY_UNKNOWN`, `KEY_REVOKED`, `KEY_EXPIRED` and 403 `ORG_DISABLED` on every endpoint):\n\n| Status | Code | When |\n|---|---|---|\n| 404 | `NOT_FOUND` | No such oracle, or no organisation for this key |\n| 422 | `VALIDATION_FAILED` | The body is missing `intent`, or it is empty or over 4000 characters; or a `format` this oracle cannot produce (`context.available` lists the ones it can). `context.parameter` names the field |\n| 422 | `DATA_REQUIRED` | A chart request does not give the values to draw, and `allow_generated_data` is not `true`. Not billed |\n| 402 | `QUOTA_EXCEEDED` | Not enough credits for the call; see Limits and credits |\n| 200 | — | `status: \"error\"` — the oracle could not answer. Not billed; retry |\n\n## Example response\n\n```json\n{\n  \"oracle\": \"chart\",\n  \"format\": \"vega-lite\",\n  \"status\": \"valid\",\n  \"credits\": 1,\n  \"request_id\": \"req_01K…\",\n  \"result\": { \"$schema\": \"https:\u002F\u002Fvega.github.io\u002Fschema\u002Fvega-lite\u002Fv6.json\", \"mark\": \"bar\" },\n  \"verified_by\": \"chart@6baf09f0\",\n  \"figure\": { \"drawable\": true, \"target\": \"vega-lite\", \"token\": \"v2.dmVnYS1saXRl…\" },\n  \"data\": \"supplied\"\n}\n```\n\n`status` is a verdict, not a health check — all three arrive with HTTP `200`.\nSee [Verdicts](https:\u002F\u002Fdocs.formalogic.io\u002Fverdicts) for which are billed and which are worth retrying.\n\n## Notes\n\n**A chart is drawn from the values you give.** Forma does not fetch or look up\ndata. A chart request with no values in it is refused with `422 DATA_REQUIRED`\nbefore anything runs; one whose chart would need values the request does not\ncontain is refused the same way. Neither is billed. Send\n`\"allow_generated_data\": true` to accept illustrative values instead. Every valid\nchart says which it is in `data`: `supplied` or `generated`. A chart with no\nvalues at all is refused even with the flag. `vector-graphics` and `coverage-policy` ignore the flag.\n\n**Ask for a view to get the answer as text as well.** Send `\"views\": [\"summary\"]`\nto an oracle format that lists `summary` under `views` in\n[List oracles](https:\u002F\u002Fdocs.formalogic.io\u002Flist-oracles), and a `valid` answer carries `views.summary`: the\nanswer written out as plain text, built from `result` and nothing else. `result`\nis the same with or without it, and it costs nothing more. A view the format\ndoes not offer is refused with `422` before anything runs, naming the ones it\ndoes; nothing is billed.\n\n**`valid` is about the answer, not the world.** It means the output passed its\nformat's checks. It does not mean the numbers are true; `data` says where they\ncame from.\n\n**A chart of a different kind is not an answer.** Ask for a candlestick and get a\nline, and the verdict is `invalid` with `reason: \"chart_type_mismatch\"`. Billed\nlike any `invalid`. Try another format: not every format can draw every kind.\n\n**`format` is read from the body and from nowhere else.** The API never consults\nan environment variable, so a request sent by `curl` and the same request sent by\nthe [MCP tools](https:\u002F\u002Fdocs.formalogic.io\u002Fmcp) mean the same thing.\n\n**Allow 120 seconds.** Reaching a verdict can take that long. No streaming, no\npolling endpoint.\n\n**One ask is one billable unit**, however long it took.\n\n**There is no idempotency key.** Two identical requests are two asks and two\ncharges, and because the same intent can return a different artifact they may\ndiffer — see [Determinism](https:\u002F\u002Fdocs.formalogic.io\u002Fcitations#determinism). If a retry must not\ndouble-charge, store the first verdict and check for it before asking again.\n",1793819974035]