Skip to content

feat(sdk): add the blocked message status from outbound abuse scanning#44

Merged
tuyakhov merged 2 commits into
mainfrom
claude/amazing-bardeen-in2ku4
Jun 17, 2026
Merged

feat(sdk): add the blocked message status from outbound abuse scanning#44
tuyakhov merged 2 commits into
mainfrom
claude/amazing-bardeen-in2ku4

Conversation

@tuyakhov

Copy link
Copy Markdown
Contributor

Why

Review of senderkit-app main since the last SDK sync (PR #41, which covered app changes through #168) — app PRs #169 → #198. Almost all of that window is marketing/SEO, Supabase inbound-hook integrations, analytics/admin-impersonation, and billing/pricing config — none of which touch the SDK's outbound API contract. The one change that does is the new outbound anti-phishing detection (app #196, refined by #198).

That feature scans rendered email/SMS content asynchronously and, on a high-confidence verdict in enforce mode, halts the send. The message lands in a brand-new terminal status blocked (added to the app's messageStatusEnum) with a human-readable blockedReason column. The synchronous send response is unchanged (still queued/scheduled), so send/sendRaw and the error classes need no changes — but the read surface does.

What changed

MCP / CLI (packages/sdk/src/mcp-schemas.ts)

  • Added blocked to MESSAGE_STATUSES (between opted_out and canceled), keeping it in lockstep with the app enum.
  • This matters functionally: senderkit_messages_list.status is a strict z.enum(MESSAGE_STATUSES), so before this change the MCP/CLI tool rejected status: "blocked" as invalid input — callers could not filter for blocked messages. The filter description string now lists blocked too.

SDK types (packages/sdk/src/types.ts)

  • Documented blocked on Message.status and added the optional Message.blockedReason?: string | null field. (status stays string and Message keeps its index signature, so this is non-breaking.)

Changeset

  • @senderkit/sdk: minor, @senderkit/cli: patch.

Not changed (and why)

  • Send request/response & error classes — the abuse block is applied asynchronously after the send is accepted; the synchronous contract (SendResponse, SenderKit*Error) is untouched.
  • Billing/pricing (app #195) — new Starter tier, Pro capped at 50k, Free message/template caps retuned. Pure server-side config + pricing UI; existing error codes (template_limit_reached, quota 409) are unchanged and the SDK doesn't model plans/quota.
  • Inbound-hook gateways (app #178 Supabase, #190 generic adapter) — these are ingress endpoints external systems POST to, separate from the SDK's outbound api.senderkit.com surface.
  • Marketing/SEO (#171–177, #197), Supabase UI/nav (#183–189), analytics & admin impersonation (#169, #191–194) — no public API impact.

Verification

pnpm build and pnpm test pass (sdk 58, cli 80, react-email 29).

🤖 Generated with Claude Code


Generated by Claude Code

senderkit-app now runs outbound anti-phishing detection over email and SMS
(app #196). A flagged send is halted and the message lands in a new terminal
`blocked` state with a `blockedReason`.

- Add `blocked` to `MESSAGE_STATUSES`, mirroring the app's `messageStatusEnum`.
  The `senderkit_messages_list.status` MCP/CLI filter is a strict
  `z.enum(MESSAGE_STATUSES)`, so it previously rejected `status: "blocked"` as
  invalid input.
- Document `blocked` on `Message.status` and add the optional
  `Message.blockedReason` field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A299AvEPRfoWPP3Hq5NJGa
@tuyakhov tuyakhov merged commit 094b8ae into main Jun 17, 2026
1 check passed
@tuyakhov tuyakhov deleted the claude/amazing-bardeen-in2ku4 branch June 17, 2026 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants