> ## 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`, the default import of the v7 Node SDK. 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.

# Send from your own domain

> Set the default from address, then override it for one template or one send.

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 AppLink = ({href, children, name, bare}) => {
  const label = children || name || "Open in Courier";
  if (bare) {
    return <a href={href} target="_blank" rel="noreferrer">{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="app" href={href} target="_blank" rel="noreferrer">
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method" aria-hidden="true">↗</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>;
};

Set the address your email comes from, then override it for one template or one send.

## What you will build

```mermaid theme={null}
flowchart LR
    A["Verify domain"] --> B["Integration default"]
    B --> C{"Different sender?"}
    C -->|Per template| D["Template From"]
    C -->|Per send| E["Send override"]
```

Set the integration default once. Reach for the other two only when a template or a single message needs a different sender.

## Prerequisites

* A domain you control, with access to its DNS records
* <Doc href="/docs/integrations/email/overview">A connected email provider</Doc>
* <AppLink href="https://app.courier.com/integrations">The Courier integrations page</AppLink>

## Set the sender

<Steps>
  <Step title="Verify the domain at your provider">
    Courier does not verify domains. Your email provider does, and it enforces the result when the message goes out.

    Add the DKIM and SPF records your provider asks for, then wait for it to mark the domain verified. [SendGrid's Sender Authentication](https://app.sendgrid.com/settings/sender_auth) and [Amazon SES verified identities](https://console.aws.amazon.com/ses/home#/verified-identities) are the two most common.

    An unverified domain fails at the provider, not in Courier. The message lands in <AppLink href="https://app.courier.com/logs">Logs</AppLink> as undeliverable with the provider's error attached.
  </Step>

  <Step title="Set the From Address on the integration">
    Open your provider in <AppLink href="https://app.courier.com/integrations">Integrations</AppLink> and set **From Address** to an address on the verified domain. Every email through that provider uses it unless something below overrides it.

    Some providers also have a **From Name** field. Where there is none, put the display name in the address itself.

    ```text theme={null}
    Acme Support <support@acme-corp.com>
    ```
  </Step>
</Steps>

## Override it for one template

Open the template's email channel and fill **From** in the subject bar. It takes the same `Name <email>` form, and it accepts <Doc href="/docs/design/templates/variables">variables</Doc>, so one template can send as a different address per message.

Reply-To, CC, and BCC sit beside it. <Doc href="/docs/send/overrides">Channel overrides</Doc> covers all four.

## Override it for one send

A <Endpoint method="POST" path="/send" name="Send a message" href="/docs/api-reference/send/send-a-message" /> request carries `message.channels.email.override.from`, which replaces the sender for that message alone, whichever email provider ends up sending it.

<CodeGroup>
  ```javascript Node.js highlight={9-11} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      to: {
        user_id: "user_123",
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      channels: {
        email: {
          override: {
            from: "Acme Support <support@acme-corp.com>",
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={9-11} theme={null}
  response = client.send.message(
      message={
          "to": {
              "user_id": "user_123",
          },
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "channels": {
              "email": {
                  "override": {
                      "from": "Acme Support <support@acme-corp.com>",
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={12-14} 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",
        "channels": {
          "email": {
            "override": {
              "from": "Acme Support <support@acme-corp.com>"
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={9-11} theme={null}
  response = courier.send_.message(
    message: {
      to: {
        user_id: "user_123"
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      channels: {
        email: {
          override: {
            from: "Acme Support <support@acme-corp.com>"
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={11-13} 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"),
  		Channels: shared.MessageChannelsParam{
  			"email": shared.ChannelParam{
  				Override: map[string]any{
  					"from": "Acme Support <support@acme-corp.com>",
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={7-8} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().userId("user_123").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .channels(MessageChannels.builder()
              .putAdditionalProperty("email", JsonValue.from(
                  java.util.Map.of("override", java.util.Map.of(
                      "from", "Acme Support <support@acme-corp.com>"))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={9-11} theme={null}
  $response = $client->send->message(
    message: [
      'to' => [
        'user_id' => 'user_123',
      ],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'channels' => [
        'email' => [
          'override' => [
            'from' => 'Acme Support <support@acme-corp.com>',
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={13-16} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { UserID = "user_123" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Channels = new Dictionary<string, Channel>
          {
              {
                  "email",
                  new Channel
                  {
                      Override = new Dictionary<string, JsonElement>()
                      {
                          { "from", JsonSerializer.SerializeToElement("Acme Support <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 '{"user_id": "user_123"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.channels '{"email": {"override": {"from": "Acme Support <support@acme-corp.com>"}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to user_123 from Acme Support <support@acme-corp.com>.
  ```
</CodeGroup>

## How the levels resolve

Every email provider resolves the sender the same way, taking the first one set:

| Order | Where it comes from                          | Scope                             |
| ----- | -------------------------------------------- | --------------------------------- |
| 1     | `message.channels.email.override.from`       | One message                       |
| 2     | The template's email **From** field          | Every send of that template       |
| 3     | **From Address** on the provider integration | Every email through that provider |

Nothing set at any level is a send-time error, not a silent fallback to a Courier address.

A few providers also accept a sender inside a provider override, such as `message.providers.postmark.override.config.fromAddress`. That form is provider-specific, and where it sits in the order above varies by provider, so check the provider's page before relying on it.

## Verify

Send a test, open the message in <AppLink href="https://app.courier.com/logs">Logs</AppLink>, and read the **Raw** tab. It shows the request Courier made to the provider, which is the only place the final sender appears. Courier applies overrides after rendering, so the Rendered tab shows the pre-override value.

## FAQ

<AccordionGroup>
  <Accordion title="Why is my template's From field ignored on Gmail?">
    Gmail sends as the authorized inbox, so the From address is always the connected Google account. A template From field has no effect there. Set the display name with the integration's **From Name**, and change the address by authorizing a different inbox.
  </Accordion>

  <Accordion title="My provider has no From Name field. How do I set a display name?">
    Put it in the address: `Acme Support <support@acme-corp.com>`. Most email providers have no separate name field, so this form is how you set a display name.
  </Accordion>

  <Accordion title="Can a brand control the sender?">
    <Doc href="/docs/design/brands">Brands</Doc> carry visual styling only, with no sender field of any kind. The sending address is provider and template configuration.
  </Accordion>

  <Accordion title="Is a branded tracking domain the same thing?">
    Link and open tracking uses a separate CNAME to Courier's tracking infrastructure, set up independently of your sending domain. See <Doc href="/docs/monitor/tracking#custom-link-tracking-domain">tracking</Doc>.
  </Accordion>
</AccordionGroup>
