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

# Direct Send best practices

> Send utility content or convert an existing template with Direct Send, then monitor generated templates and content quality.

Direct Send lets eligible businesses send Utility messages by submitting complete content or reusing an existing Utility template. Meta handles template matching and generation for custom content.

This guide covers Utility Direct Send through YCloud. For general message sending, see [Send a WhatsApp message](/en/api-reference/guides/whatsapp-platform/send-whatsapp-message).

## How Direct Send works

Direct Send uses templates behind the scenes. You can submit finished text or interactive content. You can also reference an existing Utility template and ask YCloud to convert its supported components into a Direct Send message.

| Starting point | Request | What YCloud sends |
| - | - | - |
| Complete Utility content | Set `type` to `text` or `interactive` and `category` to `utility`. | Your content as a Direct Send message. |
| Existing Utility template | Set `type` to `template`, supply `template.name`, `template.language`, and all required parameters, then set `useDirectSend: true`. | Converted text, CTA URL, or reply-button content. |

Meta matches your message content to an existing template. If there is no match, Meta removes personally identifiable information, detects the language, and generates a new template in the background for future matching messages.

For example, “Your order A123456 has shipped” and “Your order B789012 has shipped” share the same structure. Later notifications can reuse a matching generated template.

Generated templates retain category, quality, and performance information. This lets you identify which content is performing well or causing delivery problems, even though you did not create the template yourself.

## Supported features and limits

### Eligibility and sending scope

Connect your WABA and business phone number to YCloud. In **Meta WhatsApp Manager → Message templates**, check whether your business is eligible for Direct Send. If access is unavailable for your WABA, use an approved Utility template or contact YCloud to check eligibility.

Utility Direct Send can initiate an expected notification outside the 24-hour customer service window. Obtain the customer's permission and keep the content tied to their request, transaction, account, or qualifying essential information. Promotions and verification codes are outside this Utility workflow.

| Feature | Behavior |
| - | - |
| Message content | Send complete text and supported button content without pre-creating a template. |
| Existing Utility template | Set `useDirectSend: true` to convert supported template components after supplying their parameters. |
| Template creation | Meta matches an existing generated template or generates a new one in the background. |
| Submission | Use queued or synchronous submission through YCloud. |
| Delivery lifetime | Set a custom `ttlSeconds` for time-sensitive notifications. |
| Template management | View generated templates in YCloud. Change future content in your API request. |
| Pricing | The [Utility-message pricing rules](/en/documentation/whatsapp-business-platform/pricing-limits-and-quality/whatsapp-pricing) apply. |

### Message length and buttons

| Content | Limit |
| - | - |
| Body | 1,024 characters |
| Header | 60 characters |
| Footer | 60 characters |
| Button label | 20 characters |
| Reply-button format (`interactive.type: button`) | Up to 3 reply buttons |
| URL-button format (`interactive.type: cta_url`) | 1 URL button |

The sending examples below use text headers. Text messages do not display URL previews. Account limits and [throughput controls](/en/documentation/whatsapp-business-platform/pricing-limits-and-quality/messaging-limits-and-throughput) still apply.

Use text headers for custom `interactive` Direct Send requests. An image header
is available only when you convert a supported template and Meta has enabled
that capability for your WABA.

### Delivery lifetime (TTL)

`ttlSeconds` sets how long a message can remain eligible for delivery. If it cannot be delivered within that period, it is dropped. A delivered message is not deleted when its TTL expires.

| Setting | Utility value |
| - | - |
| Default when omitted | 30 days |
| Minimum custom TTL | 30 seconds |
| Maximum custom TTL | 43,200 seconds (12 hours) |

The default and the permitted custom range differ. For a delivery update that is useful for only 30 minutes, set `ttlSeconds: 1800`; do not leave it at the default.

## Supported message types

The following formats cover text notifications, links, and customer replies through YCloud.

| Type | Request fields | Typical use |
| - | - | - |
| Text | `type: text`, with `text.body` | Confirm an order or report a status change. |
| URL button | `type: interactive`, with `interactive.type: cta_url` | Open a tracking, invoice, or appointment page. |
| Reply buttons | `type: interactive`, with `interactive.type: button` | Ask the customer to confirm or request help in WhatsApp. |

A URL button opens a website. A reply button sends the selected response back to your business, so your application can continue the workflow.

### Handle reply-button responses

Although you send an `interactive` request, Direct Send delivers the content as a template. A customer's reply-button tap therefore uses the template quick-reply format: `type: button`, with `button.payload` and `button.text`.

