> ## 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 with a tenant

> Send to a user or a whole tenant with tenant_id, and handle users in several tenants.

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>;
};

<Info>
  <Doc href="/docs/tenants/context">How tenant context works</Doc> covers the concepts behind this page.
</Info>

The user determines who receives the message. The tenant determines which of that user's contexts Courier builds it from: whose brand, whose defaults, whose content.

You can target a single user in a tenant's context, fan out to every member of a tenant, or walk a tenant hierarchy up or down.

**The tenant goes in one of two places, and both behave identically.** Put it on the recipient as `to.tenant_id`, or on the message as `context.tenant_id`. Pick one and put it behind a shared helper, because tracking down a message that rendered with the wrong brand is a great deal harder when two call sites disagree about where the tenant lives.

## Prerequisites

* <Doc href="/docs/tenants/overview">A tenant with member users</Doc>
* <AppLink href="https://app.courier.com/settings/api-keys">A Courier API key</AppLink>

## Send to a user with tenant context

Set `context.tenant_id` on a recipient to attach the tenant's metadata, preferences, and branding to their message. User-level preferences and profile data take precedence over the tenant's.

The template holds the content. Pass the variables it expects in `data`, and reference tenant values like `{$.tenant.name}` from inside the template, where the tenant context resolves them.

<CodeGroup>
  ```javascript Node.js highlight={14} theme={null}
  import Courier from '@trycourier/courier';

  const client = new Courier({
    apiKey: process.env['COURIER_API_KEY'],
  });

  const { requestId } = await client.send.message({
    message: {
      to: {
        user_id: 'user_123',
        context: { tenant_id: 'acme-corp' },
      },
      template: 'nt_01kx4h2jdafq8bk9aftxak4b40',
      data: { first_name: 'Sarah' },
      routing: { method: 'single', channels: ['inbox'] },
    },
  });

  console.log(requestId);
  ```

  ```python Python highlight={14} theme={null}
  import os
  from courier import Courier

  client = Courier(
      api_key=os.environ.get("COURIER_API_KEY"),
  )
  response = client.send.message(
      message={
          "to": {
              "user_id": "user_123",
              "context": {"tenant_id": "acme-corp"},
          },
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "data": {"first_name": "Sarah"},
          "routing": {"method": "single", "channels": ["inbox"]},
      },
  )
  print(response.request_id)
  ```

  ```bash cURL highlight={8} 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", "context": { "tenant_id": "acme-corp" } },
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "data": { "first_name": "Sarah" },
        "routing": { "method": "single", "channels": ["inbox"] }
      }
    }'
  ```

  ```ruby Ruby highlight={12} theme={null}
  require "courier"

  courier = Courier::Client.new(api_key: ENV["COURIER_API_KEY"])

  response = courier.send_.message(
    message: {
      to: {
        user_id: "user_123",
        context: { tenant_id: "acme-corp" }
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      data: { first_name: "Sarah" },
      routing: { method: "single", channels: ["inbox"] }
    }
  )

  puts(response)
  ```

  ```go Go highlight={10} 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"),
  				Context: shared.MessageContextParam{TenantID: courier.String("acme-corp")},
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Data: map[string]any{
  			"first_name": "Sarah",
  		},
  		Routing: courier.SendMessageParamsMessageRouting{
  			Method:   string(shared.MessageRoutingMethodSingle),
  			Channels: []shared.MessageRoutingChannelUnionParam{{OfString: courier.String("inbox")}},
  		},
  	},
  })
  ```

  ```java Java highlight={7} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(JsonValue.from(java.util.Map.of(
              "user_id", "user_123",
              "context", java.util.Map.of("tenant_id", "acme-corp"))))
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .data(JsonValue.from(java.util.Map.of("first_name", "Sarah")))
          .routing(JsonValue.from(java.util.Map.of(
              "method", "single",
              "channels", java.util.List.of("inbox"))))
          .build())
      .build();
  client.send().message(params);
  ```

  ```php PHP highlight={8} theme={null}
  $response = $client->send->message(
    message: [
      'to' => [
        'userID' => 'user_123',
        'context' => ['tenantID' => 'acme-corp'],
      ],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'data' => ['first_name' => 'Sarah'],
      'routing' => ['method' => 'single', 'channels' => ['inbox']],
    ],
  );
  ```

  ```csharp C# highlight={7} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { UserID = "user_123", Context = new MessageContext { TenantID = "acme-corp" } },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Data = new Dictionary<string, JsonElement>()
          {
              { "first_name", JsonSerializer.SerializeToElement("Sarah") },
          },
          Routing = new Routing { Method = Method.Single, Channels = ["inbox"] },
      },
  };

  await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={3} theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message '{"to":{"user_id":"user_123","context":{"tenant_id":"acme-corp"}},"template":"nt_01kx4h2jdafq8bk9aftxak4b40","data":{"first_name":"Sarah"},"routing":{"method":"single","channels":["inbox"]}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to user_123 with acme-corp as their tenant context.
  ```
