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

# Choose a Sending Strategy

> Courier offers three ways to send notifications, from a single API call to fully managed workflows. Start simple, add complexity only when you need it.

Courier is designed so that most notifications stay simple. A single API call handles rendering, routing, preferences, and delivery across every channel. You only add complexity when your product requires it.

There are three levels of sending in Courier. Each one builds on the last, and you can mix and match across your product.

## Level 1: Inline Send

Send a notification with content defined directly in your API call. No templates, no workflows; just one request.

This is ideal for transactional messages where the content is generated by your app: password resets, verification codes, order confirmations, alert payloads.

<CodeGroup>
  ```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": { "email": "user@example.com" },
        "content": {
          "title": "Your verification code",
          "body": "Your code is {{code}}. It expires in 10 minutes."
        },
        "data": { "code": "847291" },
        "routing": { "method": "single", "channels": ["email"] }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  await courier.send({
    message: {
      to: { email: "user@example.com" },
      content: {
        title: "Your verification code",
        body: "Your code is {{code}}. It expires in 10 minutes."
      },
      data: { code: "847291" },
      routing: { method: "single", channels: ["email"] }
    }
  });
  ```

  ```python Python theme={null}
  client.send(
    message={
      "to": {"email": "user@example.com"},
      "content": {
        "title": "Your verification code",
        "body": "Your code is {{code}}. It expires in 10 minutes."
      },
      "data": {"code": "847291"},
      "routing": {"method": "single", "channels": ["email"]}
    }
  )
  ```
</CodeGroup>

**Use this when**: content is dynamic and code-driven, you're sending simple transactional messages, or you want the fastest possible integration.

## Level 2: Templates + Send API

Separate content from code by referencing a saved template. Your team designs and updates notifications in Courier's visual editor; your code just triggers the send with data.

This is ideal when non-engineers need to edit copy, when you want consistent branding across channels, or when the same notification is sent from multiple places in your codebase.

<CodeGroup>
  ```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": {
        "template": "order-confirmation",
        "to": { "user_id": "user_123" },
        "data": {
          "order_id": "ORD-7891",
          "total": "$49.99",
          "items": ["Widget Pro", "Cable Kit"]
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  await courier.send({
    message: {
      template: "order-confirmation",
      to: { user_id: "user_123" },
      data: {
        order_id: "ORD-7891",
        total: "$49.99",
        items: ["Widget Pro", "Cable Kit"]
      }
    }
  });
  ```

  ```python Python theme={null}
  client.send(
    message={
      "template": "order-confirmation",
      "to": {"user_id": "user_123"},
      "data": {
        "order_id": "ORD-7891",
        "total": "$49.99",
        "items": ["Widget Pro", "Cable Kit"]
      }
    }
  )
  ```
</CodeGroup>

**Use this when**: content is managed by PMs, designers, or ops; you want to update messaging without deploying code; or you send the same notification type from multiple services.

<Tip>
  Templates handle routing, channel-specific content, and localization in one place. Your send call stays the same regardless of how many channels or languages you support.
</Tip>

## Level 3: Automations

When a notification involves timing, sequencing, or conditional logic, use [Automations](/platform/automations/automations-overview). Automations are multi-step workflows that run on Courier's infrastructure, handling delays, batching, digests, branching, and escalation for you.

This is ideal for onboarding sequences, digest summaries, reminder chains, escalation flows, and any notification that depends on user behavior or elapsed time.

```json theme={null}
// Invoke an automation template via API
{
  "automation_template_id": "onboarding-sequence",
  "recipient": "user_123",
  "data": {
    "plan": "pro",
    "signup_date": "2026-02-10"
  }
}
```

An automation can include any combination of:

* **Delays** to pause between steps (wait 24 hours, wait until business hours)
* **Batching** to group related events into a single notification
* **Digests** to accumulate activity and deliver periodic summaries
* **Conditional logic** to branch based on user data, delivery status, or custom expressions
* **Cancellation** to abort a running workflow when conditions change

**Use this when**: notifications depend on timing or user behavior, you need to batch or digest events, you want multi-step sequences, or you need conditional escalation.

## Choosing the Right Level

|                           | Inline Send                | Templates                   | Automations                                 |
| ------------------------- | -------------------------- | --------------------------- | ------------------------------------------- |
| **Content ownership**     | Engineers                  | Anyone on the team          | Anyone on the team                          |
| **Channels**              | All                        | All                         | All                                         |
| **Routing & preferences** | Automatic                  | Automatic                   | Automatic                                   |
| **Timing control**        | Delays only                | Delays only                 | Full (delays, schedules, batching, digests) |
| **Conditional logic**     | In your code               | In your code                | Built-in (if/switch/branch)                 |
| **Multi-step sequences**  | Not supported              | Not supported               | Built-in                                    |
| **Best for**              | Transactional, code-driven | Team-managed, multi-channel | Complex workflows, sequences, digests       |

You can use all three levels across different parts of your product. A password reset can be an inline send while an onboarding flow uses automations; they share the same users, preferences, and delivery infrastructure.

## Related Resources

<CardGroup cols={2}>
  <Card title="Send a Message" href="/platform/sending/send-message" icon="paper-plane">
    Full Send API reference with examples
  </Card>

  <Card title="Template Designer" href="/platform/content/template-designer/template-designer-overview" icon="pen-ruler">
    Design and manage notification templates
  </Card>

  <Card title="Automations Overview" href="/platform/automations/automations-overview" icon="arrow-progress">
    Build multi-step notification workflows
  </Card>

  <Card title="How Sending Works" href="/platform/sending/sending-overview" icon="route">
    Routing, preferences, and delivery pipeline
  </Card>
</CardGroup>
