# Secure-send disclosure

When a send or a saved draft involves a **secure link** to an [encrypted area](/docs/api-reference/encrypted-areas/introduction),
the response carries an optional `disclosures` array. Each entry is one compact, **non-blocking**
row telling the user something true about that specific send — that the key travels inside the
link, that a saved copy could not keep it, or that an undo hold was skipped.

`disclosures` is **additive and optional**. It is `null` or omitted on every send that does not
involve a secure link, so a client that ignores the field is unaffected.

## Where it appears

| Endpoint | Where |
|  --- | --- |
| [Send a freeform message to a contact](/api-reference/conversations/contacts/send-contact-message) | On all three response shapes — the delivered send, the scheduled acknowledgement, and the undo-held acknowledgement. |
| [Save a conversation draft](/api-reference/conversations/drafts/save-draft) | On the returned `draft` object. |


No other conversations endpoint emits it today. In particular, [List scheduled
messages](/api-reference/conversations/scheduled/list-scheduled) and [Update a scheduled
message](/api-reference/conversations/scheduled/update-scheduled) return the stored scheduled
message and carry no `disclosures` field.

## The object

**`kind`** string — Which disclosure this is. One of:

| `kind` | Meaning | `severity` |
|  --- | --- | --- |
| `external_channel_send` | The key travels inside a link that was sent on a channel. | `warning` |
| `link_handoff` | The link was handed back to the sender to pass on themselves. | `warning` |
| `recipient_bound` | Sealed to one account — no link and no key travelling. | `info` |
| `secure_link_stripped` | A durable copy (a saved draft, or an internal-channel message) could not keep the working link. | `warning` |
| `schedule_refused` | The send went out immediately because a secure link cannot be held or scheduled. | `info` |


**`severity`** string — `info` or `warning`. **Derived from `kind`, never chosen by the caller** —
`warning` means the key travels in a link or a durable copy lost it; `info` means nothing degraded.

**`channel`** string or null — The channel the send goes out on (`email`, `slack`, `whatsapp`,
`imessage`, `teams`, `internal`), or `null` when there is no channel. For
`kind: "secure_link_stripped"`, `channel: "internal"` identifies the internal-channel case and any
other value (including `null`) identifies the saved-draft case.

**`headline`** string — One short sentence, at most 90 characters. The whole point of the row.

**`detail`** string — One sentence, at most 240 characters, explaining the headline.

**`points`** array of string — Zero to three short supporting lines. Render as a compact list, not
as prose.

**`controls`** object — The three per-send controls as **facts, never values**:
`{ "password_required": boolean, "burn_after_read": boolean, "expires_at": ISO-8601 string or null for never }`. The password itself is never included.

On a **recipient-bound** send, only `password_required` is forced off — that format is sealed to
the recipient's identity and has nowhere to put password material. `burn_after_read` and
`expires_at` are **server-side state checked at open time and are enforced on both crypto modes**,
so they are reported exactly as requested. This page previously said all three were off on a
recipient-bound send; that was true before burn and expiry moved server-side and has been
corrected — reporting a sender's burn-after-read as off while the server enforces it is the more
dangerous direction of the two.

**`blocking`** boolean — **Always `false`.** The disclosure is an in-line row and pressing Send is
the acknowledgment. There is never a second confirm step and never a full-screen wall.

## What it never contains

A disclosure states that a protection is **on**, never what it is. It never contains:

- the secure link,
- the decryption key that travels in the link's fragment,
- the password.


## Rendering guidance

- Render each entry as **one small in-line row** next to the composer or on the sent message —
never as a modal, an interstitial, or a blocking confirm. `blocking` is typed as a literal
`false` server-side precisely so a blocking disclosure is unrepresentable.
- Use `severity` for the visual weight, `headline` for the row's text, `detail` for the expanded
line, and `points` for a compact bullet list.
- Treat an unknown future `kind` gracefully: `headline` / `detail` / `points` are always present
and always renderable, so a client can display any entry without knowing its `kind`.


## Example


```json
{
  "disclosures": [
    {
      "kind": "external_channel_send",
      "severity": "warning",
      "channel": "teams",
      "headline": "Anyone with this link can open it.",
      "detail": "The decryption key travels inside the link, so whoever receives or forwards it can open the message.",
      "points": [
        "We do not store the key — our copy of this message keeps the link without it.",
        "Your extra protection on this send is already applied."
      ],
      "controls": {
        "password_required": true,
        "burn_after_read": false,
        "expires_at": "2026-08-06T09:00:00Z"
      },
      "blocking": false
    }
  ]
}
```

## Related Resources

- [Encrypted areas](/docs/api-reference/encrypted-areas/introduction)
- [Send a freeform message to a contact](/api-reference/conversations/contacts/send-contact-message)
- [Save a conversation draft](/api-reference/conversations/drafts/save-draft)
- [Fetch a secure-link encrypted area](/docs/api-reference/encrypted-areas/fetch-secure-link)