</CodeGroup>

A user does not need to be a member of the tenant to receive a message in its context. This is useful when the tenant holds branding or credentials but you are not fanning out to members.

## Send to every member of a tenant

Put a `tenant_id` in `to` and Courier looks up the tenant's members and sends to each one.

<CodeGroup>
  ```javascript Node.js highlight={9} theme={null}
  import Courier from '@trycourier/courier';

  const client = new Courier({
    apiKey: process.env['COURIER_API_KEY'],
  });

  const { requestId } = await client.send.message({
    message: {
      to: { tenant_id: 'acme-corp' },
      template: 'nt_01kx4h2jdafq8bk9aftxak4b40',
      data: { first_name: 'Sarah' },
      routing: { method: 'single', channels: ['inbox'] },
    },
  });

  console.log(requestId);
  ```

  ```python Python highlight={9} theme={null}
  import os
  from courier import Courier

  client = Courier(
      api_key=os.environ.get("COURIER_API_KEY"),
  )
  response = client.send.message(
      message={
          "to": {"tenant_id": "acme-corp"},
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "data": {"first_name": "Sarah"},
          "routing": {"method": "single", "channels": ["inbox"]},
      },
  )
  print(response.request_id)
  ```

  ```bash cURL highlight={6} theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "to": { "tenant_id": "acme-corp" },
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "data": { "first_name": "Sarah" },
        "routing": { "method": "single", "channels": ["inbox"] }
      }
    }'
  ```

  ```ruby Ruby highlight={7} theme={null}
  require "courier"

  courier = Courier::Client.new(api_key: ENV["COURIER_API_KEY"])

  response = courier.send_.message(
    message: {
      to: { tenant_id: "acme-corp" },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      data: { first_name: "Sarah" },
      routing: { method: "single", channels: ["inbox"] }
    }
  )

  puts(response)
  ```

  ```go Go highlight={5} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				TenantID: courier.String("acme-corp"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Data: map[string]any{
  			"first_name": "Sarah",
  		},
  		Routing: courier.SendMessageParamsMessageRouting{
  			Method:   string(shared.MessageRoutingMethodSingle),
  			Channels: []shared.MessageRoutingChannelUnionParam{{OfString: courier.String("inbox")}},
  		},
  	},
  })
  ```

  ```java Java highlight={3} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(JsonValue.from(java.util.Map.of("tenant_id", "acme-corp")))
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .data(JsonValue.from(java.util.Map.of("first_name", "Sarah")))
          .routing(JsonValue.from(java.util.Map.of(
              "method", "single",
              "channels", java.util.List.of("inbox"))))
          .build())
      .build();
  client.send().message(params);
  ```

  ```php PHP highlight={3} theme={null}
  $response = $client->send->message(
    message: [
      'to' => ['tenantID' => 'acme-corp'],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'data' => ['first_name' => 'Sarah'],
      'routing' => ['method' => 'single', 'channels' => ['inbox']],
    ],
  );
  ```

  ```csharp C# highlight={5} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { TenantID = "acme-corp" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Data = new Dictionary<string, JsonElement>()
          {
              { "first_name", JsonSerializer.SerializeToElement("Sarah") },
          },
          Routing = new Routing { Method = Method.Single, Channels = ["inbox"] },
      },
  };

  await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={3} theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message '{"to":{"tenant_id":"acme-corp"},"template":"nt_01kx4h2jdafq8bk9aftxak4b40","data":{"first_name":"Sarah"},"routing":{"method":"single","channels":["inbox"]}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to every member of acme-corp.
  ```
</CodeGroup>

## Send to multiple users with shared context

When sending to an array of users, set a shared tenant at the message level with `message.context.tenant_id`. Every recipient inherits it. Override it for a specific recipient by setting `context.tenant_id` on that entry, which takes precedence over the message-level context.

