# Send test emails

> Simulate delivered, bounced, complained, and suppressed events with SendPing test addresses — without harming your domain reputation.

While building your integration it is important to exercise the different deliverability outcomes — a delivery, a hard bounce, a spam complaint, a suppressed recipient. SendPing provides reserved **test addresses** that trigger each event reliably, so you can verify your [webhooks](https://www.sendping.co/docs/webhooks/overview), event handling, and suppression logic without mailing real people.

> **Warning:** Do not test by inventing fake addresses or pointing at a throwaway SMTP server — both can hurt your domain reputation. Use the addresses below instead.

> **Note:** Test sends still count against your account’s sending quota and produce real [email objects](https://www.sendping.co/docs/emails/managing) with a full event log.

## Available test addresses

| Address | Simulates |
| --- | --- |
| `delivered@test.sendping.co` | A successful delivery — the email advances to `delivered`. |
| `bounced@test.sendping.co` | A hard bounce (an SMTP `550 5.1.1` "Unknown User"). The email moves to `bounced` and the recipient is [auto-suppressed](https://www.sendping.co/docs/emails/bounces). |
| `complained@test.sendping.co` | The message is delivered but the recipient marks it as spam — a `complained` event, and the recipient is suppressed. |
| `suppressed@test.sendping.co` | The recipient is already on your [suppression list](https://www.sendping.co/docs/emails/suppressions), so the send is skipped with status `suppressed`. |

## Send to a test address

**Node.js**

```js
import { SendPing } from 'sendping';

const mb = new SendPing('mb_xxxxxxxxx');

const { data, error } = await mb.emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": ["bounced@test.sendping.co"],
  "subject": "Testing a bounce",
  "html": "<p>This should hard-bounce.</p>"
});
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": [
    "bounced@test.sendping.co"
  ],
  "subject": "Testing a bounce",
  "html": "<p>This should hard-bounce.</p>"
})
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendPing\SendPing;

$sendping = SendPing::client('mb_xxxxxxxxx');

$sendping->emails->send([
  'from' => "Acme <hello@yourdomain.com>",
  'to' => [
    "bounced@test.sendping.co"
  ],
  'subject' => "Testing a bounce",
  'html' => "<p>This should hard-bounce.</p>"
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": [
    "bounced@test.sendping.co"
  ],
  "subject": "Testing a bounce",
  "html": "<p>This should hard-bounce.</p>"
})
```

**Go**

```go
import "github.com/shekhu10/sendping-sdks/sendping-go"

client := sendping.NewClient("mb_xxxxxxxxx")

sent, err := client.Emails.Send(&sendping.SendEmailRequest{
    From:    "Acme <hello@yourdomain.com>",
    To:      []string{"bounced@test.sendping.co"},
    Subject: "Testing a bounce",
    Html:    "<p>This should hard-bounce.</p>",
})
```

**Rust**

```rust
use sendping::{SendEmailOptions, SendPing};

let mb = SendPing::new("mb_xxxxxxxxx");

let params = SendEmailOptions::new(
    "Acme <hello@yourdomain.com>",
    ["bounced@test.sendping.co"],
    "Testing a bounce",
)
.with_html("<p>This should hard-bounce.</p>");
let _sent = mb.emails.send(params).await?;
```

**Java**

```java
import co.sendping.SendPing;
import co.sendping.SendPingResponse;
import co.sendping.requests.SendEmailRequest;

SendPing sendping = new SendPing("mb_xxxxxxxxx");

SendEmailRequest request = SendEmailRequest.builder()
        .from("Acme <hello@yourdomain.com>")
        .to("bounced@test.sendping.co")
        .subject("Testing a bounce")
        .html("<p>This should hard-bounce.</p>")
        .build();

SendPingResponse response = sendping.emails().send(request);
```

**.NET**

```csharp
using SendPing;

ISendPing sendping = SendPingClient.Create("mb_xxxxxxxxx");

var resp = await sendping.EmailSendAsync(new EmailMessage
{
    From = "Acme <hello@yourdomain.com>",
    To = "bounced@test.sendping.co",
    Subject = "Testing a bounce",
    HtmlBody = "<p>This should hard-bounce.</p>",
});
```

**cURL**

```bash
curl -X POST 'https://www.sendping.co/api/emails' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
  "from": "Acme <hello@yourdomain.com>",
  "to": ["bounced@test.sendping.co"],
  "subject": "Testing a bounce",
  "html": "<p>This should hard-bounce.</p>"
}'
```

**CLI**

```bash
sendping emails send \
  --from 'Acme <hello@yourdomain.com>' \
  --to 'bounced@test.sendping.co' \
  --subject 'Testing a bounce' \
  --html '<p>This should hard-bounce.</p>'
```

## Labeling test runs

The `delivered`, `bounced`, and `complained` addresses support **plus-labeling**: add any string after a `+` (e.g. `delivered+signup@test.sendping.co`) and the event still fires, but the recipient address now identifies that specific test run. This is useful for correlating webhook callbacks back to the flow that triggered them.

```text
delivered+signup@test.sendping.co
delivered+password-reset@test.sendping.co
bounced+import-batch@test.sendping.co
```

> **Warning:** The `suppressed@test.sendping.co` address does not support labeling.
