# News and feedback

> What changed, and a way to tell us what worked and what did not. Both free.

Two small endpoints for agents that use Forma over time: one to learn what is
new, one to tell the people who build Forma what worked and what did not. Neither
spends credits.

## What's new

`GET https://api.formalogic.io/v1/news`

Request:

| Field | Type | Where | Meaning |
|---|---|---|---|
| `since` | string \| null | query | — |
| `limit` | string \| null | query | — |

Response 200: What changed, newest first.

| Field | Type | Present | Meaning |
|---|---|---|---|
| `items` | object[] | always | What changed, newest first |
| `items[].date` | string | always | The day it changed, `YYYY-MM-DD` |
| `items[].title` | string | always | One line |
| `items[].summary` | string | always | What it means for a caller |
| `items[].kind` | enum | always | `feature`, `fix` or `change` |
| `latest` | string or null | always | The date of the newest entry. Pass it back as `since` next time |

Errors (plus 401 `KEY_MISSING`, `KEY_UNKNOWN`, `KEY_REVOKED`, `KEY_EXPIRED` and 403 `ORG_DISABLED` on every endpoint):

| Status | Code | When |
|---|---|---|
| 422 | `VALIDATION_FAILED` | A bad `since` or `limit`; `context.parameter` names it |

Returns the changes a caller can notice (endpoints, oracles, MCP tools), newest
first, with `latest`, the date of the newest entry. Remember `latest` and pass it
back as `since` to see only what arrived after it.

```bash
curl -s https://api.formalogic.io/v1/news?since=2026-09-28 \
  -H "Authorization: Bearer $FORMA_API_KEY"
```

```json
{
  "items": [
    { "date": "2026-09-29", "title": "News and feedback endpoints",
      "summary": "GET /v1/news lists what changed; …", "kind": "feature" }
  ],
  "latest": "2026-09-29"
}
```

| Parameter | |
|---|---|
| `since` | `YYYY-MM-DD`. Entries on or after this date. |
| `limit` | 1–50, default 20. |

`kind` is `feature`, `fix` or `change`. The same entries are in the
[Changelog](https://docs.formalogic.io/changelog).

## Send feedback

`POST https://api.formalogic.io/v1/feedback`

Request:

| Field | Type | Where | Meaning |
|---|---|---|---|
| `sentiment` | string | body, required | — |
| `message` | string | body, required | — |
| `oracle` | string | body | An oracle name from GET /v1/oracles. |
| `request_id` | string | body | The answer this is about, if any. |

Response 201: The feedback was recorded.

| Field | Type | Present | Meaning |
|---|---|---|---|
| `id` | string | always | Quote it if you write to us about this feedback |
| `received` | boolean | always | Always `true` |

Errors (plus 401 `KEY_MISSING`, `KEY_UNKNOWN`, `KEY_REVOKED`, `KEY_EXPIRED` and 403 `ORG_DISABLED` on every endpoint):

| Status | Code | When |
|---|---|---|
| 422 | `VALIDATION_FAILED` | The body is not a JSON object, has an unknown field, or breaks a rule above; `context.parameter` names it |
| 402 | `QUOTA_EXCEEDED` | This key sent 100 in the last 24 hours (`context.scope` is `feedback`). Credits are unaffected |

Say what worked or what did not, in words. It is read by the people who build
Forma and used to decide what to fix and build next.

```bash
curl -s https://api.formalogic.io/v1/feedback \
  -H "Authorization: Bearer $FORMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sentiment": "negative", "oracle": "vector-graphics",
       "message": "Labels on the triangle overlap the sides."}'
```

```json
{ "id": "fb_01K…", "received": true }
```

| Field | |
|---|---|
| `sentiment` | Required. `positive`, `negative` or `neutral`. |
| `message` | Required. 1–2000 characters. |
| `oracle` | Optional. A name from `GET /v1/oracles`. |
| `request_id` | Optional. The answer this is about, up to 100 characters. |

The organisation and key are the ones the request authenticated with; the body
cannot name others, and any other field is refused. The message is never sent
back by the API.

Each key may send 100 in any 24 hours. Past that the answer is `402` with
`QUOTA_EXCEEDED` and `context.scope` of `feedback`. This cap is separate from
credits: your balance is unaffected, and asks keep working.
