Skip to content

Add Inbound Email API support - #251

Merged
mklocek merged 6 commits into
mainfrom
inbound-v2
Aug 4, 2026
Merged

Add Inbound Email API support#251
mklocek merged 6 commits into
mainfrom
inbound-v2

Conversation

@mklocek

@mklocek mklocek commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Inbound Email API support to the .NET SDK, matching the released Node, Ruby, MCP, PHP, Python, and Java SDKs. Exposed as client.Inbound() — token-scoped (no accountId), hanging off the root MailtrapClient like Organization().

The resource tree mirrors the API's own (irregular) routing:

client.Inbound().Folders()                 // GET list, POST create
client.Inbound().Folder(id)                // GET, PATCH, DELETE
client.Inbound().Folder(id).Inboxes()      // GET list, POST create
client.Inbound().Folder(id).Inbox(id)      // GET, PATCH, DELETE (folder-scoped)
client.Inbound().Inbox(id).Messages()      // List (cursor via lastId)
client.Inbound().Inbox(id).Message(id)     // GetDetails, Delete, Reply/ReplyAll/Forward
client.Inbound().Inbox(id).Threads()       // List
client.Inbound().Inbox(id).Thread(id)      // GetDetails, Delete

Inbox management is folder-scoped (/api/inbound/folders/{fid}/inboxes/{id}); messages and threads are top-level inbox-scoped (/api/inbound/inboxes/{iid}/...), so an inbox is reachable two ways — matching the API.

Also carries the other fields that ship with the Inbound Email API:

  • EmailLogMessage: RfcMessageId, InReplyTo, References, ThreadId
  • SendingDomain: InboundEnabled, InboundVerified
  • Webhook / CreateWebhookRequest / UpdateWebhookRequest: InboundInboxId, plus a new WebhookType.InboundReceiving

Notes

  • Inbound endpoints use no data/resource envelope, so requests post flat and responses deserialize directly — no request/response DTOs (unlike webhooks).
  • Reply/ReplyAll take ReplyInboundMessageRequest; Forward takes ForwardInboundMessageRequest, which validates a non-empty To (the one universally-enforced rule). Reply body is not validated client-side, consistent with the other SDKs.
  • Thread-message enums follow the SDK's StringEnum convention: ThreadMessageVisibilityStatus, ThreadMessageDirection; DeliveryStatus reuses the existing EmailLogStatus.
  • Reply/forward reuse the existing EmailAddress and Attachment models.
  • No DI changes: resources are constructed directly and validators are static .Instance.

Summary by CodeRabbit

  • New Features
    • Added Inbound Email API support for managing folders and inboxes.
    • Added message and thread retrieval, cursor-based pagination, deletion, replies, reply-all, and forwarding.
    • Added inbound attachment, threading, message direction, and visibility details.
    • Added inbound webhook configuration and sending-domain status fields.
  • Documentation
    • Documented Inbound Email capabilities and linked to a working example application.
  • Examples
    • Added a complete inbound email workflow example with configuration and logging.

mklocek added 5 commits July 31, 2026 17:28
Add the public surface for the token-scoped Inbound Email API: the
resource-tree interfaces (folders, inboxes, messages, threads), models,
requests with the forward recipient validator, response types, and the
thread-message visibility/direction string enums. Delivery status reuses
the existing EmailLogStatus.
Add the internal resource implementations for the Inbound Email API
(folders, inboxes, messages, threads) and expose them through
MailtrapClient.Inbound(). Requests are posted flat and responses are
deserialized directly, as the inbound endpoints use no data envelope.
Add the inbound URL segments.
Add inbound threading fields (rfc_message_id, in_reply_to, references,
thread_id) to email-log messages, inbound flags (inbound_enabled,
inbound_verified) to sending domains, and the optional inbound_inbox_id
to the webhook model and create/update requests. Add the
inbound_receiving webhook type so inbound webhooks can be created and
deserialized.
Add unit tests (constructor guards and resource URI construction) and
integration tests (MockHttp URL/verb checks with JSON fixtures) for the
inbound folders, inboxes, messages, and threads resources. Extend
coverage for the surfaced fields: sending-domain inbound flags, and
serialization tests for the webhook inbound_inbox_id / inbound_receiving
type and the email-log threading fields.
Add a Mailtrap.Example.Inbound console project demonstrating the inbound
folders, inboxes, messages, and threads resources (CRUD, pagination,
reply/reply-all/forward), register it in the solution, and link it from
the README.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cfe3aa26-d1a5-4351-aecc-c499e2079f73

📥 Commits

Reviewing files that changed from the base of the PR and between 94f61a6 and 6512fbd.

