Skip to content

Conversation

@dr-3lo
Copy link
Contributor

@dr-3lo dr-3lo commented Dec 29, 2025

This PR contain fixes of all C# code examples across OpenAPI files to match the lates mailtrap-dotnet SDK.

Motivation

Initial C# code examples in the OpenAPI (specs/*.openapi.yml) were inconsistent with the official .NET SDK examples and guides, what caused:

  • Missing required imports
  • Incorrect client initialization
  • Wrong method signatures and requests construction
  • Inconsistent constants naming

Key Improvements:

  • Missing imports were added
  • Fixed client initialization
  • Enhanced constants naming: YOUR_API_KEY & YOUR_ACCOUNT_ID applied to all examples
  • Corrected requests constructing logic

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced factory-based client initialization pattern for improved configuration management
    • Added fluent builder methods for constructing email and contact requests
    • New request types for events, exports, imports, lists, and fields operations
  • API Changes

    • Updated account and resource access method chains for improved clarity
    • Reorganized request type namespaces into dedicated modules
    • Enhanced webhook payload handling with improved type-safe extraction

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

This pull request updates OpenAPI specifications across seven files to introduce a factory-based client initialization pattern, fluent builder APIs for requests, and restructured API method chaining. Changes shift from direct client instantiation and object mutation to declarative factory creation and immutable request builders, affecting email sending, batch operations, contacts management, webhook handling, and general account operations.

Changes

Cohort / File(s) Summary
Email Sending & Batch Operations
specs/email-sending-transactional.openapi.yml, specs/email-sending-bulk.openapi.yml, specs/email-batch.openapi.yml
Replaced direct MailtrapClient("API_KEY") with MailtrapClientFactory pattern; introduced SendEmailRequest.Create() and BatchEmailRequest.Create() fluent builders; updated API calls from client.SendAsync() to client.Email().Send() and client.BatchEmail().Send(); added MailtrapClientOptions with ApiToken and UseBulkApi properties.
Account & General API
specs/general.openapi.yml
Migrated to factory-based client creation; pluralized account access entry point (Accounts() vs. Accounts); updated resource access patterns (e.g., Account(id).Accesses().Fetch(), Permissions().GetAll()); restructured billing and access management flows via updated client method chains.
Contact Management
specs/contacts.openapi.yml
Introduced MailtrapClientFactory for client creation; enabled object initializers for CreateContactRequest (ListIds, Fields); added specialized request types (CreateContactEventRequest, CreateContactExportRequest, CreateContactImportRequest, CreateUpdateContactListRequest, UpdateContactFieldRequest); updated method invocation from resource proxies to primary objects; added namespaces: Mailtrap.Contacts.Requests, Mailtrap.ContactExports.Requests, Mailtrap.ContactImports.Requests, Mailtrap.ContactFields.Requests.
Sandbox Environment
specs/sandbox.openapi.yml
Applied factory-based client pattern across project, inbox, message, and attachment operations; updated account/resource access patterns (Account(YOUR_ACCOUNT_ID)); added multiple request type namespaces (Mailtrap.Projects.Requests, Mailtrap.Inboxes.Requests, etc.); adjusted field naming conventions (e.g., UsernameUserName, ApiTokenApiKey); refactored email sending workflows to use new configuration approach.
Webhook Handling
specs/webhooks.openapi.yml
Added new WebhookPayload record type with [JsonPropertyName("events")] mapping; replaced direct property access with defensive TryGetProperty extraction and type-switching for event processing (delivery, bounce, open, click); updated response return value from Ok() to Ok("OK"); added System.Text.Json and Microsoft.AspNetCore.Mvc using directives.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

  • .NET examples for Email section #1 — Introduces the same factory-based client instantiation pattern (MailtrapClientFactory, CreateClient()) and updates account-scoped API chaining across multiple language implementations.