<CodeGroup>
  ```javascript Node.js highlight={10,14} theme={null}
  import Courier from '@trycourier/courier';

  const client = new Courier({
    apiKey: process.env['COURIER_API_KEY'],
  });

  const { requestId } = await client.send.message({
    message: {
      template: 'nt_01kx4h2jdafq8bk9aftxak4b40',
      context: { tenant_id: 'acme-corp' },
      to: [
        { user_id: 'user_123' },
        { user_id: 'user_456' },
        { user_id: 'user_456', context: { tenant_id: 'beta-inc' } },
      ],
    },
  });

  console.log(requestId);
  ```

  ```python Python highlight={10,14} theme={null}
  import os
  from courier import Courier

  client = Courier(
      api_key=os.environ.get("COURIER_API_KEY"),
  )
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "context": {"tenant_id": "acme-corp"},
          "to": [
              {"user_id": "user_123"},
              {"user_id": "user_456"},
              {"user_id": "user_456", "context": {"tenant_id": "beta-inc"}},
          ],
      },
  )
  print(response.request_id)
  ```

  ```bash cURL highlight={7,11} theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "context": { "tenant_id": "acme-corp" },
        "to": [
          { "user_id": "user_123" },
          { "user_id": "user_456" },
          { "user_id": "user_456", "context": { "tenant_id": "beta-inc" } }
        ]
      }
    }'
  ```

  ```ruby Ruby highlight={8,12} theme={null}
  require "courier"

  courier = Courier::Client.new(api_key: ENV["COURIER_API_KEY"])

  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      context: { tenant_id: "acme-corp" },
      to: [
        { user_id: "user_123" },
        { user_id: "user_456" },
        { user_id: "user_456", context: { tenant_id: "beta-inc" } }
      ]
    }
  )

  puts(response)
  ```

  ```go Go highlight={4,11} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Context:  shared.MessageContextParam{TenantID: courier.String("acme-corp")},
  		To: courier.SendMessageParamsMessageToUnion{
  			OfSendMessagesMessageToArray: []courier.SendMessageParamsMessageToArrayItemUnion{
  				{OfUserRecipient: &shared.UserRecipientParam{UserID: courier.String("user_123")}},
  				{OfUserRecipient: &shared.UserRecipientParam{UserID: courier.String("user_456")}},
  				{OfUserRecipient: &shared.UserRecipientParam{
  					UserID:  courier.String("user_456"),
  					Context: shared.MessageContextParam{TenantID: courier.String("beta-inc")},
  				}},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={4,8} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .context(JsonValue.from(java.util.Map.of("tenant_id", "acme-corp")))
          .to(JsonValue.from(java.util.List.of(
              java.util.Map.of("user_id", "user_123"),
              java.util.Map.of("user_id", "user_456"),
              java.util.Map.of("user_id", "user_456", "context", java.util.Map.of("tenant_id", "beta-inc")))))
          .build())
      .build();
  client.send().message(params);
  ```

  ```php PHP highlight={4,8} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'context' => ['tenantID' => 'acme-corp'],
      'to' => [
        ['userID' => 'user_123'],
        ['userID' => 'user_456'],
        ['userID' => 'user_456', 'context' => ['tenantID' => 'beta-inc']],
      ],
    ],
  );
  ```

  ```csharp C# highlight={6,11} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Context = new MessageContext { TenantID = "acme-corp" },
          To = new List<Recipient>
          {
              new UserRecipient { UserID = "user_123" },
              new UserRecipient { UserID = "user_456" },
              new UserRecipient { UserID = "user_456", Context = new MessageContext { TenantID = "beta-inc" } },
          },
      },
  };

  await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={3} theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message '{"template":"nt_01kx4h2jdafq8bk9aftxak4b40","context":{"tenant_id":"acme-corp"},"to":[{"user_id":"user_123"},{"user_id":"user_456"},{"user_id":"user_456","context":{"tenant_id":"beta-inc"}}]}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to user_123 and user_456 in acme-corp, and user_456 in beta-inc.
  ```
</CodeGroup>

Here `user_123` and `user_456` get Acme Corp's context, while `user_456` gets Beta Inc's.

## Handle users in multiple tenants

Courier infers the tenant for a user who belongs to exactly one tenant, so specifying it is optional for them. A user with two or more memberships must have `context.tenant_id` set, or the send returns `Tenant Context Not Found`.

<Warning>
  In the `tenant/<template_id>` format, `tenant` is the literal word rather than your tenant ID, which goes in `context.tenant_id`. <Doc href="/docs/tenants/templates">Create & manage tenant templates</Doc> has the full format.
</Warning>

## Fan out across a hierarchy

Set `include_children: true` to also send to users in a tenant's descendant tenants, or `include_parent: true` to walk upward through its ancestors.

