# Go SDK

The official Go client for the Mailjet API lives at [mailjet/mailjet-apiv3-go](https://github.com/mailjet/mailjet-apiv3-go). Reference documentation is published on [pkg.go.dev](https://pkg.go.dev/github.com/mailjet/mailjet-apiv3-go/v4).

## Compatibility

The library requires **Go 1.13 or higher**. Because [each major Go release is supported until two newer major releases exist](https://go.dev/doc/devel/release#policy), there is no guarantee the client works on Go versions that are themselves out of support.

**Breaking change:** backward compatibility was broken in **v3.0**, which introduced the versioned module paths required by Go modules. Import paths must include the major version.

## Installation

```bash
go get github.com/mailjet/mailjet-apiv3-go/v4
```

```go
import (
    "github.com/mailjet/mailjet-apiv3-go/v4"
    "github.com/mailjet/mailjet-apiv3-go/v4/resources"
)
```

## Authentication

The Email API authenticates with your API key and secret. Keep them in the environment rather than in code:

```bash
export MJ_APIKEY_PUBLIC='your API key'
export MJ_APIKEY_PRIVATE='your API secret'
```

```go
publicKey := os.Getenv("MJ_APIKEY_PUBLIC")
secretKey := os.Getenv("MJ_APIKEY_PRIVATE")

mj := mailjet.NewMailjetClient(publicKey, secretKey)
```

### Verify your credentials

The repository ships a small program under `tests/` that exercises the wrapper. Running it is a quick way to confirm the keys in your environment are valid and active:

```bash
go run main.go
```

## Send your first email

```go
package main

import (
    "fmt"
    "log"
    "os"

    "github.com/mailjet/mailjet-apiv3-go/v4"
)

func main() {
    mailjetClient := mailjet.NewMailjetClient(
        os.Getenv("MJ_APIKEY_PUBLIC"),
        os.Getenv("MJ_APIKEY_PRIVATE"),
    )

    messagesInfo := []mailjet.InfoMessagesV31{
        {
            From: &mailjet.RecipientV31{
                Email: "pilot@example.com",
                Name:  "Mailjet Pilot",
            },
            To: &mailjet.RecipientsV31{
                mailjet.RecipientV31{
                    Email: "passenger1@example.com",
                    Name:  "Passenger 1",
                },
            },
            Subject:  "Your email flight plan!",
            TextPart: "Dear passenger 1, welcome to Mailjet!",
            HTMLPart: "<h3>Dear passenger 1, welcome to Mailjet!</h3>",
        },
    }

    messages := mailjet.MessagesV31{Info: messagesInfo}

    res, err := mailjetClient.SendMailV31(&messages)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Data: %+v\n", res)
}
```

## Client and call configuration

### Base URL

The default base domain is `https://api.mailjet.com`. Pass a different one as a third argument to the constructor:

```go
mailjetClient := mailjet.NewMailjetClient(
    os.Getenv("MJ_APIKEY_PUBLIC"),
    os.Getenv("MJ_APIKEY_PRIVATE"),
    "https://api.us.mailjet.com",
)
```

Accounts on Mailjet's **US architecture** must set `https://api.us.mailjet.com`.

### Send through a proxy

Inject your own `*http.Client` with `SetClient`:

```go
func setupProxy(proxyURLStr string) *http.Client {
    proxyURL, err := url.Parse(proxyURLStr)
    if err != nil {
        log.Fatal(err)
    }

    transport := &http.Transport{Proxy: http.ProxyURL(proxyURL)}

    client := &http.Client{}
    client.Transport = transport

    return client
}

func main() {
    mj := mailjet.NewMailjetClient(
        os.Getenv("MJ_APIKEY_PUBLIC"),
        os.Getenv("MJ_APIKEY_PRIVATE"),
    )

    mj.SetClient(setupProxy(os.Getenv("HTTP_PROXY")))

    // ...
}
```

The same hook lets you set custom timeouts, instrumentation or retry transports.

## Request examples

REST calls are built from a `mailjet.Request` (resource, ID, action) and, for writes, a `mailjet.FullRequest` that pairs that request with a typed payload from the `resources` package. Responses are unmarshalled into a slice of the matching resource type.

### POST — create an object

```go
var data []resources.Contact

mr := &mailjet.Request{
    Resource: "contact",
}

fmr := &mailjet.FullRequest{
    Info: mr,
    Payload: &resources.Contact{
        Email:                   "passenger@example.com",
        IsExcludedFromCampaigns: true,
        Name:                    "New Contact",
    },
}

err := mailjetClient.Post(fmr, &data)
if err != nil {
    fmt.Println(err)
}
```

### POST — endpoints with an action

Set `Action` on the request to reach action endpoints such as `/contact/{id}/managecontactslists`:

```go
var data []resources.ContactManagecontactslists

mr := &mailjet.Request{
    Resource: "contact",
    ID:       423,
    Action:   "managecontactslists",
}

fmr := &mailjet.FullRequest{
    Info: mr,
    Payload: &resources.ContactManagecontactslists{
        ContactsLists: []resources.ContactsListAction{
            {
                ListID: 432,
                Action: "addnoforce",
            },
            {
                ListID: 553,
                Action: "addforce",
            },
        },
    },
}

err := mailjetClient.Post(fmr, &data)
```

### GET — all objects

```go
var data []resources.Contact

_, _, err := mailjetClient.List("contact", &data)
```

### GET — with filters

```go
var data []resources.Contact

_, _, err := mailjetClient.List(
    "contact",
    &data,
    mailjet.Filter("IsExcludedFromCampaigns", "false"),
)
```

### GET — a single object

```go
var data []resources.Contact

mr := &mailjet.Request{
    Resource: "contact",
    ID:       5234,
}

err := mailjetClient.Get(mr, &data)
```

### PUT — update an object

A `PUT` in the Mailjet API behaves like a `PATCH`: only the properties you send are updated, everything else is left untouched, and non-mandatory properties can be omitted.

`AltID` accepts an alternative identifier — a contact's email address, for example — instead of the numeric ID.

```go
mr := &mailjet.Request{
    Resource: "contactdata",
    ID:       325,
    // AltID: "user1@example.com",
}

fmr := &mailjet.FullRequest{
    Info: mr,
    Payload: &resources.Contactdata{
        Data: resources.KeyValueList{
            {
                "Name":  "name",
                "Value": "John",
            },
            {
                "Name":  "country",
                "Value": "Canada",
            },
        },
    },
}

err := mailjetClient.Put(fmr, nil)
```

### DELETE — remove an object

A successful `DELETE` returns `204 No Content` with no response body.

```go
mr := &mailjet.Request{
    Resource: "template",
    ID:       423,
}

err := mailjetClient.Delete(mr)
```

## Contribute

The wrapper is open source. Fork the repository, branch, implement your fix or feature, document it, and open a pull request at [mailjet/mailjet-apiv3-go](https://github.com/mailjet/mailjet-apiv3-go). Documentation improvements belong in the [API documentation repo](https://github.com/mailjet/api-documentation).