# Custom headers

> Attach custom MIME headers to an email with the headers object.

Add custom MIME headers to an outbound email with the `headers` object — a map of header name to string value. These are written verbatim into the message, which is useful for correlation IDs, threading, or downstream filtering on the receiving side.

SendPing already sets all the headers required for deliverability. Custom headers are an advanced feature for a few specific cases — for example, setting a unique **`X-Entity-Ref-ID`** so that Gmail does not collapse a series of distinct messages into a single conversation thread.

## Example

A common use is a per-message reference ID you can correlate against your own systems:

**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": ["delivered@test.sendping.co"],
  "subject": "Order confirmation",
  "html": "<p>Thanks for your order.</p>",
  "headers": {
    "X-Entity-Ref-ID": "order_12345",
    "X-Mailer-Campaign": "transactional"
  }
});
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": [
    "delivered@test.sendping.co"
  ],
  "subject": "Order confirmation",
  "html": "<p>Thanks for your order.</p>",
  "headers": {
    "X-Entity-Ref-ID": "order_12345",
    "X-Mailer-Campaign": "transactional"
  }
})
```

**PHP**

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

use SendPing\SendPing;

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

$sendping->emails->send([
  'from' => "Acme <hello@yourdomain.com>",
  'to' => [
    "delivered@test.sendping.co"
  ],
  'subject' => "Order confirmation",
  'html' => "<p>Thanks for your order.</p>",
  'headers' => [
    'X-Entity-Ref-ID' => "order_12345",
    'X-Mailer-Campaign' => "transactional"
  ]
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": [
    "delivered@test.sendping.co"
  ],
  "subject": "Order confirmation",
  "html": "<p>Thanks for your order.</p>",
  "headers": {
    "X-Entity-Ref-ID": "order_12345",
    "X-Mailer-Campaign": "transactional"
  }
})
```

**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{"delivered@test.sendping.co"},
    Subject: "Order confirmation",
    Html:    "<p>Thanks for your order.</p>",
    Headers: map[string]string{
        "X-Entity-Ref-ID":   "order_12345",
        "X-Mailer-Campaign": "transactional",
    },
})
```

**Rust**

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

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

let params = SendEmailOptions::new(
    "Acme <hello@yourdomain.com>",
    ["delivered@test.sendping.co"],
    "Order confirmation",
)
.with_html("<p>Thanks for your order.</p>")
.with_header("X-Entity-Ref-ID", "order_12345")
.with_header("X-Mailer-Campaign", "transactional");
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("delivered@test.sendping.co")
        .subject("Order confirmation")
        .html("<p>Thanks for your order.</p>")
        .header("X-Entity-Ref-ID", "order_12345")
        .header("X-Mailer-Campaign", "transactional")
        .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 = "delivered@test.sendping.co",
    Subject = "Order confirmation",
    HtmlBody = "<p>Thanks for your order.</p>",
    Headers = new Dictionary<string, string>
    {
        ["X-Entity-Ref-ID"] = "order_12345",
        ["X-Mailer-Campaign"] = "transactional",
    },
});
```

**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": ["delivered@test.sendping.co"],
  "subject": "Order confirmation",
  "html": "<p>Thanks for your order.</p>",
  "headers": {
    "X-Entity-Ref-ID": "order_12345",
    "X-Mailer-Campaign": "transactional"
  }
}'
```

**CLI**

```bash
sendping emails send \
  --from 'Acme <hello@yourdomain.com>' \
  --to 'delivered@test.sendping.co' \
  --subject 'Order confirmation' \
  --html '<p>Thanks for your order.</p>' \
  --headers '{"X-Entity-Ref-ID":"order_12345","X-Mailer-Campaign":"transactional"}'
```

## Header sanitization

Both header names and values are sanitized before they are written to the message: any carriage-return or line-feed characters (`\r`, `\n`) are stripped and collapsed to a single space. This prevents header injection — a value cannot smuggle in extra headers or a premature body break.

> **Note:** Set `List-Unsubscribe` by hand only on a transactional send (no `topic_id`), where SendPing adds nothing. For campaigns **and** for `POST /emails` sends that set `topic_id`, SendPing injects the RFC 8058 `List-Unsubscribe` header automatically — don't set it yourself there. See [Unsubscribe links](https://www.sendping.co/docs/emails/unsubscribe).
