# Adapter model (/docs/concepts/adapter-model)



An adapter is an Email SDK module that knows how to send through one service or transport.

```ts
import { createEmailClient } from "@opencoredev/email-sdk";
import { resend } from "@opencoredev/email-sdk/resend";
import { postmark } from "@opencoredev/email-sdk/postmark";

const email = createEmailClient({
  adapters: [
    resend({ apiKey: process.env.RESEND_API_KEY! }),
    postmark({ serverToken: process.env.POSTMARK_SERVER_TOKEN! }),
  ],
});
```

## Routing names [#routing-names]

Each adapter registers a routing name. Email SDK uses that name for defaults, fallbacks, and per-send overrides.

| Adapter                 | Routing name |
| ----------------------- | ------------ |
| Resend                  | `resend`     |
| SMTP                    | `smtp`       |
| Postmark                | `postmark`   |
| SendGrid                | `sendgrid`   |
| Mailgun                 | `mailgun`    |
| MailerSend              | `mailersend` |
| Brevo                   | `brevo`      |
| Mailchimp Transactional | `mailchimp`  |
| SparkPost               | `sparkpost`  |
| Loops                   | `loops`      |
| Plunk                   | `plunk`      |
| Mailtrap                | `mailtrap`   |
| Scaleway                | `scaleway`   |
| ZeptoMail               | `zeptomail`  |
| MailPace                | `mailpace`   |

## Send with one adapter [#send-with-one-adapter]

```ts
await email.send(message, {
  adapter: "postmark",
});
```

## Bind one adapter [#bind-one-adapter]

```ts
const transactional = email.withAdapter("postmark");

await transactional.send(message);
```

## Use adapter escape hatches [#use-adapter-escape-hatches]

Every adapter can expose `raw`. Keep provider-specific code close to the adapter and keep normal application code on the shared `send` path.

```ts
const adapter = email.adapter("resend");

console.log(adapter.raw);
```

The older `provider`, `defaultProvider`, `email.provider()`, and `email.withProvider()` names still work as aliases.
