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

# SMS providers

> Every SMS provider Courier supports, the phone_number profile field, and per-send 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 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="Twilio" href="/docs/integrations/sms/twilio" icon="https://mintcdn.com/courier-4f1f25dc/rYENcCCTyPPrDtw0/assets/provider-twilio.svg?fit=max&auto=format&n=rYENcCCTyPPrDtw0&q=85&s=fc9ee80ba4c8ae2bb9850adffd0d4416" horizontal width="24" height="24" data-path="assets/provider-twilio.svg" />

  <Card title="Vonage" href="/docs/integrations/sms/vonage" icon="https://mintcdn.com/courier-4f1f25dc/rYENcCCTyPPrDtw0/assets/provider-vonage.svg?fit=max&auto=format&n=rYENcCCTyPPrDtw0&q=85&s=41b627265f8128f0a1e4732ee8fa742e" horizontal width="24" height="24" data-path="assets/provider-vonage.svg" />

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

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

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

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

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

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

  <Card title="Amazon SNS" href="/docs/integrations/sms/aws-sns" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-aws-sns.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=64b6a140d65c06245d57828f233b3789" horizontal width="216" height="216" data-path="assets/provider-aws-sns.webp" />

  <Card title="TextUs" href="/docs/integrations/sms/textus" icon="https://mintcdn.com/courier-4f1f25dc/rYENcCCTyPPrDtw0/assets/provider-textus.svg?fit=max&auto=format&n=rYENcCCTyPPrDtw0&q=85&s=6c68cd8652205811908c06cce8f8d3b2" horizontal width="24" height="24" data-path="assets/provider-textus.svg" />

  <Card title="Africa's Talking" href="/docs/integrations/sms/africas-talking" icon="https://mintcdn.com/courier-4f1f25dc/Ia7FGvhsFU_5CtOa/assets/provider-africas-talking.webp?fit=max&auto=format&n=Ia7FGvhsFU_5CtOa&q=85&s=a84d4e804a9494e68cfbb635b10e653f" horizontal width="216" height="216" data-path="assets/provider-africas-talking.webp" />

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

Amazon SNS also sends <Doc href="/docs/integrations/push/aws-sns">push</Doc>. <Doc href="/docs/integrations/sms/twilio">Twilio</Doc> is the only one here that carries MMS.

## Profile requirements

Every SMS provider addresses the recipient the same way, by phone number, so the profile you send to needs a `phone_number`. 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: {
      phone_number: '+15551234567',
    },
  });
  ```

  ```python Python highlight={4} theme={null}
  profile = client.profiles.create(
      user_id="user_123",
      profile={
          "phone_number": "+15551234567",
      },
  )
  ```

  ```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": {
        "phone_number": "+15551234567"
      }
    }'
  ```

  ```ruby Ruby highlight={4} theme={null}
  profile = courier.profiles.create(
    "user_123",
    profile: {
      phone_number: "+15551234567"
    }
  )
  ```

  ```go Go highlight={6} theme={null}
  profile, err := client.Profiles.New(
  	context.TODO(),
  	"user_123",
  	courier.ProfileNewParams{
  		Profile: map[string]any{
  			"phone_number": "+15551234567",
  		},
  	},
  )
  ```

  ```java Java highlight={4} theme={null}
  ProfileCreateParams params = ProfileCreateParams.builder()
      .userId("user_123")
      .profile(ProfileCreateParams.Profile.builder()
          .putAdditionalProperty("phone_number", JsonValue.from("+15551234567"))
          .build())
      .build();
  ProfileCreateResponse profile = client.profiles().create(params);
  ```

  ```php PHP highlight={2} theme={null}
  $profile = $client->profiles->create('user_123', profile: [
    'phone_number' => '+15551234567',
  ]);
  ```

  ```csharp C# highlight={6} theme={null}
  ProfileCreateParams parameters = new()
  {
      UserID = "user_123",
      Profile = new Dictionary<string, JsonElement>()
      {
          { "phone_number", JsonSerializer.SerializeToElement("+15551234567") },
      },
  };
  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 '{"phone_number":"+15551234567"}'
  ```

  ```text MCP theme={null}
  With Courier MCP, create a profile for user_123 with the phone number +15551234567.
  ```
</CodeGroup>

Store the number in E.164 form, with the country code and a leading `+`. A provider that accepts a local format at its own API does not change what Courier stores, and a number without a country code fails at the provider rather than at the send.

## Send to a recipient

<Tabs>
  <Tab title="Send to user id">
    Courier reads `phone_number` off the saved profile, so preferences apply and the number 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 SMS.
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Send to phone number">
    A one-off to a number 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: {
            phone_number: "+15551234567",
          },
          template: "nt_01kx4h2jdafq8bk9aftxak4b40",
        },
      });
      ```

      ```python Python highlight={4} theme={null}
      response = client.send.message(
          message={
              "to": {
                  "phone_number": "+15551234567",
              },
              "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": {
              "phone_number": "+15551234567"
            },
            "template": "nt_01kx4h2jdafq8bk9aftxak4b40"
          }
        }'
      ```

      ```ruby Ruby highlight={4} theme={null}
      response = courier.send_.message(
        message: {
          to: {
            phone_number: "+15551234567"
          },
          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{
      				PhoneNumber: courier.String("+15551234567"),
      			},
      		},
      		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
      	},
      })
      ```

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

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

      ```csharp C# highlight={5} theme={null}
      SendMessageParams parameters = new()
      {
          Message = new()
          {
              To = new UserRecipient { PhoneNumber = "+15551234567" },
              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 '{"phone_number": "+15551234567"}' \
        --message.template nt_01kx4h2jdafq8bk9aftxak4b40
      ```

      ```text MCP theme={null}
      With Courier MCP, send my template to +15551234567 by SMS.
      ```
    </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. Most SMS providers accept these two in a provider override.

| Field    | Sets                                                                 |
| :------- | :------------------------------------------------------------------- |
| `body`   | The message text, the recipient number, or other request body fields |
| `config` | Credentials or sender numbers, swapped for this one send             |

Each provider page documents its own schema.

<Tip>
  Can't find a provider? Start a chat or email [support@courier.com](mailto:support@courier.com)
</Tip>