Suggested reviewers

  • mklocek
  • yanchuk
  • VladimirTaytor
  • leonid-shevtsov

Poem

🐰 A factory springs to life, so grand,
With fluent builders helping hands,
No more mutations left and right,
Just declarative, clean, and bright!
Request objects dance with flair,
While webhooks handle events with care. 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing .NET code examples in OpenAPI specifications to align with the mailtrap-dotnet SDK. It is concise, specific, and clearly summarizes the primary objective reflected across all file changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
specs/general.openapi.yml (1)

226-228: Clarify .NET factory initialization pattern across code samples.

The samples show two factory initialization patterns: general.openapi.yml uses new MailtrapClientFactory("YOUR_API_KEY") (simple string), while email-sending-bulk.openapi.yml and email-batch.openapi.yml use new MailtrapClientFactory(new MailtrapClientOptions { ApiToken = "...", UseBulkApi = true }) (config object). Document which pattern applies to each API context, or align samples consistently if one approach is preferred.

specs/sandbox.openapi.yml (2)

180-193: C# project & inbox samples: factory + fluent API usage looks consistent with mailtrap-dotnet

Across the project and inbox examples (create/list/get/update/delete and create inbox), the pattern:

  • using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY");
  • var client = mailtrapFactory.CreateClient();
  • Fluent navigation via .Account(YOUR_ACCOUNT_ID).Projects()/Project(id)/Inboxes()/Inbox(id)...

matches the official factory usage and fluent style described in the .NET client docs, and the request types (CreateProjectRequest, UpdateProjectRequest, CreateInboxRequest, UpdateInboxRequest) are imported from the expected namespaces. I don’t see API‑shape or flow issues here.

If you want to align more strongly with the security guidance in the .NET docs, consider reading the token from an environment variable (e.g., Environment.GetEnvironmentVariable("MAILTRAP_API_KEY")) instead of hardcoding "YOUR_API_KEY" in these snippets, but that’s optional given existing patterns in the spec.

Also applies to: 303-318, 425-437, 541-555, 682-694, 823-839, 940-953, 1038-1050, 1165-1184, 1288-1300, 1392-1404, 1496-1508, 1600-1613, 1704-1718, 1803-1815


1933-1959: Sandbox send & batch C# examples align with the new options-based .NET SDK surface

The sandbox email sending and batch sending snippets:

  • Use MailtrapClientOptions with ApiToken (and InboxId for sandbox) plus MailtrapClientFactory, consistent with the .NET quick‑start/config docs.
  • Build requests via SendEmailRequest.Create() / BatchEmailRequest.Create() fluent builders and send via .Email().Send(...) and .BatchEmail().Send(...).
  • Provide alternative flows via .Test(TEST_INBOX_ID).Send(...) and .BatchTest(TEST_INBOX_ID).Send(...), which fits the dedicated sandbox entry points described in the PR summary.

Overall these samples look correct and idiomatic for the updated SDK surface. As with other snippets, using an environment variable or configuration source instead of the literal "YOUR_API_KEY" would better reflect production best practices, but that’s non‑blocking for this PR.

Also applies to: 2172-2208

specs/contacts.openapi.yml (1)

191-213: C# contact core, events, imports, and exports: API usage matches the new SDK surface

For contact creation, retrieval, update, deletion, contact events, exports, and imports, the C# snippets consistently:

  • Initialize the client via using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient();
  • Scope operations under .Account(YOUR_ACCOUNT_ID) and then navigate through .Contacts(), e.g.:
    • .Contacts().Create(CreateContactRequest ...)
    • .Contact(contactIdOrEmail).GetDetails()/Update(request)/Delete()
    • .Contacts().Events("contact_id").Create(CreateContactEventRequest ...)
    • .Contacts().Exports().Create(...) / .Contacts().Export(exportId).GetDetails()
    • .Contacts().Imports().Create(...) / .Contacts().Import(importId).GetDetails()

