# SMTP gateway

The SMTP gateway accepts standard mail submission and forwards each message to [Messaging API v2 `Notify`](/developer/api-reference/messaging-api-v2/notify/) as a transactional email. Use it when an existing mail tool — an MTA, a framework mailer, an SDK — is easier to plug in than a JSON request to the API.

<Aside type="note">
The gateway is transactional-only. For audience segments, scheduling, or A/B campaigns, call [`Notify`](/developer/api-reference/messaging-api-v2/notify/) directly.
</Aside>

## How it works

```
   any SMTP client          smtp gateway              Messaging API v2
   ──────────────── ──────> ──────────────── ──────> ─────────────────
       submission            STARTTLS                gRPC Notify
       AUTH PLAIN            + AUTH PLAIN            Authorization: Token
```

1. The client connects to `smtp.pushwoosh.com` on port `587`, upgrades the connection to TLS with `STARTTLS`, then authenticates with `AUTH PLAIN`.
2. The gateway parses the MIME message and builds a `Notify` request with `platforms: ["EMAIL"]` and `message_type: TRANSACTIONAL`.
3. The API token from `AUTH PLAIN` is forwarded to Messaging API as the `Authorization` header. Token validation, application matching, sending identity, and bounce handling all happen on the API side.

## Endpoint

| Setting <div style="width:140px"></div> | Value <div style="width:340px"></div> |
|---------|-------|
| Host    | `smtp.pushwoosh.com` |
| Port    | `587` (SMTP submission) |
| TLS     | `STARTTLS` — mandatory before `AUTH` |
| Auth    | `AUTH PLAIN` |

## Authentication

`AUTH PLAIN` uses two Pushwoosh credentials.

| AUTH field <div style="width:120px"></div> | Pushwoosh value |
|------------|-----------------|
| `username` | [Application code](/developer/api-reference/api-identifiers/#application-code), for example `XXXXX-XXXXX` |
| `password` | [Server API token](/developer/api-reference/api-access-token/#server-api-token) |

`AUTH` is rejected outside TLS. The token never appears in the message — it is only used to authorize the upstream `Notify` call.

## How messages map to Notify

| MIME or SMTP field <div style="width:200px"></div> | Notify field |
|--------------------|--------------|
| `RCPT TO`          | `target.users.list` — Pushwoosh resolves these addresses to subscribers |
| AUTH `username`    | `application` |
| `Subject:` header  | `email_payload.subject["default"]` (RFC 2047 decoded) |
| `From:` header     | `email_payload.from` — `name` and `email` |
| HTML part          | `email_payload.body` (preferred when both parts are present) |
| Plain-text part    | `email_payload.body` (used when HTML is absent) |
| `MAIL FROM`        | Ignored — Pushwoosh substitutes its own sending identity and handles bounces itself |

Every message is sent with `schedule.send_date: now`.

## Limits

| Limit <div style="width:280px"></div> | Value |
|-------|-------|
| Maximum message size       | 25 MiB |
| Maximum recipients per envelope (`RCPT TO`) | 50 |

## Error mapping

gRPC status codes returned by Messaging API are translated to standard SMTP reply codes so that any SMTP client surfaces a meaningful error.

| Upstream gRPC status <div style="width:280px"></div> | SMTP reply <div style="width:120px"></div> | Meaning |
|----------------------|------------|---------|
| `Unauthenticated`                                          | `535 5.7.8` | Bad application code or API token. |
| `PermissionDenied`                                         | `550 5.7.1` | The token has no rights for this application. |
| `InvalidArgument` / `FailedPrecondition` / `OutOfRange`    | `550 5.6.0` | Bad MIME content (for example missing subject or body). |
| `NotFound`                                                 | `550 5.1.1` | Application or recipient was not found. |
| `ResourceExhausted`                                        | `452 4.5.3` | Rate limit reached — retry later. |
| `DeadlineExceeded` / `Unavailable`                         | `451 4.4.1` | Transient upstream error — retry later. |
| any other failure                                          | `451 4.5.0` | Transient internal error — retry later. |

Codes in the `4xx` range are temporary and should be retried by the client; codes in the `5xx` range are permanent and require a client-side fix.

## Example: send with swaks

```bash
swaks --server smtp.pushwoosh.com:587 \
      --auth-user "XXXXX-XXXXX" \
      --auth-password "YOUR_API_TOKEN" \
      --tls \
      --from from@example.com \
      --to user@example.com \
      --header "Subject: Hello from SMTP gateway" \
      --body "Plain-text body"
```

The `From:` header in the MIME body is what reaches Pushwoosh — the `--from` envelope (`MAIL FROM`) is discarded.

## Notes

- The gateway is stateless and does not store messages. Once forwarded, delivery is owned by Messaging API.
- Bounces, complaints, and unsubscribe links are handled by Pushwoosh, the same as for any other transactional email.
- For campaign sending (segments, scheduling, A/B), use [`Notify`](/developer/api-reference/messaging-api-v2/notify/) directly — the SMTP gateway is submission-only.

## See also

<CardGrid>
  <LinkCard title="Messaging API v2 overview" href="/developer/api-reference/messaging-api-v2/" />
  <LinkCard title="Notify" href="/developer/api-reference/messaging-api-v2/notify/" />
  <LinkCard title="Email payload reference" href="/developer/api-reference/messaging-api-v2/email-payload-reference/" />
  <LinkCard title="Marketing vs transactional" href="/product/messaging-channels/marketing-vs-transactional/" />
</CardGrid>