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

# Redeem a coupon

> Mark a BrandWallet coupon as redeemed and return the updated coupon.

`POST /v1/customers/:id/coupons/:couponId/redeem` marks the given coupon as redeemed and returns the updated coupon. All body fields are optional and carry **opaque IDs** (your external system identifiers) that are resolved to internal references on our side.

```bash theme={null}
POST $BASE_URL/v1/customers/:id/coupons/:couponId/redeem
```

When `user` is omitted the authenticated API user is recorded as the redeeming user; when `branch` is omitted the authenticated user's branch is used.

## Request headers

<ParamField header="Authorization" type="string" required>
  Your active Bearer token: `Bearer <accessToken>`.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Always `application/json`.
</ParamField>

## Path parameters

<ParamField path="id" type="string" required>
  Customer id.
</ParamField>

<ParamField path="couponId" type="string" required>
  Coupon instance id (from [GET /v1/customers/:id/coupons](/api/list-coupons)).
</ParamField>

## Request body

<ParamField body="user" type="string">
  Cashier user opaque id.
</ParamField>

<ParamField body="branch" type="string">
  Branch opaque id.
</ParamField>

<ParamField body="products" type="string[]">
  Product opaque ids included in the redemption.
</ParamField>

## Response fields (200 OK)

<ResponseField name="id" type="string">
  Coupon instance id.
</ResponseField>

<ResponseField name="coupon" type="object">
  Coupon summary (`name`).
</ResponseField>

<ResponseField name="redeemed" type="object">
  The branch and user that performed the redeem.

  <Expandable title="redeemed fields">
    <ResponseField name="branch" type="string">
      Branch opaque id.
    </ResponseField>

    <ResponseField name="user" type="string">
      Cashier user opaque id.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="redeemedAt" type="string">
  When the coupon was redeemed (ISO 8601).
</ResponseField>

<ResponseField name="status" type="string">
  Now `redeemed`.
</ResponseField>

<RequestExample>
  ```bash Request theme={null}
  curl --request POST \
    --url "$BASE_URL/v1/customers/3d8ec956-.../coupons/906550fd-.../redeem" \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...' \
    --header 'Content-Type: application/json' \
    --data '{
      "branch": "9bb88786-6df3-4d16-b4dd-e89b43e8b2b5"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "id": "906550fd-dcf5-4aed-a80e-03e8939fc2b4",
    "coupon": { "name": "Free Coffee Coupon" },
    "code": "500265",
    "issuedAt": "2026-04-21T12:19:19.037Z",
    "expiresAt": "2026-09-09T12:14:08.511Z",
    "redeemed": {
      "branch": "9bb88786-6df3-4d16-b4dd-e89b43e8b2b5",
      "user": "4eeb2186-7ca7-4a45-81e1-1616480975d6"
    },
    "redeemedAt": "2026-08-04T10:00:00.000Z",
    "status": "redeemed"
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "statuscode": 400,
    "errorcode": 400,
    "message": "_coupon_is_not_valid",
    "description": "",
    "timestamp": 1754040000000,
    "path": "/v1/customers/.../redeem",
    "method": "POST"
  }
  ```
</ResponseExample>

<Note>
  A coupon can also be redeemed as part of a basket by passing its id in `reward` on [POST /v1/transactions/process](/api/process-transaction).
</Note>
