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

> ## Agent Instructions
> Install the Courier skill before writing code: `npx skills add trycourier/courier-skills`. It carries the verified SDK shapes and the rules you cannot get wrong.
> Authenticate every request with `Authorization: Bearer <API_KEY>`. A workspace has several environments and each has its own keys, which are plain `pk_` strings with no environment prefix. Start with Test.
> Send with `client.send.message` from the Node SDK (`@trycourier/courier` v7 and later, where the client is the default import). Reference a template by its `nt_` id or its alias.
> A send accepts a bare Elemental element list, but storing content on a template requires the top-level elements wrapped in a channel element.
> Templates and journeys can be built in the Courier app or created through the API. Either way they live in the workspace and are referenced by ID when you send.
> The hosted MCP server is https://mcp.courier.com. For a briefing on what Courier is and when to use it, read https://www.courier.com/llms.txt.
> Prefer the Guides tab for how-do-I questions and the Docs tab for how-does-it-behave questions. The API reference lives under /api-reference.

# Email providers

> Every email provider Courier supports, what a send needs on the profile, and channel overrides.

export const Endpoint = ({method, path, name, href, children, bare}) => {
  const verb = String(method || "").toUpperCase();
  const title = verb + " " + path;
  const label = children || name || path;
  if (bare) {
    return href ? <a href={href}><code>{title}</code></a> : <code>{title}</code>;
  }
  if (!href) {
    return <span className="cx-endpoint" data-method={verb} title={title}>
        <span className="cx-endpoint-label">{label}</span>
        <span className="cx-endpoint-method">{verb}</span>
      </span>;
  }
  return <a className="cx-endpoint" data-method={verb} href={href} title={title}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">{verb}</span>
    </a>;
};

export const Guide = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="guide" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">GUIDE</span>
    </a>;
};

export const Doc = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="doc" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">DOC</span>
    </a>;
};

## Available providers

<CardGroup cols={3}>
  <Card title="Amazon SES" href="/docs/integrations/email/aws-ses" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-aws-ses.svg?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=cf1bad8459bea3e4f03f93572af48327" horizontal width="24" height="24" data-path="assets/provider-aws-ses.svg" />

  <Card title="SendGrid" href="/docs/integrations/email/sendgrid" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-sendgrid.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=bf1a98ed25e33991a1fba0d04916108c" horizontal width="216" height="216" data-path="assets/provider-sendgrid.webp" />

  <Card title="Postmark" href="/docs/integrations/email/postmark" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-postmark.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=7f5024074c5ccb09a7bc39878d3757c9" horizontal width="216" height="216" data-path="assets/provider-postmark.webp" />

  <Card title="Mailgun" href="/docs/integrations/email/mailgun" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-mailgun.svg?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=0209db7e7a659781558b42e4f51d7c60" horizontal width="24" height="24" data-path="assets/provider-mailgun.svg" />

  <Card title="Resend" href="/docs/integrations/email/resend" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-resend.svg?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=c7ea94733ea9e18e805466ff22675ef8" horizontal width="24" height="24" data-path="assets/provider-resend.svg" />

  <Card title="SMTP" href="/docs/integrations/email/smtp" icon="server" horizontal />

  <Card title="Mandrill" href="/docs/integrations/email/mandrill" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-mandrill.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=d4ee83d3836b32c8e724213b57bb83d9" horizontal width="216" height="216" data-path="assets/provider-mandrill.webp" />

  <Card title="SparkPost" href="/docs/integrations/email/sparkpost" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-sparkpost.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=c575b948fed3672ffa03fd8c0e0eb290" horizontal width="216" height="216" data-path="assets/provider-sparkpost.webp" />

  <Card title="Mailjet" href="/docs/integrations/email/mailjet" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-mailjet.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=1c8dddac36d59d6085ea4fe5eca7d991" horizontal width="216" height="216" data-path="assets/provider-mailjet.webp" />

  <Card title="MailerSend" href="/docs/integrations/email/mailersend" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-mailersend.svg?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=01b1c2a9045b42c0f5b31ca16f3cebe2" horizontal width="24" height="24" data-path="assets/provider-mailersend.svg" />

  <Card title="Amply" href="/docs/integrations/email/amply" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-amply.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=627b40186efad4f9c1eab3f14608b979" horizontal width="216" height="216" data-path="assets/provider-amply.webp" />

  <Card title="Gmail" href="/docs/integrations/email/gmail" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-gmail.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=76c42b3aab8281988902a86cdf7641b8" horizontal width="216" height="216" data-path="assets/provider-gmail.webp" />

  <Card title="OneSignal" href="/docs/integrations/email/onesignal-email" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-onesignal-email.svg?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=eaab013b4c02d1f87e2bb2a95ef0b7c6" horizontal width="24" height="24" data-path="assets/provider-onesignal-email.svg" />