📒 Files selected for processing (4)
  • examples/Mailtrap.Example.Inbound/InboundReactor.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ForwardInboundMessageRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ReplyInboundMessageRequest.cs
  • tests/Mailtrap.IntegrationTests/Inbound/InboundMessagesIntegrationTests.cs
💤 Files with no reviewable changes (4)
  • examples/Mailtrap.Example.Inbound/InboundReactor.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ReplyInboundMessageRequest.cs
  • tests/Mailtrap.IntegrationTests/Inbound/InboundMessagesIntegrationTests.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ForwardInboundMessageRequest.cs

📝 Walkthrough

Walkthrough

Added a complete Inbound Email API to the .NET SDK. The change includes public models and resources, CRUD and messaging operations, pagination, webhook and domain fields, integration and unit tests, documentation, and an executable example project.

Changes

Inbound Email API

Layer / File(s) Summary
Public contracts and models
src/Mailtrap.Abstractions/Inbound/..., src/Mailtrap.Abstractions/EmailLogs/..., src/Mailtrap.Abstractions/Webhooks/..., src/Mailtrap.Abstractions/SendingDomains/...
Adds inbound resource interfaces, message and thread models, request and response records, pagination cursors, validators, threading metadata, and inbound webhook and domain fields.
REST resource implementation
src/Mailtrap/Inbound/..., src/Mailtrap/MailtrapClient.cs, src/Mailtrap/Core/Constants/UrlSegments.cs
Adds folder, inbox, message, and thread resources with CRUD, pagination, reply, reply-all, forward, deletion, validation, and URL construction.
Integration and unit validation
tests/Mailtrap.IntegrationTests/Inbound/..., tests/Mailtrap.UnitTests/Inbound/..., tests/Mailtrap.UnitTests/Webhooks/...
Tests HTTP methods, URLs, payloads, deserialization, pagination, message actions, validation, resource construction, and webhook fields.
Example application and documentation
examples/Mailtrap.Example.Inbound/..., README.md, Mailtrap.sln
Adds an inbound example application, solution mappings, launch configuration, processing workflows, cleanup operations, and supported-functionality documentation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Application
  participant MailtrapClient
  participant InboundResource
  participant REST_API
  Application->>MailtrapClient: Inbound()
  MailtrapClient->>InboundResource: Create inbound resource
  Application->>InboundResource: Access folders and inbox content
  InboundResource->>REST_API: GET, POST, PATCH, or DELETE inbound resources
  REST_API-->>Application: Return folders, inboxes, messages, threads, or send results
Loading

Possibly related PRs

Suggested reviewers: igordobryn, leonid-shevtsov

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: adding Inbound Email API support.
Description check ✅ Passed The description gives detailed motivation and changes, but it omits the template's test checklist and images section.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/Mailtrap.Example.Inbound/InboundReactor.cs`:
- Around line 25-37: Update Process to wrap resource creation and processing in
try/finally, tracking the successfully created InboundFolder and InboundInbox.
In the finally block, delete the inbox before the folder when each resource
exists, ensuring cleanup runs after failures as well as successful processing.
- Around line 90-110: Make the default flow in the inbound example read-only by
removing or gating the Reply, ReplyAll, Forward, and Delete calls behind
explicit configuration. If enabled, require recipients supplied through
user-controlled configuration rather than hardcoded addresses, and preserve the
existing message inspection behavior by default.

In `@README.md`:
- Around line 282-284: Update the “Inbound Email” README entry to limit the CRUD
claim to folders and inboxes, and describe messages and threads separately using
only their supported list, detail, delete, and send-action operations.

In `@tests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.json`:
- Around line 2-38: The detail fixture at
tests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.json must
include a third placeholder message for thread thr_1, using
ThreadMessageVisibilityStatus.Placeholder and matching the expected placeholder
shape, so its messages count aligns with message_count 3. The list fixture at
tests/Mailtrap.IntegrationTests/Inbound/Threads/List_Success.json requires no
direct change; use it as the reference for the expected placeholder entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4020f6de-ab69-4a0e-92bd-3632764f4640

📥 Commits

Reviewing files that changed from the base of the PR and between e9a931e and 94f61a6.