Relevant fields in a YCloud inbound-message event:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "whatsapp.inbound_message.received",
  "whatsappInboundMessage": {
    "type": "button",
    "button": {
      "payload": "delivery_help_A123456",
      "text": "I need help"
    },
    "context": {
      "id": "ORIGINAL_MESSAGE_WAMID"
    }
  }
}
```

Use `button.payload` to identify the action and `context.id` to correlate the reply with the original message's `wamid`. Do not read this response from `interactive.button_reply`, which is the ordinary free-form reply-button format.

## Send through YCloud

Prepare a server-side API key and the sender and recipient numbers in E.164 format. You need the WABA ID only if you choose to submit message samples.

### 1. Choose the submission mode

| Endpoint | Behavior |
| - | - |
| `POST /v2/whatsapp/messages` | Queues the message and submits it asynchronously. |
| `POST /v2/whatsapp/messages/sendDirectly` | Submits the message synchronously to the WhatsApp Business API. |

The `sendDirectly` endpoint name describes submission timing. To use Direct Send, your WABA must have access and your request must include the Direct Send fields below.

### 2. Build the request

| Field | Value or purpose |
| - | - |
| `from`, `to` | Sender and recipient numbers in E.164 format. |
| `type` | `text` or `interactive`. |
| `text` or `interactive` | The complete message content. |
| `category` | `utility`. |
| `useDirectSend` | Set to `true` when converting an existing template. It is optional for custom content with `category: "utility"`. |
| `ttlSeconds` | Optional delivery lifetime in seconds. |
| `externalId` | Optional business reference for reconciliation; does not guarantee idempotency. |

These examples submit complete content synchronously. You can also use a queued send or [convert an existing Utility template](#convert-an-existing-utility-template). Replace the phone number placeholders and example URL before sending.

<Tabs>
  <Tab title="Text">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl --request POST \
      'https://api.ycloud.com/v2/whatsapp/messages/sendDirectly' \
      --header 'Content-Type: application/json' \
      --header "X-API-Key: ${YCLOUD_API_KEY}" \
      --data '{
        "from": "BUSINESS_PHONE_NUMBER",
        "to": "CUSTOMER_PHONE_NUMBER",
        "type": "text",
        "text": {
          "body": "Your order A123456 has shipped. Your estimated delivery date is September 15."
        },
        "category": "utility",
        "useDirectSend": true,
        "ttlSeconds": 1800,
        "externalId": "order-A123456-shipped-text"
      }'
    ```
  </Tab>

  <Tab title="URL button">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl --request POST \
      'https://api.ycloud.com/v2/whatsapp/messages/sendDirectly' \
      --header 'Content-Type: application/json' \
      --header "X-API-Key: ${YCLOUD_API_KEY}" \
      --data '{
        "from": "BUSINESS_PHONE_NUMBER",
        "to": "CUSTOMER_PHONE_NUMBER",
        "type": "interactive",
        "interactive": {
          "type": "cta_url",
          "header": {
            "type": "text",
            "text": "Order shipped"
          },
          "body": {
            "text": "Your order A123456 has shipped. View its latest delivery status below."
          },
          "footer": {
            "text": "Order A123456"
          },
          "action": {
            "name": "cta_url",
            "parameters": {
              "display_text": "Track order",
              "url": "https://example.com/orders/A123456"
            }
          }
        },
        "category": "utility",
        "useDirectSend": true,
        "ttlSeconds": 1800,
        "externalId": "order-A123456-shipped-url"
      }'
    ```
  </Tab>

  <Tab title="Reply buttons">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl --request POST \
      'https://api.ycloud.com/v2/whatsapp/messages/sendDirectly' \
      --header 'Content-Type: application/json' \
      --header "X-API-Key: ${YCLOUD_API_KEY}" \
      --data '{
        "from": "BUSINESS_PHONE_NUMBER",
        "to": "CUSTOMER_PHONE_NUMBER",
        "type": "interactive",
        "interactive": {
          "type": "button",
          "header": {
            "type": "text",
            "text": "Delivery update"
          },
          "body": {
            "text": "Your order A123456 is scheduled for delivery on September 15. Do you need help with this delivery?"
          },
          "footer": {
            "text": "Order A123456"
          },
          "action": {
            "buttons": [
              {
                "type": "reply",
                "reply": {
                  "id": "delivery_help_A123456",
                  "title": "I need help"
                }
              },
              {
                "type": "reply",
                "reply": {
                  "id": "delivery_ok_A123456",
                  "title": "No help needed"
                }
              }
            ]
          }
        },
        "category": "utility",
        "useDirectSend": true,
        "ttlSeconds": 1800,
        "externalId": "order-A123456-delivery-reply"
      }'
    ```
  </Tab>