</CardGroup>

<Doc href="/docs/integrations/email/smtp">SMTP</Doc> is the generic relay for any server that speaks it.

<Doc href="/docs/integrations/email/gmail">Gmail</Doc> is OAuth-based and suits testing rather than volume.

## Profile requirements

Every email provider addresses the recipient the same way, by email address, so the profile you send to needs an `email`. Store it once with <Endpoint method="POST" path="/profiles/{user_id}" name="Create a Profile" href="/docs/api-reference/user-profiles/create-a-profile" />, which merges into the profile and creates it if it does not exist:

<CodeGroup>
  ```javascript Node.js highlight={3} theme={null}
  const profile = await client.profiles.create('user_123', {
    profile: {
      email: 'sarah@acme-corp.com',
    },
  });
  ```

  ```python Python highlight={4} theme={null}
  profile = client.profiles.create(
      user_id="user_123",
      profile={
          "email": "sarah@acme-corp.com",
      },
  )
  ```

  ```bash cURL highlight={7} theme={null}
  curl --request POST \
    --url https://api.courier.com/profiles/user_123 \
    --header "Authorization: Bearer $COURIER_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
      "profile": {
        "email": "sarah@acme-corp.com"
      }
    }'
  ```

  ```ruby Ruby highlight={4} theme={null}
  profile = courier.profiles.create(
    "user_123",
    profile: {
      email: "sarah@acme-corp.com"
    }
  )
  ```

  ```go Go highlight={6} theme={null}
  profile, err := client.Profiles.New(
  	context.TODO(),
  	"user_123",
  	courier.ProfileNewParams{
  		Profile: map[string]any{
  			"email": "sarah@acme-corp.com",
  		},
  	},
  )
  ```

  ```java Java highlight={4} theme={null}
  ProfileCreateParams params = ProfileCreateParams.builder()
      .userId("user_123")
      .profile(ProfileCreateParams.Profile.builder()
          .putAdditionalProperty("email", JsonValue.from("sarah@acme-corp.com"))
          .build())
      .build();
  ProfileCreateResponse profile = client.profiles().create(params);
  ```

  ```php PHP highlight={2} theme={null}
  $profile = $client->profiles->create('user_123', profile: [
    'email' => 'sarah@acme-corp.com',
  ]);
  ```

  ```csharp C# highlight={6} theme={null}
  ProfileCreateParams parameters = new()
  {
      UserID = "user_123",
      Profile = new Dictionary<string, JsonElement>()
      {
          { "email", JsonSerializer.SerializeToElement("sarah@acme-corp.com") },
      },
  };
  var profile = await client.Profiles.Create(parameters);
  ```

  ```bash CLI highlight={4} theme={null}
  courier profiles create \
    --api-key "$COURIER_API_KEY" \
    --user-id user_123 \
    --profile '{"email":"sarah@acme-corp.com"}'
  ```

  ```text MCP theme={null}
  With Courier MCP, create a profile for user_123 with the email sarah@acme-corp.com.
  ```
</CodeGroup>

A provider that also accepts an inline address still reads `email` off the profile when you send to a `user_id`, which is what lets preferences apply and lets the address change without touching your send code.

## Send to a recipient

