---
title: "POST /reseller/codes — Issue gift codes"
url: https://lumean.app/en/developers/docs/api/post-reseller-codes
locale: en
description: "Issue gift codes"
generated: 2026-10-17
operationId: reseller.issueCodes
method: POST
path: /reseller/codes
scopes: [reseller.write]
spec_version: 0.0.1
---

# POST /reseller/codes

**Issue gift codes**

Issues gift codes at the reseller's personal discount, paid from the reseller balance.
The response carries the batch with the FULL codes.

**Body:** `nominals` — code nominals in LMC (strings or numbers), one per code.

**Idempotency:** send the `Idempotency-Key` header (1–64 characters `A-Z a-z 0-9 _ . : -`)
so that a network retry cannot issue a second batch. A retry with the same key and the
same nominals returns the original batch — `200` plus the `Idempotent-Replayed: true`
header, and the balance is not charged again; the same key with different nominals gives
`422` `idempotency_key_mismatch`.

**Key permission:** `reseller.write`.

- Required scope: `reseller.write`

## Request

```bash
curl -X POST 'https://api.lumean.app/api/public/reseller/codes' \
  -H 'Accept: application/json' \
  -H 'X-API-KEY: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "nominals": [
    1
  ]
}'
```

## Parameters

| Field | In | Type | Req. | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | `string` | — | Optional issue idempotency key: 1–64 characters `A-Z a-z 0-9 _ . : -`. |

## Request body

Issuing codes from the reseller balance. The `Idempotency-Key` header is optional but
recommended: with it a network retry cannot issue a second batch.

Content-Type: `application/json`

| Field | Type | Req. | Description |
| --- | --- | --- | --- |
| `nominals` | `array<number>` — min items: 1, max items: 1000 | required | Code nominals in LMC, one number per code: as many codes as elements. Numbers and decimal strings are accepted; a nominal is either one of the presets from `GET /reseller/settings` or between `min_nominal` and `max_nominal`. The number of elements is capped by `limits.max_codes_per_issue` from `GET /reseller`. |

**Example**

```json
{
  "nominals": [
    1
  ]
}
```

## Responses

### 200 — A replay by `Idempotency-Key`: the original batch, with the `Idempotent-Replayed: true` header; the balance is not charged again.

**Response fields**

| Field | Type | Req. | Description |
| --- | --- | --- | --- |
| `success` | `boolean` | required | Success flag. Branch on the HTTP status code instead: any 2xx response carries `true` here, while an error comes back in a different shape that need not contain this field at all. |
| `message` | `string` | required | A human-readable note in the account language. Fine to show to a user; do not parse it — the wording changes without notice and is not an error code. |
| `data` | `GiftCodeBatch` | required | The issued batch. On a replay by `Idempotency-Key` (code 200, header `Idempotent-Replayed: true`) it is the same batch as in the first response; the balance is not charged again. |
| `data.uuid` | `string` | required | The batch id. |
| `data.source` | `string` | required | Always `reseller` — the batch was issued from the reseller balance. |
| `data.codes_count` | `string` | required | How many codes the batch holds. |
| `data.nominal_total` | `string` | required | Sum of the code nominals, LMC minor units. |
| `data.nominal_total_formatted` | `number` | required | Sum of the nominals, LMC. |
| `data.cost_total` | `string` | — | How much was charged to the reseller balance (nominals minus the discount), LMC minor units. |
| `data.cost_total_formatted` | `number` | — | Charged to the reseller balance, LMC. |
| `data.discount_bps` | `integer` | — | The reseller personal discount at issue time, basis points (1000 = 10%). |
| `data.codes` | `array<GiftCode>` | — | The batch codes with the FULL `code` value — store them: they are bearer money. |
| `data.codes[].uuid` | `string` | required | Code UUID. Use it in the `GET /reseller/codes/{uuid}` and `POST /reseller/codes/{uuid}/cancel` paths. |
| `data.codes[].code_masked` | `string` | required | The code with a mask, `LUM-****-****-XXXX`: safe to show in a UI and to write to logs. |
| `data.codes[].code` | `string` | — | The FULL code value — what the recipient types to redeem it. The reseller public API returns it in the list, on show and on issue. Treat it as a secret: whoever knows the code can redeem it. |
| `data.codes[].nominal` | `string` | required | The code’s nominal value in minor LMC units: `real = nominal / 10^currency_asset.precision`. This is how much LMC the redeemer receives. |
| `data.codes[].nominal_formatted` | `number` | required | The same nominal value in whole LMC — a number ready to display. |
| `data.codes[].cost` | `string` | — | What the code cost the reseller after the discount, in minor LMC units. Present only for reseller codes (`source: reseller`). |
| `data.codes[].cost_formatted` | `number` | — | The same cost in whole LMC. Present only for reseller codes. |
| `data.codes[].discount_bps` | `integer` | — | The reseller’s discount at the moment of issue, in basis points (`100` = 1%). A later change of the personal discount does not affect this code. Present only for reseller codes. |
| `data.codes[].source` | `string` | required |  |
| `data.codes[].funding` | `string` | required |  |
| `data.codes[].status` | `string` | required |  |
| `data.codes[].activatable_at` | `string` | required | The moment from which the code can be redeemed; until then it is frozen. `null` means no restriction. |
| `data.codes[].redeemed_at` | `string` | required | When the code was redeemed. `null` until it is. The API never reveals who redeemed it. |
| `data.codes[].cancelled_at` | `string` | required | When the reseller cancelled the code. `null` if it was not cancelled. |
| `data.codes[].created_at` | `string` | required | When the code was issued. |
| `data.codes[].currency_asset` | `object` | required | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `data.codes[].currency_asset.code` | `string` — `LUMC` | required | Code of the asset the amounts are expressed in. |
| `data.codes[].currency_asset.precision` | `integer` | required | How many decimals LMC has: `real = value / 10^precision`. |
| `data.created_at` | `string` | required | When the batch was issued. |
| `data.currency_asset` | `object` | required | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `data.currency_asset.code` | `string` — `LUMC` | required | Code of the asset the amounts are expressed in. |
| `data.currency_asset.precision` | `integer` | required | How many decimals LMC has: `real = value / 10^precision`. |

