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

# Postman collection

> Try every Courier endpoint in Postman with the official collection.

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

Test the Courier API in Postman with no integration code.

The collection is updated with every release, so it always reflects the latest endpoints.

<Card title="Open the Courier collection in Postman" icon="play" color="#FF6C37" href="https://www.postman.com/trycourier/courier-s-api-collections/collection/aiy9mtt/courier" horizontal>
  Fork it into your workspace, then add your API key and send.
</Card>

## Set up

<Steps>
  <Step title="Fork the collection">
    Open the collection above and click **Fork**. Your copy stays linked to the source, so you can pull in updates. Requires a [Postman account](https://www.postman.com/).
  </Step>

  <Step title="Add bearer auth">
    On the forked collection's **Authorization** tab, set **Auth Type** to **Bearer Token** and enter `{{auth_token}}`.
  </Step>

  <Step title="Create an environment">
    In **Environments**, add `Courier Test` with a variable `auth_token`. Paste your <AppLink href="https://app.courier.com/~/test/platform/api-keys">Test API key</AppLink> into **Current value** (not Initial value, which syncs to Postman's cloud). Repeat for Production, then pick an environment.
  </Step>
</Steps>

## Send your first request

With `Courier Test` active, open **Send a Message** (<Endpoint method="POST" path="/send" name="Send a message" href="/docs/api-reference/send/send-a-message" />), add a body, and click **Send**. `template` is the ID or alias of a published <Doc href="/docs/design/templates/overview">template</Doc>. `data` supplies its variables:

<CodeGroup>
  ```javascript Node.js theme={null}
  const { requestId } = await courier.send.message({
    message: {
      to: {
        user_id: "user_123",
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      data: {
        name: "Sarah Bennett",
      },
      routing: {
        method: "single",
        channels: [
          "email",
        ],
      },
    },
  });
  ```

  ```python Python theme={null}
  response = client.send.message(
      message={
          "to": {
              "user_id": "user_123",
          },
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "data": {
              "name": "Sarah Bennett",
          },
          "routing": {
              "method": "single",
              "channels": [
                  "email",
              ],
          },
      },
  )
  ```

  ```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": {
        "to": {
          "user_id": "user_123"
        },
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "data": {
          "name": "Sarah Bennett"
        },
        "routing": {
          "method": "single",
          "channels": [
            "email"
          ]
        }
      }
    }'
  ```

  ```ruby Ruby theme={null}
  response = courier.send_.message(
    message: {
      to: {
        user_id: "user_123"
      },
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      data: {
        name: "Sarah Bennett"
      },
      routing: {
        method: "single",
        channels: [
          "email"
        ]
      }
    }
  )
  ```

  ```go Go 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"),
  		Data: map[string]any{
  			"name": "Sarah Bennett",
  		},
  		Routing: courier.SendMessageParamsMessageRouting{
  			Channels: []shared.MessageRoutingChannelUnionParam{
  				{OfString: courier.String("email")},
  			},
  			Method: "single",
  		},
  	},
  })
  ```

  ```java Java theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().userId("user_123").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .data(JsonValue.from(java.util.Map.of(
              "name", "Sarah Bennett"
          )))
          .routing(SendMessageParams.Message.Routing.builder()
              .addChannel("email")
              .method(SendMessageParams.Message.Routing.Method.SINGLE)
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP theme={null}
  $response = $client->send->message(
    message: [
      'to' => [
        'user_id' => 'user_123',
      ],
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'data' => [
        'name' => 'Sarah Bennett',
      ],
      'routing' => [
        'method' => 'single',
        'channels' => [
          'email',
        ],
      ],
    ],
  );
  ```

  ```csharp C# theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { UserID = "user_123" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Data = new Dictionary<string, JsonElement>()
          {
              { "name", JsonSerializer.SerializeToElement("Sarah Bennett") },
          },
          Routing = new() { Channels = ["email"], Method = Send::Method.Single },
      },
  };

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

  ```bash CLI wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"user_id": "user_123"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.data '{"name": "Sarah Bennett"}' \
    --message.routing '{"method": "single", "channels": ["email"]}'
  ```

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

Courier returns a `requestId` you can track in your <Doc href="/docs/monitor/overview">message logs</Doc>.

<Note>
  Treat your API key like a password. Use [Postman Vault](https://learning.postman.com/docs/use/postman-vault/manage-vault-secrets/) for team keys, and <Doc href="/docs/workspaces/overview#environments-and-api-keys">rotate it</Doc> if it leaks.
</Note>
