> For the complete documentation index, see [llms.txt](https://docs.hostinger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hostinger.com/api-reference/email-sdks.md).

# Email SDKs

Official client libraries for the [Hostinger Mail API](https://api.mail.hostinger.com), which reads and sends mail from the mailboxes on your [Hostinger Email](/emails/overview.md) plan. Each SDK wraps the REST API in ordinary classes and methods, so you configure your token once and call a method instead of building HTTP requests by hand.

All of them are generated from the Mail API's OpenAPI specification and cover its 27 operations across account, folders, messages, sending, webhooks, and quota.

> **Note:** The Mail API is a separate API from the one behind [developers.hostinger.com](https://developers.hostinger.com/) — different base URL, different tokens, different packages. The [SDKs](/api-reference/sdks.md) for hosting, domains, and VPS contain no email operations, and these contain nothing else. Projects that manage both install both.

## Available SDKs

| Language   | Install                                       | Import as                       | Requires     |
| ---------- | --------------------------------------------- | ------------------------------- | ------------ |
| PHP        | `composer require hostinger/mail-api-php-sdk` | `Hostinger\Api\…`               | PHP 8.2+     |
| Python     | `pip install hostinger-mail-api`              | `import hostinger_mail_api`     | Python 3.10+ |
| TypeScript | `npm install hostinger-mail-api-sdk`          | `from 'hostinger-mail-api-sdk'` | axios 1.8+   |

There's also a command-line client, `hostinger-mail` — see [Command line](#command-line).

> **Warning:** In PHP, this package and `hostinger/api-php-sdk` both publish classes under the `Hostinger\` namespace, and both define `Hostinger\Configuration`, `Hostinger\ApiException`, and `Hostinger\ObjectSerializer`. Install both in one project and only one copy of each is loaded, which can silently point your mail client at the wrong host. If you need both, call `setHost('https://api.mail.hostinger.com')` on the configuration you pass to a mail API class rather than relying on its default.

## Authenticate

Mail API tokens are separate from hosting API tokens. Create one under **Agentic Mail** → **API access** in your email domain's sidebar — see [Agentic Mail](/emails/agentic-mail.md#api-access) for the steps and the available scopes. A token is limited to a single order, and optionally to specific mailboxes within it, so the SDK can only reach what the token allows.

```bash
export HOSTINGER_MAIL_API_TOKEN=<your API token>
```

The examples below read that variable. The SDKs don't read it automatically — you pass the token in when you build the client, so any variable name works. `HOSTINGER_MAIL_API_TOKEN` is the name the `hostinger-mail` CLI uses, so reusing it keeps one credential across both.

## Your first request

Start with the authenticated account. It returns the mailboxes your token can manage along with their resource IDs, and every other operation takes one of those IDs as its first argument.

### PHP

```php
<?php
require_once __DIR__ . '/vendor/autoload.php';

$config = Hostinger\Configuration::getDefaultConfiguration()
    ->setAccessToken(getenv('HOSTINGER_MAIL_API_TOKEN'));

$account = new Hostinger\Api\AccountApi(config: $config);

$response = $account->getCurrentAccount();

foreach ($response->getData()->getMailboxes() as $mailbox) {
    echo $mailbox->getResourceId(), ' ', $mailbox->getAddress(), PHP_EOL;
}
```

### Python

```python
import os
import hostinger_mail_api

configuration = hostinger_mail_api.Configuration(
    access_token=os.environ["HOSTINGER_MAIL_API_TOKEN"]
)

with hostinger_mail_api.ApiClient(configuration) as client:
    account = hostinger_mail_api.AccountApi(client)
    response = account.get_current_account()

    for mailbox in response.data.mailboxes:
        print(mailbox.resource_id, mailbox.address)
```

The client is a context manager, so the `with` block closes the underlying connection pool when it exits.

### TypeScript

```typescript
import { AccountApi, Configuration } from 'hostinger-mail-api-sdk';

const configuration = new Configuration({
  accessToken: process.env.HOSTINGER_MAIL_API_TOKEN,
});

const account = new AccountApi(configuration);

const { data } = await account.getCurrentAccount();

for (const mailbox of data.data.mailboxes) {
  console.log(mailbox.resourceId, mailbox.address);
}
```

> **Note:** The outer `data` is the HTTP response body; the inner `data` is the envelope the API wraps every payload in. See [Response envelope](#response-envelope).

## Sending a message

`SendApi` takes the mailbox resource ID and the message. At least one of `to`, `cc`, or `bcc` is required, and a copy of what you send is saved to `INBOX.Sent`.

```python
send = hostinger_mail_api.SendApi(client)

send.send_email(
    "AC1a2b3c4d5e6f7g",
    hostinger_mail_api.V1SendRequest(
        to=["recipient@example.com"],
        subject="Hello",
        text="Sent from the Hostinger Mail API.",
    ),
)
```

Replies and forwards are the same call with a reference to the source message attached — `inReplyTo` or `forwardOf` in the API, spelled to each language's conventions in the SDKs. The API copies the original's message ID and references into the new message and flags the source as answered or forwarded, so threading works without you assembling headers yourself.

> **Note:** When an agent or automation can send on your behalf, pair this with the outgoing allow list described in [Agentic Mail](/emails/agentic-mail.md#allow-and-block-lists). It turns a message addressed to the wrong person into a rejected send.

## How the SDKs are organized

Every SDK follows the same shape, so once you know it in one language you know it in all of them:

* **One class per product area** — `AccountApi`, `FoldersApi`, `MessagesApi`, `SendApi`, `WebhooksApi`, and `QuotaApi`.
* **One method per API operation.** Nothing is hand-written and nothing is missing.
* **The method name is the API operation ID**, adjusted to each language's conventions.
* **The mailbox resource ID comes first.** Every operation except `getCurrentAccount` is scoped to one mailbox, identified by its `AC…` resource ID; message operations take the folder next.

That naming rule is what makes the reference navigable. The operation `sendEmail` is the same operation everywhere — only the spelling changes:

| Surface    | Sending a message                                 |
| ---------- | ------------------------------------------------- |
| REST       | `POST /api/v1/mailboxes/{mailboxResourceId}/send` |
| PHP        | `$api->sendEmail($mailboxResourceId, $request)`   |
| Python     | `api.send_email(mailbox_resource_id, request)`    |
| TypeScript | `api.sendEmail(mailboxResourceId, request)`       |
| CLI        | `hostinger-mail send email <mailbox-resource-id>` |

So if you find an endpoint in the [API reference](https://api.mail.hostinger.com), you can predict its method name in any of the SDKs.

## Response envelope

The Mail API wraps every payload in a top-level `data` field, and the generated models keep that shape — which is why the examples above reach through `data` before finding a mailbox. Listing endpoints add a `pagination` object alongside it, telling you the page you're on and how many items exist in total.

Page size is capped and its default varies by endpoint — messages and folders return 25 per page, capped at 100. Nothing pages automatically, so walking a large folder means passing `page` yourself until you've covered `totalPages`.

## Handling errors

Failed requests raise an exception carrying the HTTP status and the response body, rather than returning an error value you have to check.

```python
from hostinger_mail_api.rest import ApiException

try:
    response = account.get_current_account()
except ApiException as e:
    print(f"Request failed with status {e.status}")
```

In PHP, catch `Hostinger\ApiException`. In TypeScript, the underlying axios call rejects, so use `try`/`catch` around the `await`.

Error bodies carry both a machine-readable `code` (such as `ERR_MAILBOX_NOT_FOUND`) and a human-readable `error` message. Branch on `code` and keep `error` for logs. A `429` means you've hit the rate limit — back off rather than retrying immediately, because repeatedly exceeding it can get your IP temporarily blocked.

## Command line

`hostinger-mail` is the command-line client for the same API, generated from the same specification. It's a separate binary from the [`hostinger` CLI](/api-reference/cli.md), which covers hosting, domains, and VPS.

```bash
brew install hostinger/tap/hostinger-mail
export HOSTINGER_MAIL_API_TOKEN=<your API token>

hostinger-mail account current
hostinger-mail messages list <mailbox-resource-id> INBOX
hostinger-mail send email <mailbox-resource-id> --to you@example.com --subject Hi --text Hello
```

Commands follow `hostinger-mail <group> <verb> [args] [flags]`, mirroring the SDK classes. Output is a table by default; add `--format json` for scripting. A token can also be stored in `$HOME/.hostinger-mail.yaml` as `api_token: <your API token>`.

## AI agents

To let an assistant read and send mail rather than writing the calls yourself, connect the hosted MCP server at `https://mcp.mail.hostinger.com/mcp` with the same token. Setup for Claude, Cursor, and others is covered in [Agentic Mail](/emails/agentic-mail.md#mcp-server).

## Full reference

Every operation, parameter, and response model is documented in each SDK's repository, and the API itself is browsable at [api.mail.hostinger.com](https://api.mail.hostinger.com):

* [PHP SDK reference](https://github.com/hostinger/mail-api-php-sdk/tree/main/docs)
* [Python SDK reference](https://github.com/hostinger/mail-api-python-sdk/tree/main/docs)
* [TypeScript SDK reference](https://github.com/hostinger/mail-api-typescript-sdk/tree/main/docs)
* [CLI command reference](https://github.com/hostinger/mail-api-cli/tree/main/docs)

## When to use an SDK

An SDK is the right choice when mail is part of your application's own logic — a support tool that threads replies, a service that files incoming messages into folders, or a bot that acts on what arrives in a shared mailbox. You get types, editor autocompletion, and a dependency you can pin and test.

For other situations, something lighter usually wins:

* **One-off tasks, shell scripts, or CI** — use the `hostinger-mail` CLI. No project or dependency needed.
* **Reacting to new mail** — a [webhook](/emails/agentic-mail.md#webhooks) tells you when something arrives, instead of polling a folder on a timer.
* **Working through an AI assistant** — use the MCP server.
* **A language without an SDK, or a single call** — call the REST API directly.

***

*Last updated: August 6, 2026*
