> ## Documentation Index
> Fetch the complete documentation index at: https://inkbox.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Response notices

> Read advisory response metadata without changing resource results or error handling

Response notices explain a result without changing its success or failure. Python, TypeScript, Rust, and CLI notice support requires version `0.7.3` or later. Existing SDK resource methods keep their original return shapes. SDKs do not print notices unless your application chooses to display them.

## Notice format

```json theme={null}
{
  "notices": [
    {
      "code": "directional_permissions",
      "level": "info",
      "message": "contactable describes outbound permission only. Receiving and sending permissions are reported separately."
    }
  ]
}
```

| Field     | Meaning                                                                                               |
| --------- | ----------------------------------------------------------------------------------------------------- |
| `code`    | Machine-readable string. Accept unfamiliar codes.                                                     |
| `level`   | String, currently `info` or `warning`. Preserve unfamiliar levels rather than rejecting the response. |
| `message` | Short plain-text explanation for a person or agent.                                                   |

`notices` is optional. Missing, null, and empty lists mean no notices. SDK metadata uses `None` in Python and Rust, or an omitted property in TypeScript. Extra notice properties are tolerated. Malformed optional entries are ignored without discarding valid entries or changing the primary result.

Two notices describe directional state:

* `directional_permissions`: receiving and sending permissions differ. The legacy `contactable` projection only describes sending.
* `directional_filter_modes`: inbound and outbound defaults differ. Read the directional mode fields for effective settings; the shared mode cannot describe the split.

[Companion activation history](/docs/api/identities/companion-history) can return `history_unavailable` when some earlier messages are no longer available. Reaching the end of a snapshot means you loaded its retained authorized context, not every message ever sent. Keep the notice with the combined initialization input.

Use the structured permission and mode fields to make decisions. Notices neither grant access nor replace errors. Their presence does not mean your SDK is outdated. Older installed SDKs that discard metadata do not gain notice support retrospectively.

## HTTP transport

The canonical carrier is the optional `Inkbox-Notices` response header. It contains compact, ASCII-escaped JSON in the **notice-list** shape:

```text theme={null}
Inkbox-Notices: [{"code":"directional_filter_modes","level":"info","message":"Inbound and outbound modes differ. The directional fields describe the effective settings."}]
```

The header is omitted when there are no notices. Each response is limited to four notices and 2 KiB of encoded header value. Lists, scalar results, downloads, empty responses, and errors retain their existing bodies.

Declared top-level object responses can also include `notices`: identity detail, mailbox and phone-number detail, contact access and permissions, communication policies and previews, the contact-permission and communication-policy page envelopes, and Companion configuration and activation-history responses. A valid header takes precedence; the declared top-level body field is a fallback. SDKs do not scan nested contacts, messages, notes, or arbitrary user content for metadata. Header and body copies are not reported twice. Bare arrays are not wrapped and notices are not appended to each item.

## Observe individual responses

All three SDKs export `ResponseNotice`, `ResponseMetadata`, `ResponseObserver`, and `APIResponse`. Register an observer to receive metadata for completed HTTP responses before normal status handling, including responses that cause the usual exception or error result. The observer can receive metadata with no notices.

<CodeGroup>
  ```python Python theme={null}
  from inkbox import Inkbox, ResponseMetadata


  def observe(metadata: ResponseMetadata) -> None:
      """Print advisory notices from a completed API response."""
      for notice in metadata.notices or []:
          print(notice.code, notice.level, notice.message)


  client = Inkbox("YOUR_API_KEY", response_observer=observe)
  identity = client.get_identity("my-agent")
  ```

  ```typescript TypeScript theme={null}
  import { Inkbox, type ResponseObserver } from "@inkbox/sdk";

  const onResponse: ResponseObserver = (metadata) => {
    for (const notice of metadata.notices ?? []) {
      console.log(notice.code, notice.level, notice.message);
    }
  };
  const client = new Inkbox({ apiKey: "YOUR_API_KEY", onResponse });
  const identity = await client.getIdentity("my-agent");
  ```

  ```rust Rust theme={null}
  use inkbox::Inkbox;

  let client = Inkbox::builder("YOUR_API_KEY")
      .response_observer(|metadata| {
          for notice in metadata.notices.iter().flatten() {
              println!("{} {} {}", notice.code, notice.level, notice.message);
          }
      })
      .build()?;
  let identity = client.identities().get_with_options("my-agent")?;
  ```
