Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Repository instructions

## Project layout

- `mailinator-csharp-client/` contains the SDK. It targets `net471` and `netstandard2.0`; do not change the supported frameworks without an explicit compatibility decision.
- API methods live in `Clients/ApiClients/<Area>/`, and their request, response, and entity types live in the matching `Models/<Area>/` tree.
- `mailinator-csharp-client-tests/` is a legacy .NET Framework 4.7.2 MSTest project whose tests call the live Mailinator API.
- `eng/OpenApiCoverageCheck/` is a .NET 8 tool for comparing the SDK request surface with the Mailinator OpenAPI specification. See `eng/README.md` for usage.

## Making SDK changes

- Treat the [Mailinator OpenAPI specification](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml) as the source of truth for documented endpoints.
- Preserve the `/api/v2` base path defined in `MailinatorClient.cs`. Endpoint clients receive a relative prefix and append their operation paths.
- Follow the existing RestSharp request pattern: create requests with `GetRequest`, use `AddUrlSegment` for path values, `AddSafeQueryParameter` for optional query values, and `AddJsonBody` for JSON bodies.
- Keep public operations asynchronous and named with the `Async` suffix. Put new models in the matching area and layer (`Requests`, `Responses`, or `Entities`) using the existing namespaces.
- Do not remove or silently change obsolete public members as part of unrelated work; that is a breaking API change.
- When the public API changes, update relevant examples and release documentation (`EXAMPLES.md`, `README.md`, and `CHANGELOG.md`) in the same change.

## Verification

- Build the solution with `dotnet build mailinator-csharp-client.sln` when the installed SDK supports all target frameworks.
- For endpoint or parameter changes, run the coverage tool described in `eng/README.md`. Prefer a checked-out spec with `--spec`; omitting it fetches the current spec from GitHub.
- Treat the MSTest suite as integration testing, not as an offline unit suite. It requires a deliberately configured Mailinator account and can create or delete domains, rules, and messages. Do not run it against live credentials—or run deletion tests—without explicit authorization.
- If the local environment cannot build the legacy targets or lacks the .NET SDK, report that limitation instead of claiming verification.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on *Keep a Changelog* and this project aims to follow *Semantic Versioning*.


## [1.0.7] - (Unreleased)

### Added

- `ROADMAP.md`
- `CHANGELOG.md`
- `AGENTS.md`
- `EXAMPLES.md`

### Deprecated

- All `RulesClient` endpoints (`CreateRuleAsync`, `DeleteRuleAsync`, `EnableRuleAsync`, `DisableRuleAsync`, `GetAllRulesAsync`, `GetRuleAsync`).
- `DomainsClient` create/delete endpoints (`CreateDomainAsync`, `DeleteDomainAsync`).
- Messages “Latest” wildcard endpoints (`FetchLatestMessagesAsync`, `FetchLatestInboxMessagesAsync`).
220 changes: 220 additions & 0 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Examples

This file is a living collection of copy/pasteable examples for the Mailinator C# client.

## Setup

Install via NuGet:

```
PM> Install-Package MailinatorApiClient
```

Create a client using an API token:

```csharp
using mailinator_csharp_client;

var client = new MailinatorClient("yourApiTokenHere");
```

## Quickstart

Fetch message summaries for an inbox:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Requests;
using mailinator_csharp_client.Models.Messages.Entities;

var client = new MailinatorClient("yourApiTokenHere");

var request = new FetchInboxRequest
{
Domain = "your_private_domain.com",
Inbox = "your_inbox",
Skip = 0,
Limit = 20,
Sort = Sort.desc
};

var response = await client.MessagesClient.FetchInboxAsync(request);
```

## Authenticators

Instant TOTP code + list authenticators:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Authenticators.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var totp = await client.AuthenticatorsClient.InstantTOTP2FACodeAsync(
new InstantTOTP2FACodeRequest { TotpSecretKey = "yourAuthSecret" });

var authenticators = await client.AuthenticatorsClient.GetAuthenticatorsAsync();

var byId = await client.AuthenticatorsClient.GetAuthenticatorsByIdAsync(
new GetAuthenticatorsByIdRequest { Id = "yourAuthId" });
```

## Domains

List domains + fetch a domain:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Domains.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var all = await client.DomainsClient.GetAllDomainsAsync();

var domain = await client.DomainsClient.GetDomainAsync(
new GetDomainRequest { DomainId = "yourDomainIdHere" });
```

## Messages

Post (inject) a message:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Entities;
using mailinator_csharp_client.Models.Messages.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var message = new MessageToPost
{
Subject = "Testing message",
From = "test_email@test.com",
Text = "Hello World!"
};

var response = await client.MessagesClient.PostMessageAsync(
new PostMessageRequest { Domain = "yourDomainNameHere", Inbox = "yourInboxHere", Message = message });
```