<CodeGroup>
  ```javascript Node.js theme={null}
  import Courier from '@trycourier/courier';

  const client = new Courier({
    apiKey: process.env['COURIER_API_KEY'],
  });

  const { requestId } = await client.send.message({
    message: {
      to: { tenant_id: 'acme-corp', include_children: true },
      template: 'nt_01kx4h2jdafq8bk9aftxak4b40',
      routing: { method: 'single', channels: ['inbox'] },
    },
  });

  console.log(requestId);
  ```

  ```python Python theme={null}
  import os
  from courier import Courier

  client = Courier(
      api_key=os.environ.get("COURIER_API_KEY"),
  )
  response = client.send.message(
      message={
          "to": {"tenant_id": "acme-corp", "include_children": True},
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "routing": {"method": "single", "channels": ["inbox"]},
      },
  )
  print(response.request_id)
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "to": { "tenant_id": "acme-corp", "include_children": true },
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "routing": { "method": "single", "channels": ["inbox"] }
      }
    }'
  ```

  ```ruby Ruby theme={null}
  require "courier"

  courier = Courier::Client.new(api_key: ENV["COURIER_API_KEY"])

  response = courier.send_.message(
    message: {
      to: { tenant_id: "acme-corp", include_children: true },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      routing: { method: "single", channels: ["inbox"] }
    }
  )

  puts(response)
  ```

  ```go Go theme={null}
  // include_children isn't in the typed recipient model, so set it as an extra field.
  to := shared.UserRecipientParam{}
  to.SetExtraFields(map[string]any{
  	"tenant_id":        "acme-corp",
  	"include_children": true,
  })

  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To:       courier.SendMessageParamsMessageToUnion{OfUserRecipient: &to},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Routing: courier.SendMessageParamsMessageRouting{
  			Method:   string(shared.MessageRoutingMethodSingle),
  			Channels: []shared.MessageRoutingChannelUnionParam{{OfString: courier.String("inbox")}},
  		},
  	},
  })
  ```

  ```java Java theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(JsonValue.from(java.util.Map.of(
              "tenant_id", "acme-corp",
              "include_children", true)))
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .routing(JsonValue.from(java.util.Map.of(
              "method", "single",
              "channels", java.util.List.of("inbox"))))
          .build())
      .build();
  client.send().message(params);
  ```

  ```php PHP theme={null}
  $response = $client->send->message(
    message: [
      'to' => ['tenantID' => 'acme-corp', 'include_children' => true],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'routing' => ['method' => 'single', 'channels' => ['inbox']],
    ],
  );
  ```

  ```csharp C# theme={null}
  // include_children isn't in the typed recipient model, so build `to` from raw JSON.
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = UserRecipient.FromRawUnchecked(new Dictionary<string, JsonElement>
          {
              ["tenant_id"] = JsonSerializer.SerializeToElement("acme-corp"),
              ["include_children"] = JsonSerializer.SerializeToElement(true),
          }),
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Routing = new Routing { Method = Method.Single, Channels = ["inbox"] },
      },
  };

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

  ```bash CLI theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message '{"to":{"tenant_id":"acme-corp","include_children":true},"template":"nt_01kx4h2jdafq8bk9aftxak4b40","routing":{"method":"single","channels":["inbox"]}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my nt_01kx4h2jdafq8bk9aftxak4b40 template to acme-corp and all of its child tenants.
  ```
</CodeGroup>

Courier traverses up to four levels of the hierarchy in either direction.

<Note>
  On Go and C#, `include_children` and `include_parent` aren't in the typed recipient models yet, so the tabs above set them as extra fields on the recipient. Every other operation on this page has a fully typed Go and C# form.
</Note>

## Segment delivery data by customer

Courier records the tenant on the message at `providers[].reference.tenantId`, so you can group logs and delivery data by customer after the fact. Read it from the <Doc href="/docs/monitor/overview">message record</Doc> or from a <Doc href="/docs/monitor/webhooks/outbound">delivery webhook</Doc>.

A send that never named a tenant carries no reference, which is one more reason to route every multi-tenant send through the same helper.

## Limits & behavior

None of these raise an error, which is what makes them worth knowing before you ship.

* **Courier can apply a tenant you did not name.** If the user belongs to exactly one tenant and the send specifies none, Courier loads that tenant's context anyway. See <Doc href="/docs/tenants/context#auto-infer-tenant-context">auto-infer</Doc>, and turn it off in workspace settings if you would rather send unscoped.
* **A tenant-scoped inbox message is invisible to a client signed in without the tenant.** The send reports success and the feed stays empty. Pass the same `tenantId` to `signIn` that your sends carry.
* **Hierarchy traversal stops at four levels.** The window starts at the tenant you sent to rather than at the root, so a fifth ancestor's settings never reach the message.

## Verify

<Steps>
  <Step title="Send with a branded tenant">
    Send with a tenant that has a `brand_id` set, and confirm the message renders with that tenant's brand (see <Doc href="/docs/tenants/context#how-a-send-picks-a-brand">brand selection</Doc>).
  </Step>

  <Step title="Check the message log">
    Confirm the send used the tenant's preferences, not the workspace defaults.
  </Step>

  <Step title="Confirm fan-out delivery">
    For a fan-out send, confirm each expected member received a copy.
  </Step>
</Steps>
