> ## 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.

# Deliver Courier messages to your own webhook

> Deliver messages as HTTP requests to a static URL or one from the profile.

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

## Prerequisites

* A destination URL that accepts HTTP requests

## Setup

For a static destination, set the Webhook URL and Authorization type on the <AppLink href="https://app.courier.com/integrations/webhook">webhook integration setup page</AppLink>.

## Profile requirements

Every HTTP request needs a destination.

### Dynamic destination

To set the destination per recipient, choose "Dynamic Destination" and store a `webhook` object on the profile. 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-13} theme={null}
  const profile = await client.profiles.create('user_123', {
    profile: {
      webhook: {
        url: 'https://www.example.com',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        authentication: {
          mode: 'bearer',
          token: 'ABCDEFG123456',
        },
      },
    },
  });
  ```

  ```python Python highlight={4-14} theme={null}
  profile = client.profiles.create(
      user_id="user_123",
      profile={
          "webhook": {
              "url": "https://www.example.com",
              "method": "POST",
              "headers": {
                  "Content-Type": "application/json",
              },
              "authentication": {
                  "mode": "bearer",
                  "token": "ABCDEFG123456",
              },
          },
      },
  )
  ```

  ```bash cURL highlight={7-17} 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": {
        "webhook": {
          "url": "https://www.example.com",
          "method": "POST",
          "headers": {
            "Content-Type": "application/json"
          },
          "authentication": {
            "mode": "bearer",
            "token": "ABCDEFG123456"
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={4-14} theme={null}
  profile = courier.profiles.create(
    "user_123",
    profile: {
      webhook: {
        url: "https://www.example.com",
        method: "POST",
        headers: {
          "Content-Type" => "application/json"
        },
        authentication: {
          mode: "bearer",
          token: "ABCDEFG123456"
        }
      }
    }
  )
  ```

  ```go Go highlight={6-16} theme={null}
  profile, err := client.Profiles.New(
  	context.TODO(),
  	"user_123",
  	courier.ProfileNewParams{
  		Profile: map[string]any{
  			"webhook": map[string]any{
  				"url": "https://www.example.com",
  				"method": "POST",
  				"headers": map[string]any{
  					"Content-Type": "application/json",
  				},
  				"authentication": map[string]any{
  					"mode": "bearer",
  					"token": "ABCDEFG123456",
  				},
  			},
  		},
  	},
  )
  ```

  ```java Java highlight={4-11} theme={null}
  ProfileCreateParams params = ProfileCreateParams.builder()
      .userId("user_123")
      .profile(ProfileCreateParams.Profile.builder()
          .putAdditionalProperty("webhook", JsonValue.from(java.util.Map.of(
              "url", "https://www.example.com",
              "method", "POST",
              "headers", java.util.Map.of(
                  "Content-Type", "application/json"),
              "authentication", java.util.Map.of(
                  "mode", "bearer",
                  "token", "ABCDEFG123456"))))
          .build())
      .build();
  ProfileCreateResponse profile = client.profiles().create(params);
  ```

  ```php PHP highlight={2-12} theme={null}
  $profile = $client->profiles->create('user_123', profile: [
    'webhook' => [
      'url' => 'https://www.example.com',
      'method' => 'POST',
      'headers' => [
        'Content-Type' => 'application/json',
      ],
      'authentication' => [
        'mode' => 'bearer',
        'token' => 'ABCDEFG123456',
      ],
    ],
  ]);
  ```

  ```csharp C# highlight={7-17} theme={null}
  ProfileCreateParams parameters = new()
  {
      UserID = "user_123",
      Profile = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
          """
          {
            "webhook": {
              "url": "https://www.example.com",
              "method": "POST",
              "headers": {
                "Content-Type": "application/json"
              },
              "authentication": {
                "mode": "bearer",
                "token": "ABCDEFG123456"
              }
            }
          }
          """
      ),
  };
  var profile = await client.Profiles.Create(parameters);
  ```

  ```bash CLI highlight={4} wrap theme={null}
  courier profiles create \
    --api-key "$COURIER_API_KEY" \
    --user-id user_123 \
    --profile '{"webhook":{"url":"https://www.example.com","method":"POST","headers":{"Content-Type":"application/json"},"authentication":{"mode":"bearer","token":"ABCDEFG123456"}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, save the webhook destination https://www.example.com on user_123.
  ```
</CodeGroup>

#### Authentication

The webhook provider supports basic and bearer authentication. Set `authentication.mode` to `basic` or `bearer` and provide the credentials. The mode defaults to `none`.

```json theme={null}
{
  "mode": "basic",
  "username": "AzureDiamond",
  "password": "hunter2"
}
```

```json theme={null}
{
  "mode": "bearer",
  "token": "ABCDEFG123456"
}
```

Then send to `user_id` and Courier resolves the address.

<CardGroup cols={1}>
  <Card title="Send by user id" icon="user" href="/docs/recipients/overview#send-by-user-id">
    The call in every language, and the rest of the profile object.
  </Card>
</CardGroup>

## Send to a recipient

<Tabs>
  <Tab title="Send to user id">
    Courier reads `webhook` off the saved profile, so preferences apply and the value 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 `webhook`">
    Pass it inline instead and nothing is stored. Swap this `to` object into the call on the other tab.

    <CodeGroup>
      ```javascript Node.js highlight={4-6} theme={null}
      const { requestId } = await courier.send.message({
        message: {
          to: {
            webhook: {
              url: "https://www.example.com",
            },
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40",
        },
      });
      ```

      ```python Python highlight={4-6} theme={null}
      response = client.send.message(
          message={
              "to": {
                  "webhook": {
                      "url": "https://www.example.com",
                  },
              },
              "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          },
      )
      ```

      ```bash cURL highlight={7-9} 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": {
              "webhook": {
                "url": "https://www.example.com"
              }
            },
            "template": "nt_01kx4h2jdafq8bk9aftxak4b40"
          }
        }'
      ```

      ```ruby Ruby highlight={4-6} theme={null}
      response = courier.send_.message(
        message: {
          to: {
            webhook: {
              url: "https://www.example.com"
            }
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40"
        }
      )
      ```

      ```go Go highlight={4-6} theme={null}
      response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
      	Message: courier.SendMessageParamsMessage{
      		To: courier.SendMessageParamsMessageToUnion{
      			OfWebhookRecipient: &shared.WebhookRecipientParam{
      				Webhook: shared.WebhookProfileParam{URL: "https://www.example.com"},
      			},
      		},
      		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
      	},
      })
      ```

      ```java Java highlight={4-6} theme={null}
      client.send().message(SendMessageParams.builder()
          .message(SendMessageParams.Message.builder()
              .to(WebhookRecipient.builder()
                  .webhook(WebhookProfile.builder()
                      .url("https://www.example.com")
                      .build())
                  .build())
              .template("nt_01kx4h2jdafq8bk9aftxak4b40")
              .build())
          .build());
      ```

      ```php PHP highlight={4-6} theme={null}
      $response = $client->send->message(
        message: [
          'to' => [
            'webhook' => [
              'url' => 'https://www.example.com',
            ],
          ],
          'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
        ],
      );
      ```

      ```csharp C# highlight={6-8} theme={null}
      SendMessageParams parameters = new()
      {
          Message = new()
          {
              To = new WebhookRecipient
              {
                  Webhook = new () { Url = "https://www.example.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 '{"webhook": {"url": "https://www.example.com"}}' \
        --message.template nt_01kx4h2jdafq8bk9aftxak4b40
      ```

      ```text MCP theme={null}
      With Courier MCP, send my template to the webhook at https://www.example.com.
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Request payload

The webhook provider posts the data from your send request to the destination.

<CodeGroup>
  ```javascript Node.js theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
        phone_number: "+12025550165",
      },
      data: {
        name: "Sarah Bennett",
        location: "Gravity Falls, OR",
      },
    },
  });
  ```

  ```python Python theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "email": "sarah@acme-corp.com",
              "phone_number": "+12025550165",
          },
          "data": {
              "name": "Sarah Bennett",
              "location": "Gravity Falls, OR",
          },
      },
  )
  ```

  ```bash cURL wrap 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",
        "to": {
          "email": "sarah@acme-corp.com",
          "phone_number": "+12025550165"
        },
        "data": {
          "name": "Sarah Bennett",
          "location": "Gravity Falls, OR"
        }
      }
    }'
  ```

  ```ruby Ruby theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
        phone_number: "+12025550165"
      },
      data: {
        name: "Sarah Bennett",
        location: "Gravity Falls, OR"
      }
    }
  )
  ```

  ```go Go 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"),
  				PhoneNumber: courier.String("+12025550165"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Data: map[string]any{
  			"name": "Sarah Bennett",
  			"location": "Gravity Falls, OR",
  		},
  	},
  })
  ```

  ```java Java theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").phoneNumber("+12025550165").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .data(JsonValue.from(java.util.Map.of(
              "name", "Sarah Bennett",
              "location", "Gravity Falls, OR"
          )))
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'email' => 'sarah@acme-corp.com',
        'phone_number' => '+12025550165',
      ],
      'data' => [
        'name' => 'Sarah Bennett',
        'location' => 'Gravity Falls, OR',
      ],
    ],
  );
  ```

  ```csharp C# theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com", PhoneNumber = "+12025550165" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Data = new Dictionary<string, JsonElement>()
          {
              { "name", JsonSerializer.SerializeToElement("Sarah Bennett") },
              { "location", JsonSerializer.SerializeToElement("Gravity Falls, OR") },
          },
      },
  };

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

  ```bash CLI wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com", "phone_number": "+12025550165"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.data '{"name": "Sarah Bennett", "location": "Gravity Falls, OR"}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template through the webhook provider with this recipient's details.
  ```
</CodeGroup>

## Overrides

<Doc href="/docs/send/overrides#how-overrides-work">How overrides work</Doc> covers the two levels and which one wins.

A provider override changes what Courier sends to the destination. You can override `url`, `method`, `headers`, and `body`. `body` and `headers` are deep-merged, so fields you leave out are still sent. `url` and `method` are replaced outright.

<CodeGroup>
  ```javascript Node.js highlight={8-19} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      to: {
        user_id: "user_123",
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      providers: {
        webhook: {
          override: {
            url: "https://www.example.com",
            method: "PUT",
            headers: {
              "X-Custom-Header": "Hello from Courier",
            },
            body: {
              key: "value",
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-19} theme={null}
  response = client.send.message(
      message={
          "to": {
            "user_id": "user_123",
          },
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "providers": {
              "webhook": {
                  "override": {
                    "url": "https://www.example.com",
                    "method": "PUT",
                    "headers": {
                      "X-Custom-Header": "Hello from Courier",
                    },
                    "body": {
                      "key": "value",
                    },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-22} 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",
          "providers": {
            "webhook": {
              "override": {
                "url": "https://www.example.com",
                "method": "PUT",
                "headers": {
                  "X-Custom-Header": "Hello from Courier"
                },
                "body": {
                  "key": "value"
                }
              }
            }
          }
        }
      }'
  ```

  ```ruby Ruby highlight={8-19} theme={null}
  response = courier.send_.message(
    message: {
      to: {
        user_id: "user_123"
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      providers: {
        "webhook" => {
          override: {
            url: "https://www.example.com",
            method: "PUT",
            headers: {
              "X-Custom-Header" => "Hello from Courier"
            },
            body: {
              key: "value"
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-21} 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"),
  		Providers: shared.MessageProvidersParam{
  			"webhook": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"url": "https://www.example.com",
  					"method": "PUT",
  					"headers": map[string]any{
  						"X-Custom-Header": "Hello from Courier",
  					},
  					"body": map[string]any{
  						"key": "value",
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-7} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().userId("user_123").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("webhook", JsonValue.from(java.util.Map.of(
                  "override", java.util.Map.of("url", "https://www.example.com", "method", "PUT", "headers", java.util.Map.of("X-Custom-Header", "Hello from Courier"), "body", java.util.Map.of("key", "value")))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-19} theme={null}
  $response = $client->send->message(
    message: [
      'to' => [
        'user_id' => 'user_123',
      ],
      'template' => "nt_01kx4h2jdafq8bk9aftxak4b40",
      'providers' => [
        'webhook' => [
          'override' => [
            'url' => 'https://www.example.com',
            'method' => 'PUT',
            'headers' => [
              'X-Custom-Header' => 'Hello from Courier',
            ],
            'body' => [
              'key' => 'value',
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-21} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { UserID = "user_123" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "webhook",
                  new()
                  {
                      Override = new Dictionary<string, JsonElement>()
                      {
                          { "url", JsonSerializer.SerializeToElement("https://www.example.com") },
                          { "method", JsonSerializer.SerializeToElement("PUT") },
                          { "headers", JsonSerializer.SerializeToElement(new { X-Custom-Header = "Hello from Courier" }) },
                          { "body", JsonSerializer.SerializeToElement(new { key = "value" }) },
                      },
                  }
              },
          },
      },
  };

  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.providers '{"webhook": {"override": {"url": "https://www.example.com", "method": "PUT", "headers": {"X-Custom-Header": "Hello from Courier"}, "body": {"key": "value"}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to user_123 over the webhook provider and override the destination URL.
  ```
</CodeGroup>

## Provider details

```text theme={null}
webhook
```

Courier recommends routing to the channel. Naming this key in `routing.channels` instead is supported, and sends through just this provider.

<Card title="Send to a specific provider" icon="bullseye-arrow" href="/docs/send/send-to-a-provider" horizontal arrow="true">
  When that is worth doing, and what you give up: failover, channel priority, and providers you add later.
</Card>
