> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notvis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send Email

> Send a transactional email to one or more recipients.

<Note>
  Also available at `POST /v1/emails/send` for backward compatibility.
</Note>

## Request Headers

<ParamField header="Authorization" type="string" required>
  Bearer token. Format: `Bearer nc_live_your_api_key`
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Unique key to prevent duplicate sends. See [Idempotency](/idempotency).
</ParamField>

## Request Body

<ParamField body="from" type="object" required>
  The sender's email address.

  <Expandable title="properties">
    <ParamField body="email" type="string" required>
      Sender email address. Must be from a verified domain.
    </ParamField>

    <ParamField body="name" type="string">
      Sender display name.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="to" type="array" required>
  List of recipients. Minimum 1, maximum 50.

  <Expandable title="properties">
    <ParamField body="email" type="string" required>
      Recipient email address.
    </ParamField>

    <ParamField body="name" type="string">
      Recipient display name.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="cc" type="array">
  CC recipients. Maximum 20.

  <Expandable title="properties">
    <ParamField body="email" type="string" required>CC email address.</ParamField>
    <ParamField body="name" type="string">CC display name.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="bcc" type="array">
  BCC recipients. Maximum 20.

  <Expandable title="properties">
    <ParamField body="email" type="string" required>BCC email address.</ParamField>
    <ParamField body="name" type="string">BCC display name.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="subject" type="string" required>
  Email subject line. Maximum 998 characters.
</ParamField>

<ParamField body="body_html" type="string">
  HTML content of the email. At least one of `body_html` or `body_text` is required.
</ParamField>

<ParamField body="body_text" type="string">
  Plain text content of the email. At least one of `body_html` or `body_text` is required.
</ParamField>

<ParamField body="reply_to" type="string">
  Reply-to email address. Must be a valid email if provided.
</ParamField>

<ParamField body="headers" type="object">
  Custom email headers as key-value pairs.
</ParamField>

<ParamField body="callback_url" type="string">
  HTTPS URL to receive delivery status webhooks for this email. Must start with `https://`.
</ParamField>

<ParamField body="schedule_at" type="string">
  ISO 8601 timestamp to schedule the email for future delivery. Must be in the future, maximum 7 days ahead.
</ParamField>

<ParamField body="tags" type="string[]">
  Tags for categorization. Maximum 10 tags.
</ParamField>

<ParamField body="metadata" type="object">
  Custom metadata as key-value pairs. Useful for tracking and webhooks.
</ParamField>

<Note>
  Total recipients across `to`, `cc`, and `bcc` cannot exceed 50.
</Note>

## Response

<ResponseField name="message_id" type="string">
  Unique identifier for the queued email.
</ResponseField>

<ResponseField name="status" type="string">
  `"queued"` for immediate sends, `"scheduled"` for future sends.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of when the message was created.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.notvis.com/v1/emails/messages \
    -H "Authorization: Bearer nc_live_your_api_key" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "from": {
        "email": "hello@yourdomain.com",
        "name": "Your App"
      },
      "to": [
        { "email": "user@example.com", "name": "John Doe" }
      ],
      "subject": "Welcome to Our App",
      "body_html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
      "body_text": "Welcome! Thanks for signing up.",
      "callback_url": "https://example.com/webhooks/email",
      "tags": ["welcome", "onboarding"],
      "metadata": { "user_id": "usr_123" }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.notvis.com/v1/emails/messages', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer nc_live_your_api_key',
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID(),
    },
    body: JSON.stringify({
      from: { email: 'hello@yourdomain.com', name: 'Your App' },
      to: [{ email: 'user@example.com', name: 'John Doe' }],
      subject: 'Welcome to Our App',
      body_html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
    }),
  });

  const data = await response.json();
  console.log(data.message_id);
  ```

  ```python Python theme={null}
  import requests
  import uuid

  response = requests.post(
      'https://api.notvis.com/v1/emails/messages',
      headers={
          'Authorization': 'Bearer nc_live_your_api_key',
          'Idempotency-Key': str(uuid.uuid4()),
      },
      json={
          'from': {'email': 'hello@yourdomain.com', 'name': 'Your App'},
          'to': [{'email': 'user@example.com', 'name': 'John Doe'}],
          'subject': 'Welcome to Our App',
          'body_html': '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
      },
  )

  print(response.json()['message_id'])
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "net/http"

      "github.com/google/uuid"
  )

  func main() {
      payload := map[string]interface{}{
          "from":      map[string]string{"email": "hello@yourdomain.com", "name": "Your App"},
          "to":        []map[string]string{{"email": "user@example.com", "name": "John Doe"}},
          "subject":   "Welcome to Our App",
          "body_html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
      }

      body, _ := json.Marshal(payload)
      req, _ := http.NewRequest("POST", "https://api.notvis.com/v1/emails/messages", bytes.NewBuffer(body))
      req.Header.Set("Authorization", "Bearer nc_live_your_api_key")
      req.Header.Set("Content-Type", "application/json")
      req.Header.Set("Idempotency-Key", uuid.NewString())

      resp, _ := http.DefaultClient.Do(req)
      defer resp.Body.Close()
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 202 Accepted theme={null}
  {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "queued",
    "created_at": "2026-07-12T10:00:00Z"
  }
  ```

  ```json 202 Scheduled theme={null}
  {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "scheduled",
    "created_at": "2026-07-12T10:00:00Z"
  }
  ```

  ```json 400 Validation Error theme={null}
  {
    "code": 400,
    "message": "validation failed",
    "details": {
      "from.email": "required",
      "subject": "required"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "code": 401,
    "message": "invalid or missing API key"
  }
  ```
</ResponseExample>