Namespace imports like Mailtrap.Contacts.Requests, Mailtrap.ContactEvents.Requests, Mailtrap.ContactExports.*, and Mailtrap.ContactImports.Requests match the request types in use, so these examples should compile and mirror the intended SDK surface.

Only minor polish you might consider (optional): use an environment variable for the token in the snippets and align all C# labels to “.NET” for consistency with other specs.

Also applies to: 384-403, 514-522, 626-630, 712-718, 820-827, 923-926, 1042-1051, 1154-1159

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4249ac4 and 740bfc0.

📒 Files selected for processing (7)
  • specs/contacts.openapi.yml
  • specs/email-batch.openapi.yml
  • specs/email-sending-bulk.openapi.yml
  • specs/email-sending-transactional.openapi.yml
  • specs/general.openapi.yml
  • specs/sandbox.openapi.yml
  • specs/webhooks.openapi.yml
🧰 Additional context used
📓 Path-based instructions (1)
specs/**/*.openapi.yml

📄 CodeRabbit inference engine (CLAUDE.md)

specs/**/*.openapi.yml: Base URLs must never be changed in OpenAPI specs. Use https://send.api.mailtrap.io for transactional emails, https://bulk.api.mailtrap.io for bulk emails, and https://mailtrap.io for all other APIs
All documentation links in OpenAPI specs must be absolute URLs pointing to docs.mailtrap.io, not relative links or help.mailtrap.io
Update contact URLs in spec info blocks to use https://docs.mailtrap.io, not help.mailtrap.io
Use GitBook markdown syntax in OpenAPI description fields, ensuring all blocks are properly closed: {% hint %}...{% endhint %} and {% tab %}...{% endtab %}
Tabs cannot be nested inside details blocks when using GitBook syntax in OpenAPI descriptions
Include code samples in x-codeSamples in this priority order: Node.js, PHP, Python, Ruby, .NET, Java, cURL
Use official Mailtrap SDKs for language-specific code samples in x-codeSamples, with Node.js (mailtrap/mailtrap-nodejs), PHP (railsware/mailtrap-php), Python (railsware/mailtrap-python), and Ruby (railsware/mailtrap-ruby)
Use environment variables for API keys in code samples (e.g., process.env.MAILTRAP_API_KEY)
Validate YAML syntax, OpenAPI 3.1 compliance, base URLs, contact URLs, GitBook blocks, links, and code samples before committing OpenAPI spec changes
Do not use emojis in specification content
Keep OpenAPI descriptions concise and developer-focused, with technical accuracy prioritized
Use custom OpenAPI extensions for GitBook navigation: x-page-title, x-page-icon, x-page-description, x-parent, x-codeSamples, and x-logo
Structure tags with x-page-title, x-page-description, and x-parent for GitBook nested navigation in OpenAPI specs
Use official product naming: 'Email API/SMTP' (can shorten to 'Email API' or 'API/SMTP'), 'Email Sandbox' (can shorten to 'Sandbox'), 'Email Marketing' (can shorten to 'Marketing')

Files:

  • specs/webhooks.openapi.yml
  • specs/email-sending-bulk.openapi.yml
  • specs/email-sending-transactional.openapi.yml
  • specs/sandbox.openapi.yml
  • specs/email-batch.openapi.yml
  • specs/general.openapi.yml
  • specs/contacts.openapi.yml
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Use official Mailtrap SDKs for language-specific code samples in `x-codeSamples`, with Node.js (mailtrap/mailtrap-nodejs), PHP (railsware/mailtrap-php), Python (railsware/mailtrap-python), and Ruby (railsware/mailtrap-ruby)
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Update contact URLs in spec `info` blocks to use `https://docs.mailtrap.io`, not help.mailtrap.io
📚 Learning: 2025-12-23T11:20:58.573Z
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Use official Mailtrap SDKs for language-specific code samples in `x-codeSamples`, with Node.js (mailtrap/mailtrap-nodejs), PHP (railsware/mailtrap-php), Python (railsware/mailtrap-python), and Ruby (railsware/mailtrap-ruby)