</Tabs>

### 3. Track delivery

Save the returned message `id`, your `externalId`, and the `wamid` when available. Receive updates through `whatsapp.message.updated`, or query `GET /v2/whatsapp/messages/{id}`.

After `accepted`, the sending result is `sent` or `failed`. Successful messages can progress to `delivered` and `read`. An accepted request is not a delivery receipt.

For synchronous submission errors, inspect `error.whatsappApiError` when present. For queued messages, inspect subsequent status updates. If a request times out, reconcile the original message before retrying.

## Convert an existing Utility template

Use an existing Utility template in your WABA. Set `type: "template"` and
`useDirectSend: true`. Supply the template name, language, and every required
parameter. YCloud replaces the variables and converts supported components
into text or interactive content with `category: "utility"`. The template must
meet the conversion limits below. YCloud does not require `APPROVED` status for
this conversion.

If the template has an image header, confirm that Meta has enabled image-header
Direct Send for your WABA before using it. This requires separate Meta access.

For this example, use an existing utility template named `order_update` with
the body `Your order {{1}} has been updated.` and no header, footer, or buttons:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/messages/sendDirectly \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "to": "+16315552222",
    "type": "template",
    "template": {
      "name": "order_update",
      "language": {
        "code": "en_US",
        "policy": "deterministic"
      },
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "A123456"
            }
          ]
        }
      ]
    },
    "useDirectSend": true,
    "ttlSeconds": 600
  }'
```

The response contains the converted content. For this example, `type` becomes
`text`, and the template variable becomes the supplied order ID:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "MESSAGE_ID",
  "wabaId": "WHATSAPP_BUSINESS_ACCOUNT_ID",
  "from": "+16315551111",
  "to": "+16315552222",
  "type": "text",
  "text": {
    "body": "Your order A123456 has been updated."
  },
  "status": "accepted",
  "category": "utility",
  "ttlSeconds": 600,
  "createTime": "2026-09-17T08:00:00.000Z"
}
```

An `accepted` response does not confirm delivery. Store the message `id` and
track `whatsapp.message.updated` events. Review the conversion limits below
before reusing a template with headers or buttons.

If YCloud returns `WHATSAPP_DIRECT_SEND_UNSUPPORTED_COMPONENT`, check the
template's header, buttons, and unresolved variables against the limits below.
If the WABA cannot use Direct Send, check its eligibility before retrying or
send an approved Utility template through the ordinary template workflow.

### Set the message lifetime

For template conversion, a request `ttlSeconds` value takes precedence over the
template TTL. If you omit it, YCloud inherits a positive template TTL up to
`43200` seconds. A template TTL below `30` seconds fails validation, so override
it with a valid request value. YCloud does not inherit template TTL values above
`43200`. If neither value applies, Meta uses its default TTL.

## Name a Utility Direct Send template

