---
title: "Apply one suggestion"
method: POST
path: "/audit/suggestions"
---

# Apply one suggestion

`POST /audit/suggestions`

## Request

- Base URL: `https://secureai.one/v1`
- URL: `https://secureai.one/v1/audit/suggestions`
- Auth: HTTP bearer

The only way a suggestion changes anything. A product that quietly loosened a rule because a pattern looked benign would be indefensible the first time the pattern was an agent being exploited.

## Request body

- object
  - `id` string, required

## Response `200`

The updated policy, and the suggestion that was applied.

- object
  - `policy` Policy
    - `version` 1, required
    - `fallback` 'allow' | 'redact' | 'approve' | 'block', required: What happens to a kind no rule mentions.
    - `rules` Rule[], required
      - `kind` 'secret' | 'card' | 'iban' | 'ssn' | 'govid' | 'email' | 'phone' | 'address' | 'postcode' | 'name' | 'host', required
      - `decision` 'allow' | 'redact' | 'approve' | 'block', required
      - `tools` string[]: Only these tools. Exact, or a single trailing "*". Absent means all.
      - `direction` 'outbound' | 'inbound': Absent means both.
    - `denyTools` string[]: Tools that may not be called at all, whatever is inside them.
    - `allow` string[]: Literal values that are never sensitive here. A leading "@" exempts a whole domain. These are stored, unlike anything in the audit trail.
    - `gatewayAllow` string[]: Hosts the gateway may forward to. Empty or absent means any public host. A leading "." matches a domain and its subdomains. Private-address rules still apply and cannot be opened up from here.
    - `webhook` object: Where to POST when an action is refused. The payload is the audit record, which holds kinds and locations and never values.
      - `url` string, required: https only. Private and link-local addresses are refused, as everywhere else.
      - `on` string[]: Which decisions to send. Defaults to blocks only — a notification on every allowed action is one nobody reads.
      - `secret` string: When set, each delivery carries X-Secure-AI-Signature: sha256=<hmac of the body>.
    - `approvalTtlSeconds` integer: How long a held action waits before it is denied. Expiry is a denial and never a release — an action somebody wanted reviewed must not proceed because nobody had time to review it.
  - `applied` Suggestion: A rule the trail implies. Offered with its evidence; applying it is a separate, explicit call.
    - `id` string, required: Stable across calls, so one can be dismissed or applied.
    - `title` string, required
    - `because` string, required: The evidence, with the numbers that produced it.
    - `rule` Rule: One line of policy. When two rules match the same finding, the later one wins.
      - `kind` 'secret' | 'card' | 'iban' | 'ssn' | 'govid' | 'email' | 'phone' | 'address' | 'postcode' | 'name' | 'host', required
      - `decision` 'allow' | 'redact' | 'approve' | 'block', required
      - `tools` string[]: Only these tools. Exact, or a single trailing "*". Absent means all.
      - `direction` 'outbound' | 'inbound': Absent means both.
    - `denyTool` string: Set instead of `rule` when the suggestion is about a tool rather than a kind.
    - `direction` 'tighter' | 'looser' | 'advisory', required: Whether acting on this narrows or widens the policy. A UI should never present the two in one undifferentiated list.
    - `count` integer, required

## Other responses

- `401`: Missing or invalid credentials.
- `404`: No current suggestion with that id — they change as activity does.

---

[API](https://skmtc.dev/secureai/apis/secure-ai.md) · [All operations](https://skmtc.dev/secureai/apis/secure-ai/llms.txt) · [OpenAPI document](https://skmtc.dev/secureai/apis/secure-ai/revisions/6eefd7f53f8b?raw)
