> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/growth/smart-message.md).

# Smart sending

like payment completion and shipping notifications **Functional messages required for using the service**is used when sending directly from a partner company's server. This can effectively achieve goals such as improving retention and increasing service usage.

Console [Smart delivery setup guide](https://developers-apps-in-toss.toss.im/guide/marketing/smart-message).

***

### Prerequisites

#### Console setup is required

You must first complete the steps below before calling the API.

1. Create a functional campaign in the console and get the template code (`templateSetCode`).
2. If the message requires a notification consent form, create the consent form first before creating the campaign, and link it to the functional campaign.
3. You must get copy review approval. Before approval, you cannot even send test messages.

Please refer to the Smart Delivery introduction document for setup instructions.

<details>

<summary>Check whether a notification consent form is required</summary>

Before sending a message **Whether a notification consent form is required**depends on the nature of the message.

**Cases where you can send immediately without a consent form**

Information essential for service use can be sent without user consent.

* Payment completed, shipping started, shipping completed, refund completed
* Information change notice, terms change notice

**Cases where a consent form is required**

In situations where a user chooses to receive a specific notification, you must always [Request a notification consent form](#_4-알림-동의문-요청하기-requestnotificationagreement)and obtain consent first.

* Request restock notification
* Request event start notification
* Request price change notification
* Request reservation opening notification

</details>

#### Identify the target users to send to

The Smart Delivery API identifies the sending target in one of the two ways below. Do not pass both values at once; choose only one.

| Category  | Issuance method                                                                                                             |
| --------- | --------------------------------------------------------------------------------------------------------------------------- |
| `userKey` | [Toss login](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login)as.                     |
| `anonKey` | [User identification key issuance](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)as. |

Please choose according to your purpose.

* If you have already integrated Toss Login, or want to manage it together with member information such as name and email, `userKey`.
* If you want to identify only the user lightly without login integration, `anonKey`.

The delivery location differs by API.

* Test messages, messages: in the request header `x-toss-user-key` or `x-anon-key`pass it as.
* Bulk messages: request body `contextList` in the item `userKey` or `anonKey`pass it as.

`x-anon-key`If you want to check in advance whether the (hash) is a valid value, [Please use the Identify Key Validation](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key#식별키-검증하기) API.

***

### Basic information

| Item                  | Value                              |
| --------------------- | ---------------------------------- |
| Base URL              | `https://apps-in-toss-api.toss.im` |
| Server authentication | mTLS (client certificate)          |
| Content-Type          | `application/json`                 |

{% hint style="info" %}
**mTLS certificate is required for server-to-server communication**

The Smart Delivery API is server-to-server communication from the partner server to the Apps in Toss server. For security, set up an mTLS certificate on the server before calling it. For how to issue a certificate, see [mTLS certificate issuance method](https://developers-apps-in-toss.toss.im/documentation/integration/getting-started)please refer to
{% endhint %}

***

### 1. Send a test message

After creating a functional campaign in the console and receiving copy review approval, use this to check whether the bundle works properly before actual deployment.

* Content-Type: `application/json`
* Method: `POST`
* URL: `/api-partner/v1/apps-in-toss/messenger/send-test-message`

**Request headers**

Use one of the two headers below to identify the sending target. Do not pass both headers at the same time.

| Name              | Type   | Required   | Description                                                                                                                                                                                                                                                                     |
| ----------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-toss-user-key` | string | Choose one | [Toss login](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login)obtained from `userKey`It is. [You can obtain it through](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)Get user info |
| `x-anon-key`      | string | Choose one | [User identification key issuance](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)obtained from `hash` value.                                                                                                                             |

**Request body**

| Name            | Type   | Required | Description                                                                                                                               |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| templateSetCode | string | Y        | This is the message template code to use. Enter the template code registered in the console.                                              |
| deploymentId    | string | Y        | This is the bundle identifier used for testing. It is in UUID format and can be found in the bundle uploaded under Console → App Release. |
| context         | object | Y        | These are the template variable values. Enter values to be included in the template, such as user name and verification code.             |

```json
{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "deploymentId": "019abfe8-fd68-7021-9cdc-30d6053cc009",
  "context": {
    "userName": "Hong Gil-dong",
    "otp": "123456"
  }
}
```

**Success response**

| Name                | Type    | Description                                                       |
| ------------------- | ------- | ----------------------------------------------------------------- |
| msgCount            | integer | Total number of messages sent.                                    |
| sentPushCount       | integer | Number of messages sent via Push.                                 |
| sentInboxCount      | integer | Number of messages sent to Inbox.                                 |
| sentSmsCount        | integer | Number of messages sent by SMS.                                   |
| sentAlimtalkCount   | integer | Number of messages sent via Alimtalk.                             |
| sentFriendtalkCount | integer | Number of messages sent via Friend Talk.                          |
| detail              | object  | Detailed list by channel of messages that were successfully sent. |
| fail                | object  | Detailed list by channel of messages that failed to send.         |

`detail` / `fail` Sub-common fields:

| Name           | Type  | Description                                       |
| -------------- | ----- | ------------------------------------------------- |
| sentPush       | array | List of send results for the Push channel.        |
| sentInbox      | array | List of send results for the Inbox channel.       |
| sentSms        | array | List of send results for the SMS channel.         |
| sentAlimtalk   | array | List of send results for the Alimtalk channel.    |
| sentFriendtalk | array | List of send results for the Friend Talk channel. |

Item fields in each channel array:

| Name              | Type   | Description                                                 |
| ----------------- | ------ | ----------------------------------------------------------- |
| contentId         | string | Unique ID of the sent message.                              |
| reachedFailReason | string | If message delivery failed, the failure reason is included. |

```json
{
  "resultType": "SUCCESS",
  "success": {
    "msgCount": 1,
    "sentPushCount": 1,
    "sentInboxCount": 0,
    "sentSmsCount": 0,
    "sentAlimtalkCount": 0,
    "sentFriendtalkCount": 0,
    "detail": {
      "sentPush": [{ "contentId": "MSG_ABC123" }],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    },
    "fail": {
      "sentPush": [],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    }
  }
}
```

**Failure response**

```json
{
  "resultType": "FAIL",
  "error": {
    "errorCode": "INVALID_PARAMETER",
    "reason": "The request failed."
  }
}
```

| HTTP status code | Description                                                  |
| ---------------- | ------------------------------------------------------------ |
| 400              | The request was invalid or required information was missing. |
| 401              | The user is not authenticated.                               |
| 403              | You do not have permission to send messages.                 |

***

### 2. Send a message

Send a functional message to a specific user. After copy review approval, the partner server can call it directly at the desired time.

* Content-Type: `application/json`
* Method: `POST`
* URL: `/api-partner/v1/apps-in-toss/messenger/send-message`

{% hint style="info" %}
**Call limit**

You can call it up to 10 times per minute per user identification key. If exceeded, an error is returned.
{% endhint %}

**Request headers**

Use one of the two headers below to identify the sending target. Do not pass both headers at the same time.

| Name              | Type   | Required   | Description                                                                                                                                                                                                                                                                     |
| ----------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-toss-user-key` | string | Choose one | [Toss login](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login)obtained from `userKey`It is. [You can obtain it through](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)Get user info |
| `x-anon-key`      | string | Choose one | [User identification key issuance](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)obtained from `hash` value.                                                                                                                             |

**Request body**

| Name            | Type   | Required | Description                                                                                                                   |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| templateSetCode | string | Y        | This is the message template code to use. Enter the template code registered in the console.                                  |
| context         | object | Y        | These are the template variable values. Enter values to be included in the template, such as user name and verification code. |

```json
{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "context": {
    "userName": "Hong Gil-dong",
    "otp": "123456"
  }
}
```

```bash
curl --location 'https://apps-in-toss-api.toss.im/api-partner/v1/apps-in-toss/messenger/send-message' \
--header 'Content-Type: application/json' \
--header 'x-toss-user-key: {{userKey}}' \
--data '{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "context": {
    "userName": "Hong Gil-dong",
    "otp": "123456"
  }
}'
```

`anonKey`When sending to `x-anon-key` use the

```bash
curl --location 'https://apps-in-toss-api.toss.im/api-partner/v1/apps-in-toss/messenger/send-message' \
--header 'Content-Type: application/json' \
--header 'x-anon-key: {{anonKey}}' \
--data '{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "context": {
    "userName": "Hong Gil-dong",
    "otp": "123456"
  }
}'
```

**Success response**

The response structure is [Send test message](#_1-테스트-메시지-발송하기)the same as.

```json
{
  "resultType": "SUCCESS",
  "success": {
    "msgCount": 1,
    "sentPushCount": 1,
    "sentInboxCount": 0,
    "sentSmsCount": 0,
    "sentAlimtalkCount": 0,
    "sentFriendtalkCount": 0,
    "detail": {
      "sentPush": [{ "contentId": "MSG_ABC123" }],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    },
    "fail": {
      "sentPush": [],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    }
  }
}
```

**Failure response**

```json
{
  "resultType": "FAIL",
  "error": {
    "errorCode": "INVALID_PARAMETER",
    "reason": "The request failed."
  }
}
```

| HTTP status code | Description                                                  |
| ---------------- | ------------------------------------------------------------ |
| 400              | The request was invalid or required information was missing. |
| 401              | The user is not authenticated.                               |
| 403              | You do not have permission to send messages.                 |

***

### 3. Send bulk messages

Send the same functional message template to multiple users at once. Use this for sends of 50 or more, and you can send up to 2,500 at a time.

* Content-Type: `application/json`
* Method: `POST`
* URL: `/api-partner/v1/apps-in-toss/messenger/send-bulk-message`

**Request body**

| Name            | Type   | Required | Description                                                                                  |
| --------------- | ------ | -------- | -------------------------------------------------------------------------------------------- |
| templateSetCode | string | Y        | This is the message template code to use. Enter the template code registered in the console. |
| contextList     | array  | Y        | This is the list of users who will receive the message. Minimum 1, maximum 2,500.            |

`contextList` Item fields:

| Name    | Type             | Required      | Description                                                                                                                                                                                                                                                                                                              |
| ------- | ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| userKey | string \| number | Conditional Y | [Toss login](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login)obtained from `userKey`It is. [You can obtain it through](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)Get user info `x-anon-key`cannot be used together with |
| anonKey | string           | Conditional Y | Received through user identification key issuance `hash` value. `userKey`cannot be used together with                                                                                                                                                                                                                    |
| context | object           | Y             | These are the template variable values. Enter values to be included in the template, such as user name and verification code.                                                                                                                                                                                            |

Each `contextList` item `userKey`and `anonKey` one of the following must be provided.

```json
{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "contextList": [
    {
      "userKey": {{userKey1}},
      "context": {
        "userName": "Hong Gil-dong",
        "otp": "123456"
      }
    },
    {
      "userKey": {{userKey2}},
      "context": {
        "userName": "Kim Cheol-su",
        "otp": "654321"
      }
    }
  ]
}
```

`anonKey`When sending to `anonKey`put

```json
{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "contextList": [
    {
      "anonKey": "{{anonKey1}}",
      "context": {
        "userName": "Hong Gil-dong",
        "otp": "123456"
      }
    },
    {
      "anonKey": "{{anonKey2}}",
      "context": {
        "userName": "Kim Cheol-su",
        "otp": "654321"
      }
    }
  ]
}
```

```bash
curl --location 'https://apps-in-toss-api.toss.im/api-partner/v1/apps-in-toss/messenger/send-bulk-message' \
--header 'Content-Type: application/json' \
--data '{
  "templateSetCode": "ALERT_OTP_TEMPLATE",
  "contextList": [
    {
      "userKey": 12345678,
      "context": { "userName": "Hong Gil-dong", "otp": "123456" }
    },
    {
      "userKey": 87654321,
      "context": { "userName": "Kim Cheol-su", "otp": "654321" }
    }
  ]
}'
```

**Success response**

The response structure is [Send test message](#_1-테스트-메시지-발송하기)the same as.

```json
{
  "resultType": "SUCCESS",
  "success": {
    "msgCount": 2,
    "sentPushCount": 2,
    "sentInboxCount": 0,
    "sentSmsCount": 0,
    "sentAlimtalkCount": 0,
    "sentFriendtalkCount": 0,
    "detail": {
      "sentPush": [{ "contentId": "MSG_ABC123" }, { "contentId": "MSG_DEF456" }],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    },
    "fail": {
      "sentPush": [],
      "sentInbox": [],
      "sentSms": [],
      "sentAlimtalk": [],
      "sentFriendtalk": []
    }
  }
}
```

***

### 4. Request notification consent form (`requestNotificationAgreement`)

`requestNotificationAgreement`is Smart Delivery's **functional messages**It is the function that requests the user for a notification reception consent UI before sending.

In situations where the user chooses to receive a specific notification, you must obtain consent first. The consent result is `onEvent` delivered via a callback, and you can decide whether to send the notification based on the result.

{% hint style="info" %}
**You need to register a notification consent form**

Before development, complete the following steps first.

1. Create a notification consent form.
2. Create a functional campaign and link the registered notification consent form.
3. Once copy review approval is obtained, you can use the template code of the registered functional campaign.
4. Use this template code `templateCode`pass it as.

Please refer to the Smart Delivery introduction document for setup instructions.
{% endhint %}

**Signature**

```typescript
function requestNotificationAgreement(params: RequestNotificationAgreementOptions): () => void;
```

**Parameters**

* params required

  These are the parameters used for requesting notification consent. For the detailed type, see below `RequestNotificationAgreementOptions`.

**Return value**

* () => void

  Returns the Apps Bridge cleanup function. After receiving the consent result, you must call this function to release resources.

**Example**

{% tabs %}
{% tab title="React" %}

```tsx
import { requestNotificationAgreement } from '@apps-in-toss/web-framework';

function NotificationAgreementButton() {
  const handleRequestAgreement = () => {
    const cleanup = requestNotificationAgreement({
      options: {
        templateCode: 'your-template-code',
      },
      onEvent: ({ type }) => {
        if (type === 'newAgreement') {
          console.log('Agreed to receive notifications.');
        } else if (type === 'alreadyAgreed') {
          console.log('You are already in the agreed state.');
        } else if (type === 'agreementRejected') {
          console.log('You rejected receiving notifications.');
        }
        cleanup();
      },
      onError: (error) => {
        console.error('Failed to request notification consent:', error);
        cleanup();
      },
    });
  };

  return <button onClick={handleRequestAgreement}>Receive notifications</button>;
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import { Button } from 'react-native';
import { requestNotificationAgreement } from '@apps-in-toss/framework';

function NotificationAgreementButton() {
  const handleRequestAgreement = () => {
    const cleanup = requestNotificationAgreement({
      options: {
        templateCode: 'your-template-code',
      },
      onEvent: ({ type }) => {
        if (type === 'newAgreement') {
          console.log('Agreed to receive notifications.');
        } else if (type === 'alreadyAgreed') {
          console.log('You are already in the agreed state.');
        } else if (type === 'agreementRejected') {
          console.log('You rejected receiving notifications.');
        }
        cleanup();
      },
      onError: (error) => {
        console.error('Failed to request notification consent:', error);
        cleanup();
      },
    });
  };

  return <Button title="Receive notifications" onPress={handleRequestAgreement} />;
}
```

{% endtab %}
{% endtabs %}

**`RequestNotificationAgreementOptions`**

`requestNotificationAgreement` This is the type of parameters passed to the function.

```typescript
interface RequestNotificationAgreementOptions {
  options: {
    templateCode: string;
  };
  onEvent: (result: { type: NotificationAgreementResult }) => void;
  onError: (error: unknown) => void | Promise<void>;
}
```

* options required

  This is the options object used for requesting notification consent.

  * options.templateCode required

    This is the template code of the functional campaign linked to the notification consent form. Please enter the template code registered in the console.
* onEvent required

  This is the callback executed when the consent result is confirmed. `NotificationAgreementResult` of type `type` is passed.
* onError required

  This is the callback executed when an unexpected error occurs. The error object is of type `unknown`.

**`NotificationAgreementResult`**

`onEvent` This is the consent result type passed in the callback.

```typescript
type NotificationAgreementResult = 'newAgreement' | 'alreadyAgreed' | 'agreementRejected';
```

| Value               | Description                                                                                 |
| ------------------- | ------------------------------------------------------------------------------------------- |
| `newAgreement`      | This is when the user newly completed consent.                                              |
| `alreadyAgreed`     | This is when the result is returned with consent already given, without additional consent. |
| `agreementRejected` | This is when the user rejected consent.                                                     |

**Notes**

* `onEvent` or `onError` Please make sure to call the cleanup function returned by the callback.
* Before calling the function again in the same component, run the previous cleanup first. Otherwise, the previous event listener may remain duplicated.
* For how to register a notification consent form and the functional message sending flow, refer to the Smart Delivery introduction document.
* To send messages after user consent, on the partner server [Send message](#_2-메시지-발송하기)Please call.
* Users can directly control whether they receive notifications in the Toss app → More tab → Settings button → Notifications → Service-specific notifications.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/growth/smart-message.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