**Example**

```json
{
  "success": true,
  "message": "string",
  "data": {
    "uuid": "string",
    "source": "string",
    "codes_count": "string",
    "nominal_total": "string",
    "nominal_total_formatted": 1,
    "cost_total": "string",
    "cost_total_formatted": 1,
    "discount_bps": 1,
    "codes": [
      {
        "uuid": "string",
        "code_masked": "string",
        "code": "string",
        "nominal": "string",
        "nominal_formatted": 1,
        "cost": "string",
        "cost_formatted": 1,
        "discount_bps": 1,
        "source": "string",
        "funding": "string",
        "status": "string",
        "activatable_at": "string",
        "redeemed_at": "string",
        "cancelled_at": "string",
        "created_at": "string",
        "currency_asset": {
          "code": "string",
          "precision": 1
        }
      }
    ],
    "created_at": "string",
    "currency_asset": {
      "code": "string",
      "precision": 1
    }
  }
}
```

### 201 — The batch is issued. `data` holds the batch with the FULL codes in `codes[]`.

**Response fields**

| Field | Type | Req. | Description |
| --- | --- | --- | --- |
| `success` | `boolean` | required | Success flag. Branch on the HTTP status code instead: any 2xx response carries `true` here, while an error comes back in a different shape that need not contain this field at all. |
| `message` | `string` | required | A human-readable note in the account language. Fine to show to a user; do not parse it — the wording changes without notice and is not an error code. |
| `data` | `GiftCodeBatch` | required | The issued batch. On a replay by `Idempotency-Key` (code 200, header `Idempotent-Replayed: true`) it is the same batch as in the first response; the balance is not charged again. |
| `data.uuid` | `string` | required | The batch id. |
| `data.source` | `string` | required | Always `reseller` — the batch was issued from the reseller balance. |
| `data.codes_count` | `string` | required | How many codes the batch holds. |
| `data.nominal_total` | `string` | required | Sum of the code nominals, LMC minor units. |
| `data.nominal_total_formatted` | `number` | required | Sum of the nominals, LMC. |
| `data.cost_total` | `string` | — | How much was charged to the reseller balance (nominals minus the discount), LMC minor units. |
| `data.cost_total_formatted` | `number` | — | Charged to the reseller balance, LMC. |
| `data.discount_bps` | `integer` | — | The reseller personal discount at issue time, basis points (1000 = 10%). |
| `data.codes` | `array<GiftCode>` | — | The batch codes with the FULL `code` value — store them: they are bearer money. |
| `data.codes[].uuid` | `string` | required | Code UUID. Use it in the `GET /reseller/codes/{uuid}` and `POST /reseller/codes/{uuid}/cancel` paths. |
| `data.codes[].code_masked` | `string` | required | The code with a mask, `LUM-****-****-XXXX`: safe to show in a UI and to write to logs. |
| `data.codes[].code` | `string` | — | The FULL code value — what the recipient types to redeem it. The reseller public API returns it in the list, on show and on issue. Treat it as a secret: whoever knows the code can redeem it. |
| `data.codes[].nominal` | `string` | required | The code’s nominal value in minor LMC units: `real = nominal / 10^currency_asset.precision`. This is how much LMC the redeemer receives. |
| `data.codes[].nominal_formatted` | `number` | required | The same nominal value in whole LMC — a number ready to display. |
| `data.codes[].cost` | `string` | — | What the code cost the reseller after the discount, in minor LMC units. Present only for reseller codes (`source: reseller`). |
| `data.codes[].cost_formatted` | `number` | — | The same cost in whole LMC. Present only for reseller codes. |
| `data.codes[].discount_bps` | `integer` | — | The reseller’s discount at the moment of issue, in basis points (`100` = 1%). A later change of the personal discount does not affect this code. Present only for reseller codes. |
| `data.codes[].source` | `string` | required |  |
| `data.codes[].funding` | `string` | required |  |
| `data.codes[].status` | `string` | required |  |
| `data.codes[].activatable_at` | `string` | required | The moment from which the code can be redeemed; until then it is frozen. `null` means no restriction. |
| `data.codes[].redeemed_at` | `string` | required | When the code was redeemed. `null` until it is. The API never reveals who redeemed it. |
| `data.codes[].cancelled_at` | `string` | required | When the reseller cancelled the code. `null` if it was not cancelled. |
| `data.codes[].created_at` | `string` | required | When the code was issued. |
| `data.codes[].currency_asset` | `object` | required | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `data.codes[].currency_asset.code` | `string` — `LUMC` | required | Code of the asset the amounts are expressed in. |
| `data.codes[].currency_asset.precision` | `integer` | required | How many decimals LMC has: `real = value / 10^precision`. |
| `data.created_at` | `string` | required | When the batch was issued. |
| `data.currency_asset` | `object` | required | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `data.currency_asset.code` | `string` — `LUMC` | required | Code of the asset the amounts are expressed in. |
| `data.currency_asset.precision` | `integer` | required | How many decimals LMC has: `real = value / 10^precision`. |

