> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mailchannels.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send vs send async

> Learn the differences between sending emails synchronously and asynchronously.

## Synchronous vs asynchronous sending

There are two ways to send an email: synchronously and asynchronously. When you send an email synchronously, your application
waits for the API to process the request and return a response. For a single email, this is usually pretty quick. But for
larger sends, the processing time can take much longer.

When you send an email asynchronously, your application makes a request and immediately receives a response. In the background,
the API processes the request. Your application does not wait. In order to track the status of the send, you will receive
webhooks for all delivery status updates (dropped, processed, delivered, hard-bounced, etc.). These webhooks are identical
to the webhooks you receive for synchronous sends.

## When to use Send vs Send Async

Synchronous sending should only be used when the user needs feedback on the status of the send before proceeding, and the
number of emails being sent is small. Our evaluation process can take several seconds per message.

Asynchronous sending should be used for most requests. It is important to have webhooks set up to receive delivery status
updates. You can view webhook events on the [webhooks page](https://dash.mailchannels.com/webhooks).
For more information on webhooks, see the [webhooks documentation](/email-api/webhooks).

## Examples

Send synchronously:

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Send an email synchronously

    set -u
    : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
    : "${FROM_EMAIL:?Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)}"
    : "${TO_EMAIL:?Set TO_EMAIL}"

  curl -X POST https://api.mailchannels.net/tx/v1/send \
    -H "Content-Type: application/json" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
    -d @- <<JSON
  {
    "personalizations": [
      { "to": [{ "email": "$TO_EMAIL", "name": "Recipient" }] }
    ],
    "from": {
      "email": "$FROM_EMAIL",
      "name": "Your Name"
    },
    "subject": "Hello from MailChannels (sync)",
    "content": [
      {
        "type": "text/plain",
        "value": "This message was sent with POST /tx/v1/send. The caller waited for the response."
      }
    ]
  }
  JSON
  ```

  ```javascript Node.js theme={null}
  // Send an email synchronously.
  import { MailChannels } from "mailchannels-sdk";

  const { MAILCHANNELS_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env;
  if (!MAILCHANNELS_API_KEY) throw new Error("Set MAILCHANNELS_API_KEY before running");
  if (!FROM_EMAIL) throw new Error("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)");
  if (!TO_EMAIL) throw new Error("Set TO_EMAIL");

  const mailchannels = new MailChannels(MAILCHANNELS_API_KEY);

  const { data, error } = await mailchannels.emails.send({
    from: { email: FROM_EMAIL, name: "Your Name" },
    to: { email: TO_EMAIL, name: "Recipient" },
    subject: "Hello from MailChannels (sync)",
    text: "This message was sent with POST /tx/v1/send. The caller waited for the response.",
  });

  if (error) {
    console.error("Send failed:", error);
    process.exit(1);
  }
  console.log(data);
  ```

  ```python Python theme={null}
  import os
  import sys

  import mailchannels

  if not os.environ.get("MAILCHANNELS_API_KEY"):
      sys.exit("Set MAILCHANNELS_API_KEY before running")

  from_email = os.environ.get("FROM_EMAIL")
  to_email = os.environ.get("TO_EMAIL")
  if not from_email:
      sys.exit("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)")
  if not to_email:
      sys.exit("Set TO_EMAIL")

  response = mailchannels.Emails.send(
      {
          "from": {"email": from_email, "name": "Your Name"},
          "to": [{"email": to_email, "name": "Recipient"}],
          "subject": "Hello from MailChannels (sync)",
          "text": "This message was sent with Emails.send. The caller waited for the response.",
      }
  )

  print(response)
  ```

  ```php PHP theme={null}
  <?php

  require_once __DIR__ . '/vendor/autoload.php';

  use MailChannels\Client;

  $api_key    = getenv('MAILCHANNELS_API_KEY') or exit("Error: MAILCHANNELS_API_KEY is not set\n");
  $from_email = getenv('FROM_EMAIL') or exit("Error: FROM_EMAIL is not set\n");
  $to_email   = getenv('TO_EMAIL') or exit("Error: TO_EMAIL is not set\n");

  $client = new Client(apiKey: $api_key);

  $response = $client->emails->send([
      'from'    => ['email' => $from_email, 'name' => 'Your Name'],
      'to'      => ['email' => $to_email, 'name' => 'Recipient'],
      'subject' => 'Hello from MailChannels (sync)',
      'text'    => 'This message was sent with emails->send. The caller waited for the response.',
  ]);

  print_r($response->toArray());
  ```
</CodeGroup>

Send asynchronously:

<CodeGroup>
  ```bash cURL theme={null}
  #!/usr/bin/env bash
  # Send an email asynchronously.

    set -u
    : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
    : "${FROM_EMAIL:?Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)}"
    : "${TO_EMAIL:?Set TO_EMAIL}"

  curl -X POST https://api.mailchannels.net/tx/v1/send-async \
    -H "Content-Type: application/json" \
    -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
    -d @- <<JSON
  {
    "personalizations": [
      { "to": [{ "email": "$TO_EMAIL", "name": "Recipient" }] }
    ],
    "from": {
      "email": "$FROM_EMAIL",
      "name": "Your Name"
    },
    "subject": "Hello from MailChannels (async)",
    "content": [
      {
        "type": "text/plain",
        "value": "This message was sent with POST /tx/v1/send-async. Delivery status will arrive via webhook."
      }
    ]
  }
  JSON
  ```

  ```javascript Node.js theme={null}
  // Send an email asynchronously.
  import { MailChannels } from "mailchannels-sdk";

  const { MAILCHANNELS_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env;
  if (!MAILCHANNELS_API_KEY) throw new Error("Set MAILCHANNELS_API_KEY before running");
  if (!FROM_EMAIL) throw new Error("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)");
  if (!TO_EMAIL) throw new Error("Set TO_EMAIL");

  const mailchannels = new MailChannels(MAILCHANNELS_API_KEY);

  const { data, error } = await mailchannels.emails.sendAsync({
    from: { email: FROM_EMAIL, name: "Your Name" },
    to: { email: TO_EMAIL, name: "Recipient" },
    subject: "Hello from MailChannels (async)",
    text: "This message was sent with POST /tx/v1/send-async. Delivery status will arrive via webhook.",
  });

  if (error) {
    console.error("Send failed:", error);
    process.exit(1);
  }
  console.log(data);
  ```

  ```python Python theme={null}
  import os
  import sys

  import mailchannels

  if not os.environ.get("MAILCHANNELS_API_KEY"):
      sys.exit("Set MAILCHANNELS_API_KEY before running")

  from_email = os.environ.get("FROM_EMAIL")
  to_email = os.environ.get("TO_EMAIL")
  if not from_email:
      sys.exit("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)")
  if not to_email:
      sys.exit("Set TO_EMAIL")

  # Emails.queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
  response = mailchannels.Emails.queue(
      {
          "from": {"email": from_email, "name": "Your Name"},
          "to": [{"email": to_email, "name": "Recipient"}],
          "subject": "Hello from MailChannels (async)",
          "text": "This message was sent with Emails.queue. Delivery status will arrive via webhook.",
      }
  )

  print(response)
  ```

  ```php PHP theme={null}
  <?php

  require_once __DIR__ . '/vendor/autoload.php';

  use MailChannels\Client;

  $api_key    = getenv('MAILCHANNELS_API_KEY') or exit("Error: MAILCHANNELS_API_KEY is not set\n");
  $from_email = getenv('FROM_EMAIL') or exit("Error: FROM_EMAIL is not set\n");
  $to_email   = getenv('TO_EMAIL') or exit("Error: TO_EMAIL is not set\n");

  $client = new Client(apiKey: $api_key);

  // emails->queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
  $response = $client->emails->queue([
      'from'    => ['email' => $from_email, 'name' => 'Your Name'],
      'to'      => ['email' => $to_email, 'name' => 'Recipient'],
      'subject' => 'Hello from MailChannels (async)',
      'text'    => 'This message was sent with emails->queue. Delivery status will arrive via webhook.',
  ]);

  print_r($response->toArray());
  ```
</CodeGroup>
