feat: inbound receiving addresses and received mail - #12
Merged
Conversation
Mirrors the TypeScript SDK's new `inbound` resource area on both the sync and async clients: - `client.inbound.addresses` — list / create / delete addresses on the workspace's shared receiving domain. - `client.inbound.messages` — list / get received messages, plus `raw()` and `attachment(index)` returning raw bytes. - New models: InboundAddress, InboundMessage(+Summary), InboundAttachment, InboundBytes. Requires an API key with the `inbound` scope. Tests cover the address CRUD and message read/raw/attachment paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Ws2dq33N1tvwrWakzqgxL
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Extends inbound support with the phase-2 capabilities now on the API: claim a custom domain to receive on (alongside the shared receiving domain), and provision catch-all addresses. Covers both the sync and async clients. - client.inbound.domains — list(), create(domain, ...), delete(id) on both Inbound and AsyncInbound. create() returns the DNS records to publish; an existing-MX conflict surfaces as a 409 SenderKitAPIError so callers can confirm before redirecting mail. - inbound.addresses.create() gains domain_id and livemode; local_part "*" provisions a catch-all. - New models: InboundDomain, InboundDnsRecord. Tests: ruff, mypy, and pytest all pass.
CI installs the dev extra with a floating `ruff>=0.5`, so it picks up ruff 0.16, which formats Python code blocks inside Markdown by default. That makes `ruff format --check .` reformat README.md and fail, even though the pinned ruff-pre-commit hook (0.15.17) and local runs are clean. Pin `ruff==0.15.17` in the dev extra so CI matches the pre-commit hook and the lint gate is deterministic. No source changes.
CI installs the dev extra with a floating `ruff>=0.5`, so it picks up ruff 0.16, which formats Python code blocks inside Markdown by default. That makes `ruff format --check .` reformat README.md and fail, even though the pinned ruff-pre-commit hook (0.15.17) and local runs are clean. Pin `ruff==0.15.17` in the dev extra so CI matches the pre-commit hook and the lint gate is deterministic. No source changes.
…-pin ci(ruff): pin ruff below 0.16 to match the pinned pre-commit hook
…essages) Adds async-client tests for the new inbound domains methods and the async address-create params, plus the pre-existing async address/message paths that had no coverage. Raises patch coverage above the project target.
feat(inbound): custom receiving domains + catch-all addresses
CodeQL flags `assert <call> is True` because the call is skipped when asserts are disabled (python -O). Assign each delete() result to a local first, then assert on the value. Resolves the four "assert statement has a side-effect" code-scanning alerts on tests/test_inbound.py. No behavior change.
…assert test(inbound): resolve CodeQL "assert has a side-effect" alerts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for the inbound email API on both the sync and async clients:
provision addresses on a workspace's shared receiving domain and read the mail
sent to them. Access requires an API key with the
inboundscope. Received mailis surfaced through the existing webhook engine as a
message.receivedevent.client.inbound.addresses—list(),create(...),delete(id).client.inbound.messages—list(...),get(id), plusraw(id)andattachment(id, index)returning raw bytes.InboundAddress,InboundMessage,InboundMessageSummary,InboundAttachment,InboundBytes.This mirrors the matching change in the TypeScript and PHP SDKs so all three stay
in sync.
Related issues
Checklist
ruff check .passesruff format .appliedmypy srcpassespytestpasses (new behavior is covered by tests)Generated by Claude Code