Skip to content

SDKs

Official client libraries for the Mail.td API. All SDKs cover the full API surface with typed responses and error handling.

Available SDKs

Quick Start

Node.js

typescript
import { MailTD } from 'mailtd';

const client = new MailTD('td_...');

// Create a mailbox
const account = await client.accounts.create('test@mail.td', {
  password: 'mypassword',
});

// List messages
const { messages } = await client.messages.list(account.id);

// Get a message
const msg = await client.messages.get(account.id, messages[0].id);
console.log(msg.subject, msg.text_body);

Python

python
from mailtd import MailTD

client = MailTD("td_...")

# Create a mailbox
account = client.accounts.create("test@mail.td", password="mypassword")

# List messages
messages, page = client.messages.list(account.id)

# Get a message
msg = client.messages.get(account.id, messages[0].id)
print(msg.subject, msg.text_body)

Go

go
client := mailtd.NewClient("td_...")
ctx := context.Background()

// Create a mailbox
pw := "mypassword"
account, _ := client.Accounts.Create(ctx, "test@mail.td", &mailtd.CreateOptions{
    Password: &pw,
})

// List messages
result, _ := client.Messages.List(ctx, account.ID, nil)

// Get a message
msg, _ := client.Messages.Get(ctx, account.ID, result.Data[0].ID)
fmt.Println(msg.Subject, *msg.TextBody)

Authentication

All SDKs accept a Pro API Token in the constructor:

typescript
const client = new MailTD('td_...');

// Custom base URL (optional)
const client = new MailTD({ token: 'td_...', baseUrl: 'https://custom.api.url' });
python
client = MailTD("td_...")

# Custom base URL (optional)
client = MailTD("td_...", base_url="https://custom.api.url")

# Context manager support
with MailTD("td_...") as client:
    ...
go
client := mailtd.NewClient("td_...")

// Custom base URL (optional)
client := mailtd.NewClient("td_...", mailtd.WithBaseURL("https://custom.api.url"))

Error Handling

All SDKs throw/raise an APIError with status (HTTP code) and code (error string):

typescript
import { MailTD, APIError } from 'mailtd';

try {
  await client.accounts.create('taken@mail.td', { password: '...' });
} catch (err) {
  if (err instanceof APIError) {
    console.log(err.status); // 409
    console.log(err.code);   // "address_taken"
  }
}
python
from mailtd import MailTD, APIError

try:
    client.accounts.create("taken@mail.td", password="...")
except APIError as e:
    print(e.status)  # 409
    print(e.code)    # "address_taken"
go
pw := "..."
account, err := client.Accounts.Create(ctx, "taken@mail.td", &mailtd.CreateOptions{
    Password: &pw,
})
if err != nil {
    var apiErr *mailtd.APIError
    if errors.As(err, &apiErr) {
        fmt.Println(apiErr.Status) // 409
        fmt.Println(apiErr.Code)   // "address_taken"
    }
}

Resources

Each SDK exposes the same resource structure:

ResourceMethodsDescription
accountscreate, get, delete, resetPassword, listDomainsMailbox management and domain listing
messageslist, get, delete, getSource, getAttachment, markAsRead, batchMarkAsReadEmail operations
domainslist, create, verify, deleteCustom domain management (Pro)
webhookslist, create, delete, rotateSecret, listDeliveriesWebhook management (Pro)
tokenslist, create, revokeAPI token management (Pro)
sandboxgetInfo, listMessages, getMessage, deleteMessage, purgeMessages, getMessageSource, getAttachmentSMTP sandbox (Pro)
billinggetStatus, cancel, resume, getPortalUrlSubscription management (Pro)
usergetMe, listAccounts, deleteAccount, resetAccountPassword, listAccountMessagesPro user profile and multi-account management

Common Patterns

Polling for new messages

typescript
// Poll every 10 seconds until an email arrives
async function waitForEmail(client, accountId, timeout = 60000) {
  const start = Date.now();
  while (Date.now() - start < timeout) {
    const { messages } = await client.messages.list(accountId);
    if (messages.length > 0) return messages[0];
    await new Promise(r => setTimeout(r, 10000));
  }
  throw new Error('Timeout waiting for email');
}
python
import time

def wait_for_email(client, account_id, timeout=60):
    start = time.time()
    while time.time() - start < timeout:
        messages, _ = client.messages.list(account_id)
        if messages:
            return messages[0]
        time.sleep(10)
    raise TimeoutError("Timeout waiting for email")
go
func waitForEmail(ctx context.Context, client *mailtd.Client, accountID string, timeout time.Duration) (*mailtd.EmailSummary, error) {
    deadline := time.Now().Add(timeout)
    for time.Now().Before(deadline) {
        result, err := client.Messages.List(ctx, accountID, nil)
        if err != nil {
            return nil, err
        }
        if len(result.Data) > 0 {
            return &result.Data[0], nil
        }
        time.Sleep(10 * time.Second)
    }
    return nil, fmt.Errorf("timeout waiting for email")
}

Download attachments

typescript
const msg = await client.messages.get(accountId, messageId);
for (const att of msg.attachments) {
  const data = await client.messages.getAttachment(accountId, messageId, att.index);
  // data is ArrayBuffer
  fs.writeFileSync(att.filename, Buffer.from(data));
}
python
msg = client.messages.get(account_id, message_id)
for att in msg.attachments:
    data = client.messages.get_attachment(account_id, message_id, att.index)
    with open(att.filename, "wb") as f:
        f.write(data)
go
msg, _ := client.Messages.Get(ctx, accountID, messageID)
for _, att := range msg.Attachments {
    data, _ := client.Messages.GetAttachment(ctx, accountID, messageID, att.Index)
    os.WriteFile(att.Filename, data, 0644)
}

Mail.td API Documentation