`template.name` identifies an existing template in the conversion request above.
`templateName` serves a different purpose: set it when you want Meta to reuse a recognizable name for a Utility
Direct Send template. The field is optional and does not enable Direct Send by
itself. You must also set `useDirectSend: true` or `category: "utility"`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "from": "+16315551111",
  "to": "+16315552222",
  "type": "text",
  "text": {
    "body": "Your order 12131123 has been placed at the door."
  },
  "category": "utility",
  "templateName": "order_update_ds"
}
```

The name is case-sensitive. Use 1 to 512 lowercase letters, digits, or
underscores. YCloud rejects uppercase letters, spaces, and other characters.

The same WABA cannot use a name that belongs to an existing regular WhatsApp
message template, including a rejected template. YCloud checks this before a
synchronous provider call or before accepting a queued message. Deleted templates
do not reserve the name, and you can reuse a name that Meta previously generated
for Direct Send.

If a regular template already uses the name, the API returns HTTP `400` with
target `templateName` and message `A template with the same name already
exists.` Choose another name before retrying.

`templateName` is not supported for Authentication Direct Send. For a queued
Utility Direct Send message, YCloud returns the validation error without returning
a message ID and otherwise forwards the name to Meta without storing it on the
message record. YCloud ignores the field for messages that do not use Direct Send.

## Template conversion and language limits

Utility Direct Send supports text, CTA URL buttons, and reply buttons. These
limits also apply when YCloud converts a utility template:

| Content or component | Limit and conversion behavior |
| - | - |
| Body | Maximum 1,024 characters. Supply every template variable. Direct Send does not display URL previews; omit `preview_url`. |
| Text header | Maximum 60 characters. With buttons, it becomes the interactive text header. Without buttons, YCloud joins the header and body into a text message. |
| Image header | Requires a CTA URL or reply button. Supply an `image.link` or `image.id` parameter. An image header without buttons cannot be converted. |
| Footer | Maximum 60 characters. YCloud includes it in interactive messages and omits it when converting a template without buttons to text. |
| CTA URL button | Maximum one. YCloud converts a template `URL` button to `interactive.cta_url`. |
| Reply buttons | Maximum three. YCloud converts template `QUICK_REPLY` buttons to `interactive.button`. |
| Button label | Maximum 20 characters. |

Do not combine CTA URL and quick reply buttons. Other header and button types
cannot be converted. Unsupported components or unresolved template variables
return HTTP `400` with code `WHATSAPP_DIRECT_SEND_UNSUPPORTED_COMPONENT`.

### Language support

Direct Send supports [WhatsApp template languages](/en/api-reference/guides/whatsapp-platform/supported-whatsapp-template-languages)
except:

| Language | Code |
| - | - |
| Chinese, Simplified | `zh_CN` |
| Chinese, Hong Kong | `zh_HK` |
| Chinese, Taiwan | `zh_TW` |
| Japanese | `ja` |
| Korean | `ko` |
| Thai | `th` |
| Lao | `lo` |

Use a supported language for Direct Send workflows.

## View templates generated by Direct Send in YCloud

1. Open **WhatsApp Manager → Templates** in the YCloud console.
2. Select the WABA used to send the message.
3. Set **Creator → Auto generated**. Use **Category → Utility** to narrow the list to Utility templates.
4. Check the template's name, category, language, status, and last updated time. Click its name or **Insights** to open its preview and performance details.

<Frame caption="Set Creator to Auto generated. This test WABA has no matching generated templates.">
  <img src="https://mintcdn.com/lchnan/TsMGu8UTNQaUw-Rc/product-assets/english-help-demo-2026-09-23/direct-send-template-filter.png?fit=max&auto=format&n=TsMGu8UTNQaUw-Rc&q=85&s=ec1549dab1e78e079cddf2e78deab1dd" alt="Creator filter set to Auto generated in Templates" width="2530" height="315" data-path="product-assets/english-help-demo-2026-09-23/direct-send-template-filter.png" />
</Frame>

Content-generated template names commonly start with `auto_generated`. Use the **Auto generated** filter to identify them rather than relying only on their names.

The insight page shows the message preview and available delivery, failure, read, and interaction statistics for the selected period. Use the template's status and content together when investigating a warning or a paused template.

Generated templates cannot be edited or deleted manually. To change the notification, change the content in your send request; Meta then matches or generates a template for that content.

## Integrity and content guidelines

### Keep Utility content specific and non-promotional

Utility messages should follow an expected customer action or provide qualifying essential information. State the relevant order, appointment, account, or transaction clearly.

| Appropriate Utility content | Content to keep out of this workflow |
| - | - |
| “Your order A123456 has shipped.” | “Your order has shipped. Buy again today for 20% off.” |
| “Your appointment is confirmed for September 15 at 10:00.” | “Book another appointment now and receive a gift.” |
| “Your refund for order A123456 has been processed.” | A general promotion or an identity verification code. |

Changing `category` to `utility` does not change the meaning of the content. Meta continues to assess generated templates after sending. You can check a materially different use case with a message sample before sending.

### Check a new use case with message samples (optional)

`POST /v2/whatsapp/messages/{wabaId}/messageSamples` submits one example to Meta and returns the category Meta detects. It does not send a message to a customer. This check is optional; you do not need to call it for every message or before using Direct Send. For a new Utility use case, we recommend checking three or four representative samples, one per request.

Replace `WABA_ID` with your WhatsApp Business Account ID and set `YCLOUD_API_KEY` in your environment. Use fictional customer details in the sample:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  'https://api.ycloud.com/v2/whatsapp/messages/WABA_ID/messageSamples' \
  --header 'Content-Type: application/json' \
  --header "X-API-Key: ${YCLOUD_API_KEY}" \
  --data '{
    "type": "text",
    "text": {
      "body": "Your order A123456 has shipped. Your estimated delivery date is September 15."
    }
  }'
```