<Tabs>
  <Tab title="Send to user id">
    Courier reads `email` off the saved profile, so preferences apply and the address can change without touching this code.

    <CodeGroup>
      ```javascript Node.js highlight={4} theme={null}
      const { requestId } = await courier.send.message({
        message: {
          to: {
            user_id: "user_123",
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40",
        },
      });
      ```

      ```python Python highlight={4} theme={null}
      response = client.send.message(
          message={
              "to": {
                  "user_id": "user_123",
              },
              "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          },
      )
      ```

      ```bash cURL highlight={7} wrap theme={null}
      curl -X POST https://api.courier.com/send \
        -H "Authorization: Bearer $COURIER_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "message": {
            "to": {
              "user_id": "user_123"
            },
            "template": "nt_01kx4h2jdafq8bk9aftxak4b40"
          }
        }'
      ```

      ```ruby Ruby highlight={4} theme={null}
      response = courier.send_.message(
        message: {
          to: {
            user_id: "user_123"
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40"
        }
      )
      ```

      ```go Go highlight={5} theme={null}
      response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
      	Message: courier.SendMessageParamsMessage{
      		To: courier.SendMessageParamsMessageToUnion{
      			OfUserRecipient: &shared.UserRecipientParam{
      				UserID: courier.String("user_123"),
      			},
      		},
      		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
      	},
      })
      ```

      ```java Java highlight={3} theme={null}
      SendMessageParams params = SendMessageParams.builder()
          .message(SendMessageParams.Message.builder()
              .to(UserRecipient.builder().userId("user_123").build())
              .template("nt_01kx4h2jdafq8bk9aftxak4b40")
              .build())
          .build();
      SendMessageResponse response = client.send().message(params);
      ```

      ```php PHP highlight={4} theme={null}
      $response = $client->send->message(
        message: [
          'to' => [
            'user_id' => 'user_123',
          ],
          'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
        ],
      );
      ```

      ```csharp C# highlight={5} theme={null}
      SendMessageParams parameters = new()
      {
          Message = new()
          {
              To = new UserRecipient { UserID = "user_123" },
              Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          },
      };

      var response = await client.Send.Message(parameters);
      ```

      ```bash CLI highlight={3} wrap theme={null}
      courier send message \
        --api-key "$COURIER_API_KEY" \
        --message.to '{"user_id": "user_123"}' \
        --message.template nt_01kx4h2jdafq8bk9aftxak4b40
      ```

      ```text MCP theme={null}
      With Courier MCP, send my template to user_123 by email.
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Send to email">
    A one-off to an address you are not storing. No profile is created, so no preference applies.

    <CodeGroup>
      ```javascript Node.js highlight={4} theme={null}
      const { requestId } = await courier.send.message({
        message: {
          to: {
            email: "sarah@acme-corp.com",
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40",
        },
      });
      ```

      ```python Python highlight={4} theme={null}
      response = client.send.message(
          message={
              "to": {
                  "email": "sarah@acme-corp.com",
              },
              "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          },
      )
      ```

      ```bash cURL highlight={7} wrap theme={null}
      curl -X POST https://api.courier.com/send \
        -H "Authorization: Bearer $COURIER_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "message": {
            "to": {
              "email": "sarah@acme-corp.com"
            },
            "template": "nt_01kx4h2jdafq8bk9aftxak4b40"
          }
        }'
      ```

      ```ruby Ruby highlight={4} theme={null}
      response = courier.send_.message(
        message: {
          to: {
            email: "sarah@acme-corp.com"
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40"
        }
      )
      ```

      ```go Go highlight={5} theme={null}
      response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
      	Message: courier.SendMessageParamsMessage{
      		To: courier.SendMessageParamsMessageToUnion{
      			OfUserRecipient: &shared.UserRecipientParam{
      				Email: courier.String("sarah@acme-corp.com"),
      			},
      		},
      		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
      	},
      })
      ```

      ```java Java highlight={3} theme={null}
      SendMessageParams params = SendMessageParams.builder()
          .message(SendMessageParams.Message.builder()
              .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
              .template("nt_01kx4h2jdafq8bk9aftxak4b40")
              .build())
          .build();
      SendMessageResponse response = client.send().message(params);
      ```

      ```php PHP highlight={4} theme={null}
      $response = $client->send->message(
        message: [
          'to' => [
            'email' => 'sarah@acme-corp.com',
          ],
          'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
        ],
      );
      ```

      ```csharp C# highlight={5} theme={null}
      SendMessageParams parameters = new()
      {
          Message = new()
          {
              To = new UserRecipient { Email = "sarah@acme-corp.com" },
              Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          },
      };

      var response = await client.Send.Message(parameters);
      ```

      ```bash CLI highlight={3} wrap theme={null}
      courier send message \
        --api-key "$COURIER_API_KEY" \
        --message.to '{"email": "sarah@acme-corp.com"}' \
        --message.template nt_01kx4h2jdafq8bk9aftxak4b40
      ```

      ```text MCP theme={null}
      With Courier MCP, send my template to sarah@acme-corp.com by email.
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Channel overrides

<Doc href="/docs/send/overrides#how-overrides-work">How overrides work</Doc> covers the two levels and which one wins. These are the fields an email channel override accepts.

The sender is the field most often overridden. With no override and no template **From**, an email goes out as the **From Address** on the provider's integration. <Guide href="/docs/guides/send-from-your-domain">Send from your own domain</Guide> covers all three levels. Postmark, Amply, and MailerSend also accept a sender inside a provider override at `override.config.fromAddress`. On MailerSend that value beats a channel override, and on the other two the channel override still wins.

### Available channel override fields

Every field you can set in `message.channels.email.override`. All are optional.