Fetch inbox summaries + fetch message by id:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Requests;
using mailinator_csharp_client.Models.Messages.Entities;

var client = new MailinatorClient("yourApiTokenHere");

var inbox = await client.MessagesClient.FetchInboxAsync(
new FetchInboxRequest { Domain = "yourDomainNameHere", Inbox = "yourInboxHere", Skip = 0, Limit = 20, Sort = Sort.desc });

var message = await client.MessagesClient.FetchMessageAsync(
new FetchMessageRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });
```

Fetch attachments + download a single attachment:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var attachments = await client.MessagesClient.FetchMessageAttachmentsAsync(
new FetchMessageAttachmentsRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });

var attachment = await client.MessagesClient.FetchMessageAttachmentAsync(
new FetchMessageAttachmentRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere", AttachmentId = "yourAttachmentIdHere" });
```

Links, SMTP log, and raw content:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var links = await client.MessagesClient.FetchMessageLinksAsync(
new FetchMessageLinksRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });

var linksFull = await client.MessagesClient.FetchMessageLinksFullAsync(
new FetchMessageLinksFullRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });

var smtp = await client.MessagesClient.FetchMessageSmtpLogAsync(
new FetchMessageSmtpLogRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });

var raw = await client.MessagesClient.FetchMessageRawAsync(
new FetchMessageRawRequest { Domain = "yourDomainNameHere", MessageId = "yourMessageIdHere" });
```

Deletes:

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Messages.Requests;

var client = new MailinatorClient("yourApiTokenHere");

var deleted = await client.MessagesClient.DeleteMessageAsync(
new DeleteMessageRequest { Domain = "yourDomainNameHere", Inbox = "yourInboxHere", MessageId = "yourMessageIdHere" });

var deletedInbox = await client.MessagesClient.DeleteAllInboxMessagesAsync(
new DeleteAllInboxMessagesRequest { Domain = "yourDomainNameHere", Inbox = "yourInboxHere" });

var deletedDomain = await client.MessagesClient.DeleteAllDomainMessagesAsync(
new DeleteAllDomainMessagesRequest { Domain = "yourDomainNameHere" });
```

## Stats

Team summary:

```csharp
using mailinator_csharp_client;

var client = new MailinatorClient("yourApiTokenHere");

var team = await client.StatsClient.GetTeamAsync();
var stats = await client.StatsClient.GetTeamStatsAsync();
var info = await client.StatsClient.GetTeamInfoAsync();
```

## Webhooks

Inject via webhook endpoints (uses `whtoken`):

```csharp
using mailinator_csharp_client;
using mailinator_csharp_client.Models.Webhooks.Entities;
using mailinator_csharp_client.Models.Webhooks.Requests;

var client = new MailinatorClient("yourApiTokenHere");

Copilot AI Apr 12, 2026

Copy link

Choose a reason for hiding this comment

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

Webhook injection endpoints are documented in-code as not using the regular API token (auth should be via the whtoken query param). Using new MailinatorClient("yourApiTokenHere") here is misleading; prefer new MailinatorClient() (or explicitly note that the API token is not required/used for webhook calls).

Suggested change
var client = new MailinatorClient("yourApiTokenHere");
var client = new MailinatorClient();

Copilot uses AI. Check for mistakes.

var webhook = new Webhook
{
From = "MyMailinatorCSharpTest",
Subject = "testing message",
Text = "hello world",
To = "jack"
};

var privateWebhook = await client.WebhooksClient.PrivateWebhookAsync(
new PrivateWebhookRequest { WebhookToken = "yourWebhookTokenPrivateDomain", Webhook = webhook });

var privateInboxWebhook = await client.WebhooksClient.PrivateInboxWebhookAsync(
new PrivateInboxWebhookRequest { WebhookToken = "yourWebhookTokenPrivateDomain", Inbox = "yourWebhookInbox", Webhook = webhook });

var customServiceWebhook = await client.WebhooksClient.PrivateCustomServiceWebhookAsync(
new PrivateCustomServiceWebhookRequest { WebhookToken = "yourWebhookTokenCustomService", CustomService = "yourWebhookCustomService", Webhook = webhook });

var customServiceInboxWebhook = await client.WebhooksClient.PrivateCustomServiceInboxWebhookAsync(
new PrivateCustomServiceInboxWebhookRequest { WebhookToken = "yourWebhookTokenCustomService", CustomService = "yourWebhookCustomService", Inbox = "yourWebhookInbox", Webhook = webhook });
```

## Troubleshooting

- Ensure you’re using an API token from your Mailinator team settings.
- For webhook injection, use webhook tokens (`whtoken`) instead of your API token.
Loading