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

# Automated Messaging

> Append a premium brand offer to the automated messages your platform already sends on WhatsApp, Messenger, Instagram, or SMS.

If your platform automates outbound messages for your clients (WhatsApp, Messenger, Instagram, SMS, or any other text channel), Encore can supply one extra outbound message per conversation: a complimentary, brand-safe offer sent alongside the response your client already sends. The selection call is [`POST /offers/message`](/publishers/offers-api/reference/message); you compose the reply from the returned offer fields and send it through whatever messaging API you already use.

This guide covers only the messaging-channel deltas; the shared flow (selection, claim via `clickUrl`, server-verified activation) lives in [the overview](/publishers/offers-api/overview#the-flow), and the complete worked example is [Rewarded Actions guide](/publishers/offers-api/guides/rewarded-actions).

## When to call

Two triggers, both gated by a **max-ads-per-thread** check on your side:

1. **First message of a new conversation thread.** Always eligible. Call Encore, send the offer message first, then your client's normal automated reply as a follow-up.
2. **First message after a long idle gap** (a re-engagement), but only if you haven't already shown the configured max number of Encore offers in the same thread.

Counting prior offers is simple: every Encore offer link is a branded short link on the **`link.encorekit.com`** host. Scan the thread's message history for outbound links to that host and compare to your per-thread cap (for example 3). Below the cap, call Encore; at the cap, skip.

Never call on mid-thread replies, and skip users who have opted out (recipient-level cooldown is a planned feature).

<Note>
  Sequence matters: send the offer message **before** your client's reply, not after. The offer reads as a brief "while you wait" footer to the conversation rather than a postscript stapled onto the end.
</Note>

## Map the request fields from your webhook

The request carries a `clientId`, a `chatId`, and targeting attributes ([full contract](/publishers/offers-api/reference/message)). On a Meta channel, the identifiers map to values Meta already puts in the inbound webhook payload:

| Encore field             | Where it comes from                                                                                                                                                                                         |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chatId`                 | WhatsApp Cloud API: `entry[].changes[].value.metadata.phone_number_id` or your own thread key. Instagram / Facebook (Messenger Platform): `messaging[].thread.id` if present, else `messaging[].sender.id`. |
| `clientId`               | Integrator-defined: your operator's stable id (restaurant id, account id). Same value across platforms for the same operator.                                                                               |
| `attributes.countryCode` | Your platform's view of the end user's country (account profile, IP lookup).                                                                                                                                |
| `attributes.language`    | The end user's language preference, or the language they're actively chatting in.                                                                                                                           |
| `attributes.platform`    | The end user's device, if known (otherwise pick the most likely surface).                                                                                                                                   |

If `offer` comes back `null`, skip the promo step entirely and send only your client's normal automated reply; that's a normal response, never an error.

## Compose and send the message

You send the offer yourself, as a normal text message, through your existing channel API. Build the text from the offer fields (`title`, `description`, `perk`, `advertiserName`). The only hard requirement: **the branded short `clickUrl` must appear in the text** so the tap attributes correctly.

A simple, effective plain-text template (field contract: [`POST /offers/message` response](/publishers/offers-api/reference/message#response)):

```text theme={null}
Get {perk} by claiming now: {clickUrl} - Unlocked by our partner EncoreKit
```

For example: `Get 6 months free by claiming now: https://link.encorekit.com/aB3xY7q2 - Unlocked by our partner EncoreKit`

<Tip>
  **Append the partner sign-off.** End the message with **`Unlocked by our partner EncoreKit`**. The `clickUrl` points to the `link.encorekit.com` host, one the end user wasn't expecting from the business they were chatting with, so naming the partner keeps them comfortable tapping the link.
</Tip>

<Note>
  `clickUrl` is a plain URL, so it renders and links correctly in any text channel with no interactive template or Graph API body required. If your channel supports media messages, attach `offer.imageUrl` as the image and put your copy in the caption; on text-only channels, omit the image.
</Note>

## Gotchas

* **Call once per inbound message.** Retries are not deduplicated server-side; every call generates a fresh short link and analytics row. De-dupe inbound webhooks on your side before calling ([retry guidance](/publishers/offers-api/reference/message#retry-guidance)).
* **Fail soft.** Treat any non-200 as a signal to skip the promo step and send your client's configured auto-reply on its own. The end-user experience should never degrade because of an Encore outage.
* **`chatId` is the user key on this surface.** It seeds ranking and is the userId on the click-time transaction, so keep it stable per conversation thread.

## Related

* [`POST /offers/message` reference](/publishers/offers-api/reference/message): full request/response contract and status codes.
* [API Reference overview](/publishers/offers-api/overview#choosing-a-selection-mode): the selection-mode decision table.
* [Receive Completion Events](/publishers/offers-api/guides/receive-completion-events): react server-side when a completion is verified.