**Example**

```json
{
  "success": true,
  "message": "string",
  "data": {
    "uuid": "string",
    "source": "string",
    "codes_count": "string",
    "nominal_total": "string",
    "nominal_total_formatted": 1,
    "cost_total": "string",
    "cost_total_formatted": 1,
    "discount_bps": 1,
    "codes": [
      {
        "uuid": "string",
        "code_masked": "string",
        "code": "string",
        "nominal": "string",
        "nominal_formatted": 1,
        "cost": "string",
        "cost_formatted": 1,
        "discount_bps": 1,
        "source": "string",
        "funding": "string",
        "status": "string",
        "activatable_at": "string",
        "redeemed_at": "string",
        "cancelled_at": "string",
        "created_at": "string",
        "currency_asset": {
          "code": "string",
          "precision": 1
        }
      }
    ],
    "created_at": "string",
    "currency_asset": {
      "code": "string",
      "precision": 1
    }
  }
}
```

### 409 — `reseller_inactive` — the account is blocked; `reseller_insufficient_balance` — the balance is not enough.

**Response fields**

| Field | Type | Req. | Description |
| --- | --- | --- | --- |
| `success` | `boolean` | required | Always `false` in error responses. |
| `message` | `string` | required | Error text in the key's language (set through the `X-Locale` header). |
| `reason` | `string` — `quote_mismatch` | required | Machine-readable failure reason — branch on this, not on the message text. |
| `error_code` | `string` — `quote_mismatch` | required | The same machine-readable code as in `reason` — a second name for the field. The values always match; branch on either. |
| `actual_lmc_minor` | `integer` | required | What the top-up costs right now (LMC minor units). |
| `quoted_lmc_minor` | `integer` | required | The price you agreed to earlier (LMC minor units). |

**Example**

```json
{
  "success": false,
  "message": "The pay-as-you-go quote is stale — request a fresh one.",
  "reason": "quote_mismatch",
  "error_code": "quote_mismatch",
  "actual_lmc_minor": 380000000,
  "quoted_lmc_minor": 360000000
}
```

### 422 — Validation error; `gift_code_nominal_not_allowed`, `reseller_too_many_codes`, `idempotency_key_mismatch` — the same key with different nominals.

**Response fields**

| Field | Type | Req. | Description |
| --- | --- | --- | --- |
| `message` | `string` | required | Errors overview. |
| `errors` | `object` | required | A detailed description of each field that failed validation. |
| `errors.*` | `array<string>` — arbitrary keys | — |  |

**Example**

```json
{
  "message": "string",
  "errors": {
    "key": [
      "string"
    ]
  }
}
```

---

- This page in the browser: https://lumean.app/en/developers/docs/api/post-reseller-codes
- Full machine-readable reference: https://api.lumean.app/docs/llm.md
