[{"data":1,"prerenderedAt":174},["ShallowReactive",2],{"doc-news-feedback":3},{"blocks":4,"markdown":173},[5,8,87,89,93,96,98,165,167,169,171],{"kind":6,"html":7},"html","\u003Cp>Two small endpoints for agents that use Forma over time: one to learn what is\nnew, one to tell the people who build Forma what worked and what did not. Neither\nspends credits.\u003C\u002Fp>\n\u003Ch2 id=\"what-s-new\">What's new\u003C\u002Fh2>\n",{"kind":9,"method":10,"path":11,"operation":12,"example":29,"response":40,"errors":64,"authErrors":69},"endpoint","GET","\u002Fv1\u002Fnews",{"method":10,"path":11,"summary":13,"description":14,"parameters":15,"body":24,"responses":25},"News","What is new for callers of this API and the MCP server.\n\nFree. `since` (YYYY-MM-DD) keeps entries on or after that date; `limit`\n(1-50, default 20) caps how many come back. An agent can remember `latest`\nand ask again with it as `since`.",[16,22],{"name":17,"in":18,"type":19,"required":20,"description":21},"since","query","string | null",false,"",{"name":23,"in":18,"type":19,"required":20,"description":21},"limit",[],[26],{"status":27,"description":28},"200","What changed, newest first.",{"query":30,"status":32,"response":33},{"since":31},"2026-09-28",200,{"items":34,"latest":36},[35],{"date":36,"title":37,"summary":38,"kind":39},"2026-09-29","News and feedback endpoints","GET \u002Fv1\u002Fnews lists what changed; POST \u002Fv1\u002Ffeedback records what worked and what did not. Both are free.","feature",{"status":27,"description":28,"binary":20,"fields":41},[42,46,50,53,56,60],{"name":43,"type":44,"description":45},"items","object[]","What changed, newest first",{"name":47,"type":48,"description":49},"items[].date","string","The day it changed, `YYYY-MM-DD`",{"name":51,"type":48,"description":52},"items[].title","One line",{"name":54,"type":48,"description":55},"items[].summary","What it means for a caller",{"name":57,"type":58,"description":59},"items[].kind","enum","`feature`, `fix` or `change`",{"name":61,"type":62,"description":63},"latest","string or null","The date of the newest entry. Pass it back as `since` next time",[65],{"status":66,"code":67,"when":68},422,"VALIDATION_FAILED","A bad `since` or `limit`; `context.parameter` names it",[70,74,77,80,83],{"status":71,"code":72,"when":73},401,"KEY_MISSING","No `Authorization` header",{"status":71,"code":75,"when":76},"KEY_UNKNOWN","The key is not one we issued",{"status":71,"code":78,"when":79},"KEY_REVOKED","The key was revoked in the console",{"status":71,"code":81,"when":82},"KEY_EXPIRED","The key is past its expiry",{"status":84,"code":85,"when":86},403,"ORG_DISABLED","The key is fine; its organisation is not active",{"kind":6,"html":88},"\u003Cp>Returns the changes a caller can notice (endpoints, oracles, MCP tools), newest\nfirst, with \u003Ccode>latest\u003C\u002Fcode>, the date of the newest entry. Remember \u003Ccode>latest\u003C\u002Fcode> and pass it\nback as \u003Ccode>since\u003C\u002Fcode> to see only what arrived after it.\u003C\u002Fp>\n",{"kind":90,"lang":91,"code":92},"code","bash","curl -s https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Fnews?since=2026-09-28 \\\n  -H \"Authorization: Bearer $FORMA_API_KEY\"",{"kind":90,"lang":94,"code":95},"json","{\n  \"items\": [\n    { \"date\": \"2026-09-29\", \"title\": \"News and feedback endpoints\",\n      \"summary\": \"GET \u002Fv1\u002Fnews lists what changed; …\", \"kind\": \"feature\" }\n  ],\n  \"latest\": \"2026-09-29\"\n}",{"kind":6,"html":97},"\u003Cdiv class=\"doc-table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Parameter\u003C\u002Fth>\n\u003Cth>\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>since\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>YYYY-MM-DD\u003C\u002Fcode>. Entries on or after this date.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>limit\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>1–50, default 20.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>kind\u003C\u002Fcode> is \u003Ccode>feature\u003C\u002Fcode>, \u003Ccode>fix\u003C\u002Fcode> or \u003Ccode>change\u003C\u002Fcode>. The same entries are in the\n\u003Ca href=\"\u002Fchangelog\">Changelog\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"send-feedback\">Send feedback\u003C\u002Fh2>\n",{"kind":9,"method":99,"path":100,"operation":101,"example":136,"response":143,"errors":152,"authErrors":159},"POST","\u002Fv1\u002Ffeedback",{"method":99,"path":100,"summary":102,"description":103,"parameters":104,"body":105,"responses":132},"Feedback","Tell us what worked and what did not. Free, and read by the people who build Forma.\n\n`sentiment` is positive, negative or neutral; `message` says why. Name the\n`oracle` it is about, and a `request_id` from an answer if it is about one.\nThe organisation and key are the ones this request authenticated with; the\nbody cannot name others. Each key may send 100 in any 24 hours.",[],[106,115,121,126],{"name":107,"type":48,"required":108,"description":21,"enum":109,"default":113,"constraints":114},"sentiment",true,[110,111,112],"positive","negative","neutral",null,[],{"name":116,"type":48,"required":108,"description":21,"enum":117,"default":113,"constraints":118},"message",[],[119,120],"min length 1","max length 2000",{"name":122,"type":48,"required":20,"description":123,"enum":124,"default":113,"constraints":125},"oracle","An oracle name from GET \u002Fv1\u002Foracles.",[],[],{"name":127,"type":48,"required":20,"description":128,"enum":129,"default":113,"constraints":130},"request_id","The answer this is about, if any.",[],[131],"max length 100",[133],{"status":134,"description":135},"201","The feedback was recorded.",{"body":137,"status":140,"response":141},{"sentiment":111,"oracle":138,"message":139},"chart","The legend covers the last bar.",201,{"id":142,"received":108},"fb_01K…",{"status":134,"description":135,"binary":20,"fields":144},[145,148],{"name":146,"type":48,"description":147},"id","Quote it if you write to us about this feedback",{"name":149,"type":150,"description":151},"received","boolean","Always `true`",[153,155],{"status":66,"code":67,"when":154},"The body is not a JSON object, has an unknown field, or breaks a rule above; `context.parameter` names it",{"status":156,"code":157,"when":158},402,"QUOTA_EXCEEDED","This key sent 100 in the last 24 hours (`context.scope` is `feedback`). Credits are unaffected",[160,161,162,163,164],{"status":71,"code":72,"when":73},{"status":71,"code":75,"when":76},{"status":71,"code":78,"when":79},{"status":71,"code":81,"when":82},{"status":84,"code":85,"when":86},{"kind":6,"html":166},"\u003Cp>Say what worked or what did not, in words. It is read by the people who build\nForma and used to decide what to fix and build next.\u003C\u002Fp>\n",{"kind":90,"lang":91,"code":168},"curl -s https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Ffeedback \\\n  -H \"Authorization: Bearer $FORMA_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"sentiment\": \"negative\", \"oracle\": \"vector-graphics\",\n       \"message\": \"Labels on the triangle overlap the sides.\"}'",{"kind":90,"lang":94,"code":170},"{ \"id\": \"fb_01K…\", \"received\": true }",{"kind":6,"html":172},"\u003Cdiv class=\"doc-table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Field\u003C\u002Fth>\n\u003Cth>\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>sentiment\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Required. \u003Ccode>positive\u003C\u002Fcode>, \u003Ccode>negative\u003C\u002Fcode> or \u003Ccode>neutral\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>message\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Required. 1–2000 characters.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>oracle\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Optional. A name from \u003Ccode>GET \u002Fv1\u002Foracles\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>request_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Optional. The answer this is about, up to 100 characters.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>The organisation and key are the ones the request authenticated with; the body\ncannot name others, and any other field is refused. The message is never sent\nback by the API.\u003C\u002Fp>\n\u003Cp>Each key may send 100 in any 24 hours. Past that the answer is \u003Ccode>402\u003C\u002Fcode> with\n\u003Ccode>QUOTA_EXCEEDED\u003C\u002Fcode> and \u003Ccode>context.scope\u003C\u002Fcode> of \u003Ccode>feedback\u003C\u002Fcode>. This cap is separate from\ncredits: your balance is unaffected, and asks keep working.\u003C\u002Fp>\n","# News and feedback\n\n> What changed, and a way to tell us what worked and what did not. Both free.\n\nTwo small endpoints for agents that use Forma over time: one to learn what is\nnew, one to tell the people who build Forma what worked and what did not. Neither\nspends credits.\n\n## What's new\n\n`GET https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Fnews`\n\nRequest:\n\n| Field | Type | Where | Meaning |\n|---|---|---|---|\n| `since` | string \\| null | query | — |\n| `limit` | string \\| null | query | — |\n\nResponse 200: What changed, newest first.\n\n| Field | Type | Present | Meaning |\n|---|---|---|---|\n| `items` | object[] | always | What changed, newest first |\n| `items[].date` | string | always | The day it changed, `YYYY-MM-DD` |\n| `items[].title` | string | always | One line |\n| `items[].summary` | string | always | What it means for a caller |\n| `items[].kind` | enum | always | `feature`, `fix` or `change` |\n| `latest` | string or null | always | The date of the newest entry. Pass it back as `since` next time |\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| 422 | `VALIDATION_FAILED` | A bad `since` or `limit`; `context.parameter` names it |\n\nReturns the changes a caller can notice (endpoints, oracles, MCP tools), newest\nfirst, with `latest`, the date of the newest entry. Remember `latest` and pass it\nback as `since` to see only what arrived after it.\n\n```bash\ncurl -s https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Fnews?since=2026-09-28 \\\n  -H \"Authorization: Bearer $FORMA_API_KEY\"\n```\n\n```json\n{\n  \"items\": [\n    { \"date\": \"2026-09-29\", \"title\": \"News and feedback endpoints\",\n      \"summary\": \"GET \u002Fv1\u002Fnews lists what changed; …\", \"kind\": \"feature\" }\n  ],\n  \"latest\": \"2026-09-29\"\n}\n```\n\n| Parameter | |\n|---|---|\n| `since` | `YYYY-MM-DD`. Entries on or after this date. |\n| `limit` | 1–50, default 20. |\n\n`kind` is `feature`, `fix` or `change`. The same entries are in the\n[Changelog](https:\u002F\u002Fdocs.formalogic.io\u002Fchangelog).\n\n## Send feedback\n\n`POST https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Ffeedback`\n\nRequest:\n\n| Field | Type | Where | Meaning |\n|---|---|---|---|\n| `sentiment` | string | body, required | — |\n| `message` | string | body, required | — |\n| `oracle` | string | body | An oracle name from GET \u002Fv1\u002Foracles. |\n| `request_id` | string | body | The answer this is about, if any. |\n\nResponse 201: The feedback was recorded.\n\n| Field | Type | Present | Meaning |\n|---|---|---|---|\n| `id` | string | always | Quote it if you write to us about this feedback |\n| `received` | boolean | always | Always `true` |\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| 422 | `VALIDATION_FAILED` | The body is not a JSON object, has an unknown field, or breaks a rule above; `context.parameter` names it |\n| 402 | `QUOTA_EXCEEDED` | This key sent 100 in the last 24 hours (`context.scope` is `feedback`). Credits are unaffected |\n\nSay what worked or what did not, in words. It is read by the people who build\nForma and used to decide what to fix and build next.\n\n```bash\ncurl -s https:\u002F\u002Fapi.formalogic.io\u002Fv1\u002Ffeedback \\\n  -H \"Authorization: Bearer $FORMA_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"sentiment\": \"negative\", \"oracle\": \"vector-graphics\",\n       \"message\": \"Labels on the triangle overlap the sides.\"}'\n```\n\n```json\n{ \"id\": \"fb_01K…\", \"received\": true }\n```\n\n| Field | |\n|---|---|\n| `sentiment` | Required. `positive`, `negative` or `neutral`. |\n| `message` | Required. 1–2000 characters. |\n| `oracle` | Optional. A name from `GET \u002Fv1\u002Foracles`. |\n| `request_id` | Optional. The answer this is about, up to 100 characters. |\n\nThe organisation and key are the ones the request authenticated with; the body\ncannot name others, and any other field is refused. The message is never sent\nback by the API.\n\nEach key may send 100 in any 24 hours. Past that the answer is `402` with\n`QUOTA_EXCEEDED` and `context.scope` of `feedback`. This cap is separate from\ncredits: your balance is unaffected, and asks keep working.\n",1793819974022]