Applied to files:

  • specs/email-sending-bulk.openapi.yml
  • specs/email-sending-transactional.openapi.yml
  • specs/sandbox.openapi.yml
  • specs/email-batch.openapi.yml
  • specs/general.openapi.yml
  • specs/contacts.openapi.yml
📚 Learning: 2025-12-23T11:20:58.573Z
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Base URLs must never be changed in OpenAPI specs. Use `https://send.api.mailtrap.io` for transactional emails, `https://bulk.api.mailtrap.io` for bulk emails, and `https://mailtrap.io` for all other APIs

Applied to files:

  • specs/email-sending-bulk.openapi.yml
  • specs/email-sending-transactional.openapi.yml
  • specs/sandbox.openapi.yml
  • specs/email-batch.openapi.yml
  • specs/general.openapi.yml
  • specs/contacts.openapi.yml
📚 Learning: 2025-12-23T11:20:58.573Z
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Update contact URLs in spec `info` blocks to use `https://docs.mailtrap.io`, not help.mailtrap.io

Applied to files:

  • specs/email-sending-bulk.openapi.yml
  • specs/sandbox.openapi.yml
  • specs/general.openapi.yml
  • specs/contacts.openapi.yml
📚 Learning: 2025-12-23T11:20:58.573Z
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Use official product naming: 'Email API/SMTP' (can shorten to 'Email API' or 'API/SMTP'), 'Email Sandbox' (can shorten to 'Sandbox'), 'Email Marketing' (can shorten to 'Marketing')

Applied to files:

  • specs/email-sending-bulk.openapi.yml
  • specs/email-sending-transactional.openapi.yml
  • specs/sandbox.openapi.yml
📚 Learning: 2025-12-23T11:20:58.573Z
Learnt from: CR
Repo: mailtrap/mailtrap-openapi PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-23T11:20:58.573Z
Learning: Applies to specs/**/*.openapi.yml : Use environment variables for API keys in code samples (e.g., `process.env.MAILTRAP_API_KEY`)

Applied to files:

  • specs/sandbox.openapi.yml
🔇 Additional comments (17)
specs/general.openapi.yml (4)

330-332: LGTM with verification caveat.

The method chaining Account(YOUR_ACCOUNT_ID).Accesses().Fetch() aligns with the updated SDK API. However, the same factory initialization pattern inconsistency applies here.


430-432: LGTM with verification caveat.

The updated deletion path Account(YOUR_ACCOUNT_ID).Access(accessId).Delete() properly reflects the new SDK structure. Same factory initialization consistency concern applies.


667-669: LGTM with verification caveat.

The permissions retrieval using Permissions().GetAll() correctly reflects the API update. Same factory initialization consistency concern applies.


776-778: LGTM with verification caveat.

The billing usage retrieval pattern is correct. Same factory initialization consistency concern applies across all samples in this file.

specs/webhooks.openapi.yml (3)

216-227: Excellent addition of type-safe webhook payload model.

The WebhookPayload record with JsonPropertyName attribute provides type-safe deserialization while maintaining flexibility with List<JsonElement> for the events array. The necessary using directives are properly included.


233-259: Robust defensive JSON handling implementation.

The defensive pattern using TryGetProperty throughout prevents exceptions from malformed or unexpected webhook payloads. This is essential for production webhook handlers receiving external data. The consistent application across all event types (delivery, bounce, open, click) is commendable.


260-260: Good improvement for consistency and clarity.

Returning Ok("OK") with an explicit string body aligns with other language samples and provides clearer webhook acknowledgment responses.

specs/email-sending-bulk.openapi.yml (2)

149-150: LGTM!

The necessary namespace imports are correctly added for MailtrapClientOptions and SendEmailRequest.


