# Send emails with Go

> Send email from Go with the official senddart-go module — typed request structs, context variants, and zero third-party dependencies.

The official Go module is the fastest way to send email from Go. It depends only on the standard library, sets the required `User-Agent` header for you, and retries `429`/`503` responses automatically.

The SendDart 1.0.0 module path is `github.com/shekhu10/senddart-sdks/senddart-go`, without a major-version suffix. The package name is `senddart`.

## Prerequisites

1. A **verified domain** for your `from` address. ([guide](https://www.senddart.com/docs/domains/managing))
2. An **API key** (`mb_...`), read from `SENDDART_API_KEY`. ([Authentication](https://www.senddart.com/docs/authentication))
3. **Go 1.22 or newer** — that is the floor declared in the module `go.mod`.

## Install

```sh
go get github.com/shekhu10/senddart-sdks/senddart-go
```

## Send an email

Construct the client with `senddart.NewClient` and call `client.Emails.Send`. `delivered@test.senddart.com` is the delivery simulator — safe to send to while you wire things up. Do not use `example.com`: it is a blocked recipient domain and the send comes back `422`.

**main.go**

```go
package main

import (
	"errors"
	"fmt"
	"log"
	"os"

	senddart "github.com/shekhu10/senddart-sdks/senddart-go"
)

func main() {
	client := senddart.NewClient(os.Getenv("SENDDART_API_KEY"))

	sent, err := client.Emails.Send(&senddart.SendEmailRequest{
		From:    "Acme <hello@yourdomain.com>",
		To:      []string{"delivered@test.senddart.com"},
		Subject: "Hello from Go",
		Html:    "<p>Sent with the official Go module 🐹</p>",
	})
	if err != nil {
		var apiErr *senddart.SendDartError
		if errors.As(err, &apiErr) {
			log.Fatalf("SendDart %d %s: %s", apiErr.StatusCode, apiErr.Name, apiErr.Message)
		}
		log.Fatal(err)
	}

	fmt.Println("Sent email", sent.Id)
}
```

## Handling the response

A successful send returns `*senddart.CreateEmailResponse`, whose only field is `Id`. Keep it to [retrieve the email](https://www.senddart.com/docs/api/emails-get) later or to correlate [webhook](https://www.senddart.com/docs/webhooks/overview) events.

```json
{
  "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"
}
```

Any non-2xx answer comes back as a `*senddart.SendDartError` carrying the `{ statusCode, name, message }` envelope. Branch on `Name` together with `StatusCode`, never on `Message` — message text is scrubbed server-side and is not a stable contract. Plan and quota rejections additionally populate `Limit`, and reputation gates populate `Reputation`; both are `nil` on an ordinary error.

```go
var apiErr *senddart.SendDartError
if errors.As(err, &apiErr) {
	switch apiErr.Name {
	case "validation_error":
		// 422 — a bad field, or 403 when the User-Agent header is missing.
	case "daily_quota_exceeded":
		if l := apiErr.Limit; l != nil {
			fmt.Printf("%s cap hit: %d/%d\n", l.Kind, l.Used, l.Limit)
		}
	}
}
```

## Context and tuning

Every method has a context-aware variant with a `WithContext` suffix, so a send can inherit the deadline of the request that triggered it.

```go
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

sent, err := client.Emails.SendWithContext(ctx, params)
```

The exported client fields may be overridden before first use. `Timeout` bounds each attempt (default `senddart.DefaultTimeout`, 30s) and `MaxRetries` is the retry budget for `429`/`503` only (default `senddart.DefaultMaxRetries`, 2) — no other status, network error, or timeout is retried, so a send is never silently duplicated.

```go
client := senddart.NewClient(os.Getenv("SENDDART_API_KEY"))
client.Timeout = 10 * time.Second
client.MaxRetries = 3
```

> **Note:** The module always sends a non-empty `User-Agent` (`senddart-go/1.0.0`), which the API requires on every route — a request without one is rejected with `403 validation_error` before it is even authenticated. Setting `client.UserAgent = ""` falls back to that default rather than producing a client that 403s on every call.

> **Warning:** Read the `mb_` API key from the environment (or your secrets manager) and keep it server-side. Never compile it into a binary you ship to users — the key can send email as your account.

## Next steps

- See the full [Send Email API](https://www.senddart.com/docs/api/emails-send) reference for every body field (`Cc`, `Bcc`, `ReplyTo`, `Attachments`, `ScheduledAt`).
- Explore [the SDKs reference](https://www.senddart.com/docs/resources/sdks) for the other resources the module exposes.
- Prefer no dependencies at all? [Send with Go over raw HTTP](https://www.senddart.com/docs/send-with/go) uses only `net/http`.
