# Send with a template

> Reference a saved template from POST /emails and fill its variables.

To send an email from a template, pass `template_id` (and any `variables`) to `POST /emails` instead of inline `html`/`text`. SendPing loads the template, substitutes the variables, and sends the result. Everything else about the send — `from`, `to`, attachments, scheduling, tracking — works exactly as a normal send.

> **Warning:** The template must be **published** first. Sends always read the published snapshot, so a template that is still a `draft` (which is what [`POST /templates`](https://www.sendping.co/docs/api/templates-create) creates) returns a `validation_error` reading *"Template ... has not been published. Publish it before sending."* Call [`POST /templates/:id/publish`](https://www.sendping.co/docs/api/templates-publish) once before your first send, and again after every edit you want live.

**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"],
  "template_id": "43f68331-0622-4e15-8202-246a0388854b",
  "variables": { "first_name": "Ada", "company": "Acme" }
});
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"
  ],
  "template_id": "43f68331-0622-4e15-8202-246a0388854b",
  "variables": {
    "first_name": "Ada",
    "company": "Acme"
  }
})
```

**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"
  ],
  'template_id' => "43f68331-0622-4e15-8202-246a0388854b",
  'variables' => [
    'first_name' => "Ada",
    'company' => "Acme"
  ]
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Emails.send({
  "from": "Acme <hello@yourdomain.com>",
  "to": [
    "delivered@test.sendping.co"
  ],
  "template_id": "43f68331-0622-4e15-8202-246a0388854b",
  "variables": {
    "first_name": "Ada",
    "company": "Acme"
  }
})
```

**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"},
    TemplateId: "43f68331-0622-4e15-8202-246a0388854b",
    Variables:  map[string]any{"first_name": "Ada", "company": "Acme"},
})
```

**Rust**

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

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

let email = SendEmailOptions::new(
    "Acme <hello@yourdomain.com>",
    ["delivered@test.sendping.co"],
    "hello world",
).with_html("<p>it works!</p>");
let _sent = mb.emails.send(email).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")
        .templateId("43f68331-0622-4e15-8202-246a0388854b")
        .variable("first_name", "Ada")
        .variable("company", "Acme")
        .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",
    TemplateId = "43f68331-0622-4e15-8202-246a0388854b",
    Variables = new Dictionary<string, object?>
    {
        ["first_name"] = "Ada",
        ["company"] = "Acme",
    },
});
```

**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"],
  "template_id": "43f68331-0622-4e15-8202-246a0388854b",
  "variables": { "first_name": "Ada", "company": "Acme" }
}'
```

## Overrides

Any field you set directly on the request wins over the template. For example, passing `subject` alongside `template_id` uses your subject and the template's body. This lets one template back many variations. The `from`, `subject`, and `reply_to` in the payload take precedence over the template's defaults for these fields; if the template defines no default for one of them, you must supply it in the payload.

> **Warning:** When a `template_id` is provided, you cannot also send `html` or `text` in the same request — doing so returns a `validation_error`.

## Variables and fallbacks

Each value in `variables` replaces the matching `{{ key }}` placeholder. If you omit a variable that the template defines, its `fallback_value` is used. If that variable has no fallback value, the email is **not** sent and a `validation_error` is returned.

> **Warning:** If the resolved email has neither `html` nor `text` (e.g. the template has only a subject and you sent no body), the request fails with `validation_error`. An unpublished template also fails with `validation_error`. A `template_id` that isn't yours — or one that does not exist — returns `not_found`.