153-157: LGTM!

The MailtrapClientOptions configuration object with ApiToken and UseBulkApi properties correctly sets up the client for bulk email sending.

specs/email-sending-transactional.openapi.yml (3)

131-131: LGTM!

The Mailtrap.Emails.Requests import is correctly added. Note that Mailtrap.Configuration is not needed here since the factory is initialized with a string.


133-134: LGTM!

The simpler string-based factory initialization is appropriate for transactional emails using default settings. This pattern makes sense when no special configuration (like UseBulkApi) is needed.


136-143: LGTM!

The fluent SendEmailRequest builder correctly constructs the email with all necessary fields, and the send operation properly uses async/await with the updated client.Email().Send() API.

specs/email-batch.openapi.yml (3)

177-178: LGTM!

The necessary namespace imports are correctly included for configuration and batch email requests.


180-184: LGTM!

The configuration correctly shows the default transactional stream setup with a helpful comment indicating how to switch to bulk stream using UseBulkApi = true.


186-187: LGTM!

Factory-based client creation with config object is correctly implemented.

specs/sandbox.openapi.yml (1)

2388-2403: C# message, content, and attachment samples: resource graph usage looks coherent

For message operations (get/update/delete/list, spam/HTML analysis, text/raw/HTML/EML bodies, headers, attachments):

  • All samples consistently obtain the client via MailtrapClientFactory("YOUR_API_KEY").CreateClient().
  • Resource traversal uses a clear hierarchy like .Account(YOUR_ACCOUNT_ID).Inbox(inboxId).Message(messageId)... and then terminal operations such as .GetDetails(), .Update(request), .Delete(), .GetSpamReport(), .GetHtmlAnalysisReport(), .GetTextBody(), .AsRaw(), .GetHtmlSource(), .GetHtmlBody(), .AsEml(), and for attachments .Message(messageId).Attachments().Fetch() / .Attachment(attachmentId).GetDetails()—this matches the shape described in the PR summary and is internally consistent.
  • Imports such as Mailtrap.TestingMessages.Requests and Mailtrap.Attachments line up with the request types being used in each sample.

I don’t see mismatches between the paths and the method names given the new fluent client design; these snippets should be accurate references for SDK consumers.

Also applies to: 2610-2624, 2804-2818, 3010-3026, 3333-3347, 3499-3512, 3611-3622, 3767-3778, 3898-3909, 4031-4042, 4187-4198, 4292-4305, 4436-4448, 4571-4584

specs/contacts.openapi.yml (1)

1248-1254: C# contact list & field samples: fluent resource navigation looks correct

For contact lists and custom fields, the updated C# examples:

  • Use the same factory + account pattern as the rest of the file.
  • Navigate lists via:
    • .Account(YOUR_ACCOUNT_ID).Contacts().Lists().GetAll()
    • .Contacts().Lists().Create(new() { Name = "..." })
    • .Contacts().List(listId).GetDetails()/Update(new() { ... }).Delete()
  • Navigate fields via:
    • .Contacts().Fields().GetAll()
    • .Contacts().Fields().Create(new CreateContactFieldRequest(...))
    • .Contacts().Field(fieldId).GetDetails()/Update(new UpdateContactFieldRequest(...))/Delete()

Request/enum types from Mailtrap.ContactFields.Models and Mailtrap.ContactFields.Requests are correctly imported where needed, and the method naming matches the underlying operations described in the spec (get/create/update/delete). I don’t see any obvious mismatches or missing steps in these samples.

Also applies to: 1333-1339, 1425-1431, 1503-1507, 1592-1596, 1668-1674, 1758-1767, 1888-1892, 1967-1972, 2080-2084

@yanchuk yanchuk requested review from mklocek and yanchuk December 29, 2025 16:08
@yanchuk yanchuk merged commit 3812c42 into mailtrap:main Dec 30, 2025
2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 28, 2026
3 tasks
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