> 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/promotion.md).

# Promotion

For service introduction and console setup instructions, [the promotion introduction document](https://developers-apps-in-toss.toss.im/guide/marketing/promotion)please refer to.

{% hint style="info" %}
**Please make sure to check before developing a promotion**

To prevent users from misunderstanding, you cannot use the same name as one already used in Toss or use it with a different meaning.

**\[Example]**

* **Points**
  * For in-app rewards that are used within the mini app, **'Points'** cannot be used as the name.
    * It may be mistaken as having been granted 'Toss Points'.
  * Please use a term that can be clearly distinguished from 'Toss Points'.
* **Withdrawal, cash-out, etc.** — Terms that may be mistaken for cashing out cannot be used.
  * If virtual assets are converted to 'Toss Points' within the mini app, **'Toss Points granted'** please label it as
    {% endhint %}

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

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

***

### Game mini app

Even without separate server integration, **grant Toss Points to users within the game mini app**and expose it in the Benefits tab.

**SDK function: `grantPromotionRewardForGame`**

This function can only be called from mini apps in the game category. If executed in a non-game category, an error occurs.

{% hint style="info" %}
**Please note**

* **Toss app version 5.232.0 or later**is supported. `undefined` The undefined value is returned below that version, and in that case, a screen that guides users to update is displayed when entering the mini app.
* To reliably secure identifiers for all users, **we raised the minimum supported version of the Toss app to 5.232.0**.
* The game user identifier is **an internal key for identifying the game company**and can only be used as such; you cannot make direct requests to Toss servers with this key.
* If you call the function repeatedly, rewards may be granted to the same user more than once, so **please be sure to apply defensive logic**.
* **Before starting the actual promotion, you must call at least once with the test promotion code**must do so. (Through the test call, the promotion is properly registered and transitions to approved status.)
  {% endhint %}

**Signature**

{% code collapsedlinecount="10" %}

```typescript
function grantPromotionRewardForGame({
  params,
}: {
  params: {
    promotionCode: string;
    amount: number;
  };
}): Promise<GrantPromotionRewardForGameResult>;
```

{% endcode %}

**Parameters**

* **params** · Required · `{ params: { promotionCode: string; amount: number } }`

  This is the information needed to grant points.

  * **params.promotionCode** · Required · `string`

    This is the promotion code.
  * **params.amount** · Required · `number`

    This is the amount of points to grant.

**Return value**

* `Promise<{ key: string } | { errorCode: string; message: string } | 'ERROR' | undefined>`

Returns the point grant result.

* `{ key: string }`: Point grant succeeded. key refers to the reward key.
* `{ errorCode: string, message: string }`: Point grant failed. Please check the error code.

**Error code**

These are the error codes that can occur while using the promotion function. Refer to the response code or message and **apply appropriate exception handling logic**.

{% hint style="info" %}
**`4109` What if an error occurs?**

* When **80% of the promotion budget has been spent, an email notification**is sent.
* To continue the promotion, **increase the budget in the console**.
* If the budget is insufficient, **top up the amount in Biz Wallet**to increase the budget.
* When the budget is exhausted, the promotion **ends automatically `4109` and an error occurs**.
* If point grant fails due to insufficient budget, **it can lead to user CS issues, so please be careful**.
  {% endhint %}

| Code        | Message                                                      | Cause / response method                                                                                             |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `40000`     |                                                              | When called from a non-game mini app                                                                                |
| `4100`      | Could not find promotion information                         | When called with a promotion key not registered in the console                                                      |
| `4109`      | The promotion is not running                                 | When the promotion was not started in the console, or was automatically terminated because the budget was exhausted |
| `4110`      | Rewards cannot be granted/reclaimed                          | This is a case where an internal system error occurred, **Re-grant logic**.                                         |
| `4111`      | Could not find reward grant history                          | When querying a grant history that does not exist                                                                   |
| `4112`      | Promotion funds are insufficient                             | Grant failed due to insufficient budget; increase the budget in the console or top up Biz Wallet is required        |
| `4114`      | Exceeded the one-time grant amount                           |                                                                                                                     |
| `4116`      | The maximum grant amount exceeded the budget                 |                                                                                                                     |
| `ERROR`     | An unknown error occurred.                                   |                                                                                                                     |
| `undefined` | The app version is lower than the minimum supported version. |                                                                                                                     |

**Example**

{% tabs %}
{% tab title="js" %}
{% code collapsedlinecount="10" %}

```js
import { grantPromotionRewardForGame } from '@apps-in-toss/web-framework';

async function handleGrantPromotionRewardForGame() {
  const result = await grantPromotionRewardForGame({
    params: {
      promotionCode: 'GAME_EVENT_2024',
      amount: 1000,
    },
  });

  if (!result) {
    console.warn('Unsupported app version.');
  } else if (result === 'ERROR') {
    console.error('An unknown error occurred while granting points.');
  } else if ('key' in result) {
    console.log('Point grant succeeded!', result.key);
  } else if ('errorCode' in result) {
    console.error('Point grant failed:', result.errorCode, result.message);
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="React" %}
{% code collapsedlinecount="10" %}

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

function GrantRewardButton() {
  async function handleClick() {
    const result = await grantPromotionRewardForGame({
      params: {
        promotionCode: 'GAME_EVENT_2024',
        amount: 1000,
      },
    });

    if (!result) {
      console.warn('Unsupported app version.');
      return;
    }

    if (result === 'ERROR') {
      console.error('An unknown error occurred while granting points.');
      return;
    }

    if ('key' in result) {
      console.log('Point grant succeeded!', result.key);
    } else if ('errorCode' in result) {
      console.error('Point grant failed:', result.errorCode, result.message);
    }
  }

  return <button onClick={handleClick}>Grant points</button>;
}
```

{% endcode %}
{% endtab %}

{% tab title="React Native" %}
{% code collapsedlinecount="10" %}

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

function GrantRewardButton() {
  async function handlePress() {
    const result = await grantPromotionRewardForGame({
      params: {
        promotionCode: 'GAME_EVENT_2024',
        amount: 1000,
      },
    });

    if (!result) {
      console.warn('Unsupported app version.');
      return;
    }

    if (result === 'ERROR') {
      console.error('An unknown error occurred while granting points.');
      return;
    }

    if ('key' in result) {
      console.log('Point grant succeeded!', result.key);
    } else if ('errorCode' in result) {
      console.error('Point grant failed:', result.errorCode, result.message);
    }
  }

  return <Button onPress={handlePress} title="Grant points" />;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

### Non-game mini app

There are two ways to grant Toss Points to users through promotions in a non-game category mini app.

* **Grant without a server**: Grant points simply by calling the SDK function without separate server integration.
* **Grant through server**: Grant points by directly calling the API from the partner company's server. Use this when integrity is important, such as preventing request tampering.

#### Grant promotional points without a server

**SDK function: `grantPromotionReward`**

Even without separate server integration, **Grant Toss Points to users within the non-game mini app**and expose it in the Benefits tab.

{% hint style="info" %}
**Please note**

* **Toss app version 5.232.0 or later**is supported. Below that version, `undefined`is returned, and a screen that guides users to update is displayed when entering the mini app.
* If you call the function repeatedly, rewards may be granted to the same user more than once, so **please be sure to apply defensive logic**.
* **Before starting the actual promotion, you must call at least once with the test promotion code**You have to. Test promotion codes should not be called from the sandbox app **Toss app (QR code test)** must be called from.
  {% endhint %}

**Signature**

{% code collapsedlinecount="10" %}

```typescript
function grantPromotionReward({
  params,
}: {
  params: {
    promotionCode: string;
    amount: number;
  };
}): Promise<GrantPromotionRewardResult>;
```

{% endcode %}

**Parameters**

* **params** · Required · `{ params: { promotionCode: string; amount: number } }`

  This is the information needed to grant points.

  * **params.promotionCode** · Required · `string`

    This is the promotion code.
  * **params.amount** · Required · `number`

    This is the amount of points to grant.

**Return value**

* `Promise<{ key: string } | { errorCode: string; message: string } | 'ERROR' | undefined>`

Returns the point grant result.

* `{ key: string }`: Point grant succeeded. key refers to the reward key.
* `{ errorCode: string, message: string }`: Point grant failed. Please check the error code.

**Error code**

These are the error codes that can occur while using the promotion function. Refer to the response code or message and **apply appropriate exception handling logic**.

{% hint style="info" %}
**`4109` What if an error occurs?**

* When **80% of the promotion budget has been spent, an email notification**is sent.
* To continue the promotion, **increase the budget in the console**.
* If the budget is insufficient, **top up the amount in Biz Wallet**to increase the budget.
* When the budget is exhausted, the promotion **ends automatically `4109` and an error occurs**.
* If point grant fails due to insufficient budget, **it can lead to user CS issues, so please be careful**.
  {% endhint %}

| Code        | Message                                                      | Cause / response method                                                                                             |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `4100`      | Could not find promotion information                         | When called with a promotion key not registered in the console                                                      |
| `4109`      | The promotion is not running                                 | When the promotion was not started in the console, or was automatically terminated because the budget was exhausted |
| `4110`      | Rewards cannot be granted/reclaimed                          | This is a case where an internal system error occurred, **Re-grant logic**.                                         |
| `4111`      | Could not find reward grant history                          | When querying a grant history that does not exist                                                                   |
| `4112`      | Promotion funds are insufficient                             | Grant failed due to insufficient budget; increase the budget in the console or top up Biz Wallet is required        |
| `4114`      | Exceeded the one-time grant amount                           |                                                                                                                     |
| `4116`      | The maximum grant amount exceeded the budget                 |                                                                                                                     |
| `ERROR`     | An unknown error occurred.                                   |                                                                                                                     |
| `undefined` | The app version is lower than the minimum supported version. |                                                                                                                     |

**Example**

{% tabs %}
{% tab title="js" %}
{% code collapsedlinecount="10" %}

```js
import { grantPromotionReward } from '@apps-in-toss/web-framework';

async function handleGrantPromotionReward() {
  const result = await grantPromotionReward({
    params: {
      promotionCode: 'EVENT_2024',
      amount: 1000,
    },
  });

  if (!result) {
    console.warn('Unsupported app version.');
  } else if (result === 'ERROR') {
    console.error('An unknown error occurred while granting points.');
  } else if ('key' in result) {
    console.log('Point grant succeeded!', result.key);
  } else if ('errorCode' in result) {
    console.error('Point grant failed:', result.errorCode, result.message);
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="React" %}
{% code collapsedlinecount="10" %}

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

function GrantRewardButton() {
  async function handleClick() {
    const result = await grantPromotionReward({
      params: {
        promotionCode: 'EVENT_2024',
        amount: 1000,
      },
    });

    if (!result) {
      console.warn('Unsupported app version.');
      return;
    }

    if (result === 'ERROR') {
      console.error('An unknown error occurred while granting points.');
      return;
    }

    if ('key' in result) {
      console.log('Point grant succeeded!', result.key);
    } else if ('errorCode' in result) {
      console.error('Point grant failed:', result.errorCode, result.message);
    }
  }

  return <button onClick={handleClick}>Grant points</button>;
}
```

{% endcode %}
{% endtab %}

{% tab title="React Native" %}
{% code collapsedlinecount="10" %}

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

function GrantRewardButton() {
  async function handlePress() {
    const result = await grantPromotionReward({
      params: {
        promotionCode: 'EVENT_2024',
        amount: 1000,
      },
    });

    if (!result) {
      console.warn('Unsupported app version.');
      return;
    }

    if (result === 'ERROR') {
      console.error('An unknown error occurred while granting points.');
      return;
    }

    if ('key' in result) {
      console.log('Point grant succeeded!', result.key);
    } else if ('errorCode' in result) {
      console.error('Point grant failed:', result.errorCode, result.message);
    }
  }

  return <Button onPress={handlePress} title="Grant points" />;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

#### Grant promotional points through the server

This is a method of directly calling the API from the partner company's server to grant Toss Points to users.

#### Identify the promotion target users

The promotion API identifies the promotion target using one of the two methods below. Do not pass both values at the same time; choose only one.

| Category          | Issuance method                                                                                                                                           |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-toss-user-key` | [Toss Login](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login)obtained with `userKey` value.                        |
| `x-anon-key`      | [Issue user identification key](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)This is the hash value obtained with |

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, use Toss Login.
* If you want to identify users lightly without login integration, use the user identification key issuance feature.

`x-anon-key`If you want to check in advance whether (hash) is a valid value, [Check identification key](/documentation/api-and-sdk-en/common/authentication/hash-key.md#undefined-4) use the 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 promotion API is server-to-server communication called from the partner server to the Apps in Toss server. For security, configure the mTLS certificate on the server before calling it. How to issue the certificate is [How to issue an mTLS certificate](https://developers-apps-in-toss.toss.im/documentation/integration/getting-started)please refer to.
{% endhint %}

#### ① Create a promotion reward grant key

Issue a key for promotion grants. You can use this key to grant rewards to users.

{% hint style="info" %}
**Please note**

* The party that grants rewards to users is the partner company. If you grant rewards to users with the issued key, **within the promotion budget limit** they will continue to be granted.

* **Grant only once**To allow

* If you try to grant again with a key that has already been used, `4113` an error occurs. If additional grants are needed, **issue a new key**.

* Issued **The key is valid for 1 hour**.
  {% endhint %}

* Content-type: application/json

* Method: `POST`

* Endpoint: `/api-partner/v1/apps-in-toss/promotion/execute-promotion/get-key`

**Request headers**

For the headers that identify the promotion target, use one of the two below. Do not send 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 with `userKey`. [Get user information](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)can be obtained through. |
| `x-anon-key`      | string | Choose one | [Issue user identification key](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)obtained with `hash` value.                                                                                                                                 |

**Response parameters**

| Name | Type   | Description                                          |
| ---- | ------ | ---------------------------------------------------- |
| key  | String | Key value for promotion grant (base64 encoded value) |

{% code collapsedlinecount="10" %}

```json
{
  "resultType": "SUCCESS",
  "success": {
    "key": "3oBpxjUgl5r66edcVi7ynHGIjhzr9KOka6FfEKikev0="
  }
}
```

{% endcode %}

#### ② Grant promotion rewards

with the issued key **execute promotion reward grant**The amount is deducted from the promotion budget when granted, and there may be a slight delay until the actual grant.

* Content-type: application/json
* Method: `POST`
* Endpoint: `/api-partner/v1/apps-in-toss/promotion/execute-promotion`

**Request headers**

For the headers that identify the promotion target, use one of the two below. Do not send 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 with `userKey`. [Get user information](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)can be obtained through. |
| `x-anon-key`      | string | Choose one | [Issue user identification key](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)obtained with `hash` value.                                                                                                                                 |

**Request parameters**

| Name          | Type    | Required | Description                              |
| ------------- | ------- | -------- | ---------------------------------------- |
| promotionCode | String  | Y        | Promotion code ID created in the console |
| key           | String  | Y        | The KEY issued for promotion grant       |
| amount        | Integer | Y        | Promotion grant amount                   |

{% code collapsedlinecount="10" %}

```json
{
  "promotionCode": "01JPPJ6SB66BQXXDAKRQZ6SZD7",
  "key": "3oBpxjUgl5r66edcVi7ynHGIjhzr9KOka6FfEKikev0=",
  "amount": 10
}
```

{% endcode %}

**Response parameters**

| Name | Type   | Description                        |
| ---- | ------ | ---------------------------------- |
| key  | String | The KEY issued for promotion grant |

{% code collapsedlinecount="10" %}

```json
{
  "resultType": "SUCCESS",
  "success": {
    "key": "3oBpxjUgl5r66edcVi7ynHGIjhzr9KOka6FfEKikev0="
  }
}
```

{% endcode %}

#### ③ Check promotion grant result

After the grant request **query the promotion grant status**.

* Content-type: application/json
* Method: `POST`
* Endpoint: `/api-partner/v1/apps-in-toss/promotion/execution-result`

**Request headers**

For the headers that identify the promotion target, use one of the two below. Do not send 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 with `userKey`. [Get user information](https://developers-apps-in-toss.toss.im/documentation/common/authentication/toss-login#_4-사용자-정보-받기)can be obtained through. |
| `x-anon-key`      | string | Choose one | [Issue user identification key](https://developers-apps-in-toss.toss.im/documentation/common/authentication/hash-key)obtained with `hash` value.                                                                                                                                 |

**Request parameters**

| Name          | Type   | Required | Description                              |
| ------------- | ------ | -------- | ---------------------------------------- |
| promotionCode | String | Y        | Promotion code ID created in the console |
| key           | String | Y        | The KEY issued for promotion grant       |

{% code collapsedlinecount="10" %}

```json
{
  "promotionCode": "01JPPJ6SB66BQXXDAKRQZ6SZD7",
  "key": "3oBpxjUgl5r66edcVi7ynHGIjhzr9KOka6FfEKikev0="
}
```

{% endcode %}

**Response parameters**

| Name    | Type   | Description                                               |
| ------- | ------ | --------------------------------------------------------- |
| success | String | Promotion grant result (`SUCCESS` / `PENDING` / `FAILED`) |

{% code collapsedlinecount="10" %}

```json
{
  "resultType": "SUCCESS",
  "success": "PENDING"
}
```

{% endcode %}

**Error code**

These are the error codes that can occur while using the promotion API. Refer to the response code or message and **apply appropriate exception handling logic**.

{% hint style="info" %}
**`4109` What if an error occurs?**

* When **80% of the promotion budget has been spent, an email notification**is sent.
* To continue the promotion, **increase the budget in the console**.
* If the budget is insufficient, **top up the amount in Biz Wallet**to increase the budget.
* When the budget is exhausted, the promotion **ends automatically `4109` and an error occurs**.
* If point grant fails due to insufficient budget, **it can lead to user CS issues, so please be careful**.
  {% endhint %}

| Code   | Message                                                       | Cause / response method                                                                                             |
| ------ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `4100` | Could not find promotion information                          | When called with a promotion key not registered in the console                                                      |
| `4109` | The promotion is not running                                  | When the promotion was not started in the console, or was automatically terminated because the budget was exhausted |
| `4110` | Rewards cannot be granted/reclaimed                           | This is a case where an internal system error occurred, **Re-grant logic**.                                         |
| `4111` | Could not find reward grant history                           | When querying a grant history that does not exist                                                                   |
| `4112` | Promotion funds are insufficient                              | Grant failed due to insufficient budget; increase the budget in the console or top up Biz Wallet is required        |
| `4113` | This is a case where the grant/reclaim history already exists | If you attempt duplicate granting with the same Key, issue a new Key and try again.                                 |
| `4114` | Exceeded the one-time grant amount                            |                                                                                                                     |
| `4116` | The maximum grant amount exceeded the budget                  |                                                                                                                     |


---

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