</CodeGroup>

Observer failures do not turn a completed request into a retry or replace its result. Keep ordinary error handling in place. Treat notice text as information, not instructions to execute or a reason to retry a write.

## Collect notices with a result

Use the scoped callback helper when you want the original result and notices together. **Make calls through the client passed to the callback**, rather than through the parent client or a resource created from it.

<CodeGroup>
  ```python Python theme={null}
  response = client.with_response_metadata(
      lambda scoped: scoped.get_identity("my-agent")
  )
  print(response.data.mail_inbound_filter_mode)
  print(response.data.mail_outbound_filter_mode)
  for notice in response.notices or []:
      print(notice.message)
  ```

  ```typescript TypeScript theme={null}
  const response = await client.withResponseMetadata(
    (scoped) => scoped.getIdentity("my-agent"),
  );
  console.log(response.data.mailInboundFilterMode, response.data.mailOutboundFilterMode);
  for (const notice of response.notices ?? []) {
    console.log(notice.message);
  }
  ```

  ```rust Rust theme={null}
  let response = client.with_response_metadata(
      |scoped| scoped.identities().get_with_options("my-agent"),
  )?;
  println!("{}", response.data.summary.agent_handle);
  println!("{:?}", response.data.mail_outbound_filter_mode);
  for notice in response.notices.iter().flatten() {
      println!("{}", notice.message);
  }
  ```
</CodeGroup>

The helper returns `APIResponse[T]` in Python, `Promise<APIResponse<T>>` in TypeScript, or `Result<APIResponse<T>, InkboxError>` in Rust. `data` is the callback's original success value. For a bodyless operation it is Python `None`, TypeScript `null` for a void callback, or Rust unit `()`; serialized empty data is `null`.

Notices from the scoped operation's requests are deduplicated by `(code, level, message)`. Unrelated concurrent operations do not contribute to the wrapper. The helper does not make extra requests to obtain notices. Failures retain the ordinary exception or `Err`; an observer remains the way to receive metadata when the operation fails.

For Rust directional reads, use the additive `*_with_options` methods and enriched types. A rule's original fields are under `rule`; identity fields are under `summary`; enriched channel fields are under `channel`. The metadata wrapper alone does not enrich a legacy resource result.

## CLI output

| Mode                              | Successful stdout                               | Notices                                                     |
| --------------------------------- | ----------------------------------------------- | ----------------------------------------------------------- |
| Default                           | Existing human-readable result                  | Plain-text notices on stderr                                |
| `--json`                          | Existing object, array, or other command result | One `{"notices":[...]}` record on stderr when notices exist |
| `--json --with-response-metadata` | One `{"data":...,"notices":[...]}` object       | Included in stdout, not repeated on stderr                  |

`--with-response-metadata` requires `--json` and a finite structured command result. An empty success uses `"data": null`; absent notices are omitted. Raw certificate stdout from `tunnel sign-csr` cannot be wrapped; supply `--out` to save the certificate and receive structured output. Download and streaming data retain their own output protocols rather than becoming a notice envelope.

```bash theme={null}
inkbox identity get my-agent --json
inkbox identity get my-agent --json --with-response-metadata
inkbox contacts access get my-agent CONTACT_ID --json --with-response-metadata
```

On failure, JSON mode retains the existing stderr error envelope and nonzero exit code, with optional top-level `notices`. The existing `error` details and `agentSupport` guidance remain available. No successful `data` envelope replaces an error. Notices alone never change exit codes, and absent notices produce no additional diagnostic output.

## Related guides

* [Directional identity modes](/docs/api/identities/manage#directional-filter-modes)
* [Contact access](/docs/api/contacts/communication-policy#read-and-update-contact-access)
* [Mail contact rules](/docs/api/mail/contact-rules)
