From 55df6264c1533bea97371de425aabecad3509e9e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 21:07:58 +0000 Subject: [PATCH] fix(sdk): correct blocked-message docs; drop non-existent blockedReason field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review of senderkit-app main since the last SDK sync (PR #44, which covered app PRs through #198) — app PRs #199 → #211. App PR #211 ("keep spam-detection detail out of customer-visible surfaces") makes explicit and enforces that the abuse-scan detail is operator-only: the public message read surface (`GET /api/v1/messages` list/get, used by `messages.list`/`messages.get`) projects a lean column set that has never included `blocked_reason`. The SDK's `Message.blockedReason` field (added in PR #44 on the assumption it was readable) was therefore never populated by the API and is misleading. - types.ts: remove `Message.blockedReason`; reword the `status` doc so a `blocked` message is identified by its status + generic `timeline` entry. - mcp-schemas.ts: drop the comment claiming the trigger is on `blockedReason`. `blocked` stays in MESSAGE_STATUSES (unchanged). Non-breaking: the field was always `undefined` and `Message` keeps its index signature. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_019CX1MwgJt4TBjL8RnG9hax --- .changeset/correct-blocked-reason.md | 5 +++++ packages/sdk/src/mcp-schemas.ts | 3 ++- packages/sdk/src/types.ts | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .changeset/correct-blocked-reason.md diff --git a/.changeset/correct-blocked-reason.md b/.changeset/correct-blocked-reason.md new file mode 100644 index 0000000..81545e0 --- /dev/null +++ b/.changeset/correct-blocked-reason.md @@ -0,0 +1,5 @@ +--- +"@senderkit/sdk": patch +--- + +Correct the `blocked` message documentation. The detailed abuse-scan trigger is operator-only and is never returned on the public message read surface (`messages.list` / `messages.get`), so the previously-documented `Message.blockedReason` field (which the API never populated) has been removed. A blocked message is identified by its `blocked` status and a generic entry on its `timeline`. The `blocked` status itself is unchanged. diff --git a/packages/sdk/src/mcp-schemas.ts b/packages/sdk/src/mcp-schemas.ts index 0dec5e3..5d46121 100644 --- a/packages/sdk/src/mcp-schemas.ts +++ b/packages/sdk/src/mcp-schemas.ts @@ -122,7 +122,8 @@ const emailEnvelope = { * The ten message lifecycle statuses (mirrors the app's `messageStatusEnum`). * Bounces normalize to `failed` with the reason on the message timeline. * `blocked` is a terminal state set when the outbound abuse scanner halts a - * send (the human-readable trigger is on the message's `blockedReason`). + * send. The detailed trigger is operator-only and is never returned on the + * message; a blocked message carries only a generic reason on its timeline. */ export const MESSAGE_STATUSES = [ "scheduled", diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index a3345e7..7b14769 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -195,15 +195,15 @@ export interface Message { publicId: string; /** * Lifecycle status (one of `MESSAGE_STATUSES`). A `blocked` message was - * halted by the outbound abuse scanner; `blockedReason` carries the trigger. + * halted by the outbound abuse scanner. The detailed trigger is operator-only + * and is not returned here — a blocked message exposes only its `blocked` + * status and a generic entry on its `timeline`. */ status: string; channel: Channel; templateSlug: string | null; recipient: string; createdAt: string; - /** Human-readable reason a `blocked` message was halted. Absent otherwise. */ - blockedReason?: string | null; [key: string]: unknown; }