| Field         | Type   | Description                                                                                                                                                                           |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `subject`     | string | Overrides the email subject line.                                                                                                                                                     |
| `from`        | string | Sender address. Accepts a plain email or `"Display Name <email>"` format.                                                                                                             |
| `reply_to`    | string | Sets the Reply-To header. Same format as `from`.                                                                                                                                      |
| `cc`          | string | CC recipients as a comma-separated string (e.g. `"sarah@acme-corp.com,ops@acme-corp.com"`).                                                                                           |
| `bcc`         | string | BCC recipients as a comma-separated string. Courier converts this to an array for providers that require it.                                                                          |
| `html`        | string | Replaces the rendered HTML body entirely.                                                                                                                                             |
| `text`        | string | Replaces the plain-text body.                                                                                                                                                         |
| `attachments` | array  | File attachments. Schema varies by provider. See the provider page.                                                                                                                   |
| `brand`       | object | Overrides brand settings (logo, colors). Uses the same schema as <Endpoint method="POST" path="/brands" name="Create a new Brand" href="/docs/api-reference/brands/create-a-new-brand" />. |
| `tracking`    | object | Controls tracking behavior. Set `{ "open": false }` to disable open tracking.                                                                                                         |

Set any of them under `channels.email.override` on the send. The table above is the full list:

<CodeGroup>
  ```javascript Node.js highlight={7-10} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      to: { email: 'sarah@acme-corp.com' },
      template: 'nt_01kx4h2jdafq8bk9aftxak4b40',
      channels: {
        email: {
          override: {
            subject: 'Your order has shipped',
            reply_to: 'support@acme-corp.com',
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={7-10} theme={null}
  response = client.send.message(
      message={
          "to": {"email": "sarah@acme-corp.com"},
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "channels": {
              "email": {
                  "override": {
                      "subject": "Your order has shipped",
                      "reply_to": "support@acme-corp.com",
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={10-13} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "to": { "email": "sarah@acme-corp.com" },
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "channels": {
          "email": {
            "override": {
              "subject": "Your order has shipped",
              "reply_to": "support@acme-corp.com"
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={7-10} theme={null}
  response = courier.send_.message(
    message: {
      to: { email: "sarah@acme-corp.com" },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      channels: {
        email: {
          override: {
            subject: "Your order has shipped",
            reply_to: "support@acme-corp.com"
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={11-14} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				Email: courier.String("sarah@acme-corp.com"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Channels: shared.MessageChannelsParam{
  			"email": shared.ChannelParam{
  				Override: map[string]any{
  					"subject":  "Your order has shipped",
  					"reply_to": "support@acme-corp.com",
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={7-9} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .channels(MessageChannels.builder()
              .putAdditionalProperty("email", JsonValue.from(java.util.Map.of(
                  "override", java.util.Map.of(
                      "subject", "Your order has shipped",
                      "reply_to", "support@acme-corp.com"))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={7-10} theme={null}
  $response = $client->send->message(
    message: [
      'to' => ['email' => 'sarah@acme-corp.com'],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'channels' => [
        'email' => [
          'override' => [
            'subject' => 'Your order has shipped',
            'reply_to' => 'support@acme-corp.com',
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={13-17} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Channels = new Dictionary<string, Channel>()
          {
              {
                  "email",
                  new()
                  {
                      Override = new Dictionary<string, JsonElement>()
                      {
                          { "subject", JsonSerializer.SerializeToElement("Your order has shipped") },
                          { "reply_to", JsonSerializer.SerializeToElement("support@acme-corp.com") },
                      },
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.channels '{"email":{"override":{"subject":"Your order has shipped","reply_to":"support@acme-corp.com"}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to sarah@acme-corp.com and override the email subject to "Your order has shipped".
  ```
</CodeGroup>

## Brand override

The `channels.email.override.brand` property uses the same schema as the <Endpoint method="POST" path="/brands" name="Create a new Brand" href="/docs/api-reference/brands/create-a-new-brand" /> request payload.

You can override:

* logo
* top bar color
* brand colors

**Example:**

```json theme={null}
{
  "message": {
    // ...rest of request
    "channels": {
      "email": {
        "override": {
          "brand": {
            "settings": {
              "email": {
                "header": {
                  "logo": {
                    "image": "https://www.courier.com/logo.png",
                    "href": "https://www.courier.com"
                  },
                  "barColor": "#674ea7"
                }
              }
            }
          }
        }
      }
    }
  }
}
```

## Allowlist for AWS IP addresses

Some providers, such as Mailgun, let you [allowlist the IP addresses](https://help.mailgun.com/hc/en-us/articles/360012244474-IP-Allowlist) that reach their API. Courier runs on AWS and does not publish an IP range to allowlist.

Instead, subscribe to the `AmazonIpSpaceChanged` topic to get notified when AWS IP ranges change. See the [AWS documentation](https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#subscribe-notifications).