📒 Files selected for processing (95)
  • Mailtrap.sln
  • README.md
  • examples/Mailtrap.Example.Inbound/InboundReactor.cs
  • examples/Mailtrap.Example.Inbound/Mailtrap.Example.Inbound.csproj
  • examples/Mailtrap.Example.Inbound/Program.cs
  • examples/Mailtrap.Example.Inbound/Properties/launchSettings.json
  • examples/Mailtrap.Example.Inbound/appsettings.json
  • src/Mailtrap.Abstractions/EmailLogs/Models/EmailLogMessage.cs
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs
  • src/Mailtrap.Abstractions/GlobalUsings.cs
  • src/Mailtrap.Abstractions/IMailtrapClient.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundFolderCollectionResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundFolderResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundInboxCollectionResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundInboxContentResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundInboxResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundMessageCollectionResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundMessageResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundThreadCollectionResource.cs
  • src/Mailtrap.Abstractions/Inbound/IInboundThreadResource.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundAttachment.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundFolder.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundInbox.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundMessage.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundThread.cs
  • src/Mailtrap.Abstractions/Inbound/Models/InboundThreadMessage.cs
  • src/Mailtrap.Abstractions/Inbound/Models/SendMessageResult.cs
  • src/Mailtrap.Abstractions/Inbound/Models/ThreadMessageDirection.cs
  • src/Mailtrap.Abstractions/Inbound/Models/ThreadMessageVisibilityStatus.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/CreateInboundFolderRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/CreateInboundInboxRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ForwardInboundMessageRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/ReplyInboundMessageRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/UpdateInboundFolderRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Requests/UpdateInboundInboxRequest.cs
  • src/Mailtrap.Abstractions/Inbound/Responses/InboundMessagesListResponse.cs
  • src/Mailtrap.Abstractions/Inbound/Responses/InboundThreadsListResponse.cs
  • src/Mailtrap.Abstractions/Inbound/Validators/ForwardInboundMessageRequestValidator.cs
  • src/Mailtrap.Abstractions/SendingDomains/Models/SendingDomain.cs
  • src/Mailtrap.Abstractions/Webhooks/Models/Webhook.cs
  • src/Mailtrap.Abstractions/Webhooks/Models/WebhookType.cs
  • src/Mailtrap.Abstractions/Webhooks/Requests/CreateWebhookRequest.cs
  • src/Mailtrap.Abstractions/Webhooks/Requests/UpdateWebhookRequest.cs
  • src/Mailtrap/Core/Constants/UrlSegments.cs
  • src/Mailtrap/GlobalUsings.cs
  • src/Mailtrap/Inbound/InboundFolderCollectionResource.cs
  • src/Mailtrap/Inbound/InboundFolderResource.cs
  • src/Mailtrap/Inbound/InboundInboxCollectionResource.cs
  • src/Mailtrap/Inbound/InboundInboxContentResource.cs
  • src/Mailtrap/Inbound/InboundInboxResource.cs
  • src/Mailtrap/Inbound/InboundMessageCollectionResource.cs
  • src/Mailtrap/Inbound/InboundMessageResource.cs
  • src/Mailtrap/Inbound/InboundResource.cs
  • src/Mailtrap/Inbound/InboundThreadCollectionResource.cs
  • src/Mailtrap/Inbound/InboundThreadResource.cs
  • src/Mailtrap/MailtrapClient.cs
  • tests/Mailtrap.IntegrationTests/GlobalUsings.cs
  • tests/Mailtrap.IntegrationTests/Inbound/Folders/Create_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Folders/GetAll_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Folders/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Folders/Update_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/InboundFoldersIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/Inbound/InboundInboxesIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/Inbound/InboundMessagesIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/Inbound/InboundThreadsIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/Inbound/Inboxes/Create_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Inboxes/GetAll_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Inboxes/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Inboxes/Update_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/Forward_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/List_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/List_WithCursor_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/ReplyAll_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Messages/Reply_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Threads/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/Inbound/Threads/List_Success.json
  • tests/Mailtrap.IntegrationTests/SendingDomains/GetDetails_Success.json
  • tests/Mailtrap.IntegrationTests/SendingDomains/SendingDomainIntegrationTests.cs
  • tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs
  • tests/Mailtrap.UnitTests/EmailLogs/EmailLogMessageThreadingFieldsTests.cs
  • tests/Mailtrap.UnitTests/GlobalUsings.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundFolderCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundFolderResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundInboxCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundInboxContentResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundInboxResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundMessageCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundMessageResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundThreadCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/Inbound/InboundThreadResourceTests.cs
  • tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs
  • tests/Mailtrap.UnitTests/Webhooks/WebhookInboundFieldsTests.cs

Comment thread examples/Mailtrap.Example.Inbound/InboundReactor.cs
Comment thread examples/Mailtrap.Example.Inbound/InboundReactor.cs
Comment thread README.md
Comment thread examples/Mailtrap.Example.Inbound/InboundReactor.cs Outdated
The inbound SendMessageInput has no subject field - reply/reply_all
derive it (Re: prefix) and forward uses Fwd:. Drop the erroneous subject
from the reply/forward request models, example, and tests.
@mklocek
mklocek merged commit 0a815f9 into main Aug 4, 2026
3 checks passed
@mklocek
mklocek deleted the inbound-v2 branch August 4, 2026 13:07
@github-actions github-actions Bot mentioned this pull request Aug 4, 2026
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.

3 participants