# Coupons

Codes guests can enter for additional discounts

Endpoint: `https://api.bookingmood.com/v1/coupons`, supporting `GET`, `POST`, `DELETE`, `PATCH`. Authenticate with the header `Authorization: Bearer YOUR_API_KEY` (see [authentication](https://www.bookingmood.com/he-IL/api-reference/authentication.md)).

## The coupon object

| Attribute | Type | Description |
| --- | --- | --- |
| `id` | `uuid` | Unique identifier. |
| `organization_id` | `uuid` | Identifier of the organization this coupon is defined in. References [`organizations.id`](https://www.bookingmood.com/he-IL/api-reference/organizations.md). |
| `created_at` | `timestamp with time zone` | Creation timestamp. Read-only: set by the database. |
| `updated_at` | `timestamp with time zone` | Last modification timestamp. Read-only: set by the database. |
| `deleted_at` | `timestamp with time zone \| null` | Timestamp at which the coupon was deleted. |
| `code` | `text` | Code guests enter to use the coupon. |
| `definition` | `PriceExpression` | Definition of the coupon. |
| `description` | `text` | Description of the coupon. |
| `fts` | `tsvector` | Full text search index. Read-only: set by the database. |
| `quota` | `integer \| null` | Maximum number of times the coupon can be used. |
| `scope` | `CouponScope` | Scope of the coupon. |
| `stackable` | `boolean` | Whether the coupon can be used together with other coupons in one booking. |

```json
{
  "id": "00000000-0000-0000-0000-000000000000",
  "organization_id": "00000000-0000-0000-0000-000000000000",
  "created_at": "2026-10-30T23:37:06.667Z",
  "updated_at": "2026-10-30T23:37:06.667Z",
  "deleted_at": "2026-10-30T23:37:06.667Z",
  "code": "SUMMER24",
  "definition": {},
  "description": "A short description.",
  "quota": 0,
  "scope": "global",
  "stackable": true
}
```

### Types

```typescript
type AbsolutePriceExpression = {
  occupancy_group_id: string | null;
  period: PeriodExpression | null;
  value: number;
};

type BookingDateVariable = "arrival_date" | "departure_date";

type BooleanExpression = 
  | {
      max: number | null;
      min: number | null;
      operator: "duration";
      variable: DurationVariable;
    }
  | {
      operator: "implies";
      then: BooleanExpression;
      when: BooleanExpression;
    }
  | {
      max: number | null;
      min: number | null;
      occupancy_group_id: string;
      operator: "occupancy";
    }
  | {
      operator: "season";
      season_id: string;
      variable: BookingDateVariable;
    }
  | {
      operator: "weekday";
      variable: BookingDateVariable;
      weekdays: Array<Day>;
    };

type CouponScope = "global" | "product" | "rent" | "service";

type Day = 6 | 0 | 1 | 2 | 3 | 4 | 5;

type DurationVariable = "advance_days" | "booking_days";

type PeriodExpression = {
  duration: number;
  start: Array<Day> | null;
};

type PriceExpression = 
  | {
      restrictions: Array<BooleanExpression>;
      type: "on-request";
    }
  | {
      restrictions: Array<BooleanExpression>;
      type: "absolute";
      value: Array<AbsolutePriceExpression>;
    }
  | {
      restrictions: Array<BooleanExpression>;
      type: "relative";
      value: number;
    }
  | {
      groups: Array<{
        max: number | null;
        min: number | null;
        value: PriceExpression;
      }>;
      occupancy_group_id: string;
      restrictions: Array<BooleanExpression>;
      type: "occupancy-discrimination";
    }
  | {
      groups: Array<{
        season_id: string;
        value: PriceExpression;
      }>;
      restrictions: Array<BooleanExpression>;
      type: "season-discrimination";
      variable: "arrival_date";
    }
  | {
      groups: Array<{
        max: number | null;
        min: number | null;
        value: PriceExpression;
      }>;
      restrictions: Array<BooleanExpression>;
      type: "duration-discrimination";
      variable: DurationVariable;
    };
```

### Related resources

Embed related resources with the [`select` parameter](https://www.bookingmood.com/he-IL/api-reference/selecting.md), e.g. `select=*,organizations(*)`. Resources related through more than one column need the column as a hint, like `table!column(*)`.

| Embed | Type | Description |
| --- | --- | --- |
| `organizations(*)` | `object \| null` | The [organization](https://www.bookingmood.com/he-IL/api-reference/organizations.md) referenced by `organization_id`. |
| `coupon_products(*)` | `array` | The [coupon products](https://www.bookingmood.com/he-IL/api-reference/coupon_products.md) referencing this coupon through `coupon_products.coupon_id`. |
| `coupon_services(*)` | `array` | The [coupon services](https://www.bookingmood.com/he-IL/api-reference/coupon_services.md) referencing this coupon through `coupon_services.coupon_id`. |
| `coupon_uses(*)` | `array` | The [coupon uses](https://www.bookingmood.com/he-IL/api-reference/coupon_uses.md) referencing this coupon through `coupon_uses.coupon_id`. |

## List coupons

`GET /v1/coupons`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Choose columns and embed related resources with `select` (see [selecting](https://www.bookingmood.com/he-IL/api-reference/selecting.md)), and sort and paginate with `order`, `limit` and `offset` (see [sorting and pagination](https://www.bookingmood.com/he-IL/api-reference/sorting-pagination.md)).

```bash
curl -X GET "https://api.bookingmood.com/v1/coupons?select=*&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: A list of coupons with the selected columns. `206` when the list is a partial range.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.

## Create coupons

`POST /v1/coupons`

Insert one coupon or an array of coupons. The body is a `Partial` coupon object, so columns with a default can be left out. Read-only attributes can't be written.

```bash
curl -X POST "https://api.bookingmood.com/v1/coupons" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "00000000-0000-0000-0000-000000000000",
    "code": "SUMMER24",
    "definition": {},
    "description": "A short description.",
    "scope": "global",
    "stackable": true
  }'
```

Responses:

- `201`: The newly created coupons with the selected columns.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

## Delete coupons

`DELETE /v1/coupons`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Without filters, this request deletes all coupons you have access to. Always filter on at least one column, e.g. `id=eq.{id}`.

```bash
curl -X DELETE "https://api.bookingmood.com/v1/coupons?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: The deleted coupons with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.

## Update coupons

`PATCH /v1/coupons`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/he-IL/api-reference/filtering.md)). Without filters, this request updates all coupons you have access to. Always filter on at least one column, e.g. `id=eq.{id}`. The body holds the attributes to change.

```bash
curl -X PATCH "https://api.bookingmood.com/v1/coupons?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "SUMMER24"
  }'
```

Responses:

- `200`: The updated coupons with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

Errors have a JSON body with a `code`, `message`, `details` and `hint`. See the [introduction](https://www.bookingmood.com/he-IL/api-reference.md) for more on errors. The full API is described by the OpenAPI spec at https://api.bookingmood.com/v1/openapi.json.
