Home
Official SDKs

Go SDK

Standard-library tropmail-go client with range-over-func iterators.
go get github.com/tropmail/tropmail-go

Standard library only. Requires Go 1.23+ for range-over-func iterators.

Source: github.com/tropmail/tropmail-go

Quick start

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/tropmail/tropmail-go"
)

func main() {
	client, err := tropmail.New("") // reads TROPMAIL_API_KEY
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	listed, err := client.Mailboxes.List(ctx)
	if err != nil {
		log.Fatal(err)
	}
	mailbox := listed.Mailboxes[0]
	fmt.Printf("%s: %d opened\n", mailbox.Email, mailbox.OpenedCount)

	for email, err := range client.Emails.All(ctx, tropmail.ListOptions{MailboxID: mailbox.ID, Status: "Open"}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(email.Timestamp, email.From.Address, email.Subject)
	}
}

Pagination

All and SearchAll return iter.Seq2[Email, error], so they compose with range and stop as soon as you break:

for email, err := range client.Emails.SearchAll(ctx, "invoice", tropmail.ListOptions{MailboxID: mailbox.ID}) {
	if err != nil {
		return err
	}
	if strings.Contains(email.Subject, "Q4") {
		return handle(email)
	}
}

The iterators stop on the first short page. Total on list is the mailbox opened count plus closed count. Total on search is the match count.

Reading an email

Get returns the HTML view by default. Use GetEmail with an email you already have and the client forwards its timestamp for a faster lookup.

page, err := client.Emails.List(ctx, tropmail.ListOptions{MailboxID: mailbox.ID, Limit: 10})
if err != nil {
	return err
}

detail, err := client.Emails.GetEmail(ctx, mailbox.ID, page.Emails[0], tropmail.ViewText)
if err != nil {
	return err
}
fmt.Println(detail.Content)

Markdown

The markdown view is generated on demand. GetMarkdown retries 504:

detail, err := client.Emails.GetMarkdown(ctx, mailbox.ID, email.ID, email.Timestamp)

Actions

client.Emails.Favorite(ctx, mailbox.ID, id)
client.Emails.SetState(ctx, mailbox.ID, id, tropmail.StateClose)
client.Emails.Block(ctx, mailbox.ID, id)
client.Emails.ClearAction(ctx, mailbox.ID, id)

Attachments

_, err := client.Attachments.Scan(ctx, mailbox.ID, attachmentID)
for {
	info, err := client.Attachments.Get(ctx, mailbox.ID, attachmentID)
	if err != nil {
		log.Fatal(err)
	}
	if info.ScanStatus != tropmail.ScanProcessing && info.ScanStatus != tropmail.ScanNotScanned {
		fmt.Println(info.ScanStatus, info.ScanResult)
		break
	}
	time.Sleep(2 * time.Second)
}

n, err := client.Attachments.DownloadTo(ctx, mailbox.ID, attachmentID, "/tmp/invoice.pdf")

body, err := client.Attachments.Open(ctx, mailbox.ID, attachmentID)
defer body.Close()

A file whose size is 0 is a real empty attachment. Download returns 200 with an empty body.

Downloads use your API key on the same host as the rest of the API.

Errors

Every API failure is a *tropmail.Error with status, message, and the X-Request-ID the API echoed back. A missing or malformed key is ErrInvalidAPIKey before any HTTP call.

detail, err := client.Emails.Get(ctx, mailbox.ID, id, tropmail.GetOptions{})
switch {
case tropmail.IsNotFound(err):
	// gone
case tropmail.IsRateLimit(err):
	var apiErr *tropmail.Error
	errors.As(err, &apiErr)
	time.Sleep(apiErr.RetryAfter)
case err != nil:
	return err
}
HelperCondition
errors.Is(..., ErrInvalidAPIKey)local key check
IsValidation400
IsAuth401
IsTier403
IsNotFound404
IsRateLimit429
IsMarkdownTimeout504
IsServer5xx except 504
IsConnectiontransport failure

Rate limits

The client reads X-RateLimit-* headers and stays within your account limit.

snap := client.RateLimit()
fmt.Println(snap.Limit, snap.Remaining, snap.Reset)

Pass tropmail.WithThrottle(false) if you manage concurrency yourself.

Configuration

client, err := tropmail.New(apiKey,
	tropmail.WithBaseURL("https://api.tropmail.com/api/v1"),
	tropmail.WithTimeout(120*time.Second),
	tropmail.WithMaxRetries(3),
	tropmail.WithThrottle(true),
	tropmail.WithHTTPClient(myClient),
	tropmail.WithUserAgent("my-app/1.0"),
)

Every call takes a context.Context. Retries with backoff on 429, 502, 503, 504, and transport errors. Reads retry. Mutations do not.

Examples

DirectoryWhat it shows
quickstartmailbox summary, listing, reading one message
triageauto-paging, bulk actions
attachmentsscan and download to disk