Example response:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "success": true,
  "category": "UTILITY"
}
```

Check `category` before using the content in a Utility Direct Send request. If Meta detects `MARKETING` or `AUTHENTICATION`, revise the content or use the appropriate messaging workflow. For a button sample, submit the `type` and `interactive` fields from a sending example above; omit recipient and sending fields.

### Distinguish a paused template from an account restriction

A template can be paused because of low quality. Messages that match it, or are very similar, can then fail with Meta error `132015`. Find the affected template in YCloud, inspect its content and status, and address the cause before resuming that notification.

Repeated category misuse can restrict Direct Send for the entire WABA:

| Stage | Effect |
| - | - |
| Warning | Meta identifies the misuse so you can correct it or request a review. |
| Rate limit | The WABA can send up to a temporary cap. Further Utility sends can return `131064`. |
| Seven-day restriction | Direct Send messaging is blocked for seven days. |
| Thirty-day restriction | Continued misuse results in an extended restriction. |
| Revocation | Direct Send access is permanently removed. |

Follow the account notice for the active restriction and expiry. A successful review of one template does not automatically lift an account-level restriction.

### Receive YCloud notifications

| Event | What to use it for |
| - | - |
| `whatsapp.message.updated` | Track delivery and inspect message failures. |
| `whatsapp.template.correct_category_detection` | Learn when Meta detects a different category for a Utility Direct Send template. |
| `whatsapp.business_account.updated` | Track Direct Send warnings, restrictions, and recovery. |

Subscribe to `whatsapp.template.correct_category_detection` through your [webhook endpoint](/en/api-reference/guides/api-fundamentals/configure-webhooks) if you want category-detection notifications. It is not a response to `messageSamples`, and it does not fire for every message. In the event's `whatsappTemplate`, compare `previousCategory` with `category`. For example, `previousCategory: "UTILITY"` and `category: "MARKETING"` means Meta identified marketing content in a Utility Direct Send template. Review the content before sending similar messages again. Use `whatsapp.message.updated` to track delivery separately.

Relevant fields from a YCloud account-restriction event:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "EVENT_ID",
  "type": "whatsapp.business_account.updated",
  "apiVersion": "v2",
  "whatsappBusinessAccount": {
    "id": "WABA_ID",
    "updateEvent": "ACCOUNT_RESTRICTION",
    "violationType": "DIRECT_SEND_UTILITY_CATEGORY_ABUSE_STRIKE_1",
    "restrictions": [
      {
        "restrictionType": "RESTRICTED_DIRECT_SEND_UTILITY_TEMPLATES",
        "expiration": "2026-09-17T10:00:00.000Z"
      }
    ]
  }
}
```

Use the WABA ID to pause the affected workflow. Read `violationType` for the reason and `restrictions[].expiration` for its expiry, when supplied.

### Request a review of a category decision

If you believe the content was incorrectly flagged, open **Meta Business Support Home → WhatsApp account → Direct Send template updates → Available for review**. Select the affected templates and choose **Request review**.

Submit the request within 60 days of the notification. Each flagged template can be reviewed once. Track the result as **In review**, **Reversed**, or **Unchanged**. If the review option is unavailable, contact YCloud with the WABA ID, template name or ID, language, and notification details.

## Direct Send FAQ

<AccordionGroup>
  <Accordion title="Do I need a template name before sending?">
    No for custom content. Supply the complete message and let Meta match or generate a template. To convert an existing Utility template, supply its `template.name` and set `useDirectSend: true`. The optional `templateName` field names a Utility Direct Send template; it does not select an existing template.
  </Accordion>

  <Accordion title="Why does Direct Send still generate templates?">
    Templates support category and quality checks, performance reporting, and troubleshooting. Direct Send removes the need to create them manually, not the template-based processing behind the message.
  </Accordion>

  <Accordion title="Can I send outside the 24-hour customer service window?">
    Yes, for eligible Utility Direct Send notifications. Your WABA must have access, the customer must expect the message, and the content must meet Utility requirements. Ordinary free-form service messages still require an open service window.
  </Accordion>

  <Accordion title="Why can a message succeed before its generated template appears?">
    Template generation and synchronization are asynchronous and can finish after the message is sent. Once complete, select the correct WABA and use the **Auto generated** filter.
  </Accordion>

  <Accordion title="How are unused generated templates cleaned up?">
    Meta deletes generated templates that have never been used for sending after 24 hours. Previously used templates can be archived after a period of inactivity. You do not need to delete them manually.
  </Accordion>

  <Accordion title="Does setting utility guarantee that Meta will accept the category?">
    No. Meta assesses the actual content. Remove promotional wording from Utility notifications, and use the review process if a genuine Utility message is incorrectly flagged.
  </Accordion>

  <Accordion title="How is Direct Send billed?">
    Utility messages follow the same Utility-message pricing rules as manually created Utility templates. See [WhatsApp pricing](/en/documentation/whatsapp-business-platform/pricing-limits-and-quality/whatsapp-pricing).
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.