# Get all promo codes

`GET /api/configuration/promotion-codes`

- **Success:** `200 OK`
- **Products:** Operator (`FOH`)
- **Features:** Front of House Generic Access (`FOHGENERIC`)

HTML version: [Get all promo codes](https://support.gladstonesoftware.cloud/reference/configuration/get-all-promo-codes)

## Overview

Lists the promo codes defined for the tenant. A promo code is the string a customer types at checkout — for example `SUMMER25` — which the platform resolves to one or more discounts.

**By default this returns only codes whose `active` flag is set.** The `includeInactive` parameter switches that filter off. Read the note on that parameter carefully before you rely on it: it filters on the `active` flag and nothing else, so the default response still contains codes whose validity window has already closed.

This list is deliberately thin. It gives you the code, its window and its flag, and nothing more — there is no usage limit, no remaining-usage count, no auto-apply flag and no list of associated discounts, even though all of those exist on the promo code. To see any of that, call [Get promo code by ID or code](get-promo-code-by-id-or-code.md) for the individual code. Use this endpoint to discover which codes exist; use that one to find out what a code does.

The response is a JSON array. There is no paging and no ordering guarantee. When nothing matches you get `200` with `[]` — never `204` and never `404`. That includes the case where codes exist but all of them are inactive and you did not pass `includeInactive=true`, which is a distinct situation the response does not let you tell apart from having no codes at all.

`promoId` values are allocated per tenant. They are not stable across tenants or environments, and the same integer will mean a different code in a different installation. Codes themselves are unique within a tenant — the create endpoint rejects a duplicate — but are likewise not globally meaningful.

Switching `includeInactive` costs nothing. Creating or updating a promo code through this API is reflected here immediately; a change made any other way can take up to six hours to appear here.

## Endpoint

`GET {base_url}/api/configuration/promotion-codes`

`{base_url}` is the environment URL issued to your integration. See [Authenticating with Gladstone APIs](../../guides/authenticating-with-gladstone-apis.md).

## Query parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `includeInactive` | boolean | No | Controls whether deactivated codes are included. **It filters on the `active` flag only — it has nothing to do with dates.** Omit it, or send `false`, and you get just the codes where `active` is `true`; an expired code that is still flagged active is returned either way, and you must check `validTo` yourself. Send `true` to receive every code regardless of flag. The default is `false`. The value must parse as a boolean (`true`/`false`); anything else is rejected with a `400`. It does not add any extra fields to the response. |

## Sample request

```bash title="cURL"
curl -X GET '{base_url}/api/configuration/promotion-codes' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `[].promoId` | integer (int32) | The promo code's numeric identifier, assigned by Gladstone when the code is created. Tenant-local and not reused; it carries no meaning across environments, so never hardcode one. Pass it to [Get promo code by ID or code](get-promo-code-by-id-or-code.md) to retrieve the code's discounts, usage limits and auto-apply setting. That endpoint accepts either this integer or the `code` string, but a code string must be wrapped in curly braces — `/api/configuration/promotion-codes/{SUMMER25}` — or it is read as an id and rejected. |
| `[].code` | string | The string the customer enters to claim the promotion. Up to 25 characters, mandatory, and unique within the tenant — an attempt to create a second code with the same text is rejected as a conflict. Whitespace is not allowed anywhere in it. Case is kept as the operator entered it. |
| `[].validFrom` | string (date-time) | The first date on which the code can be used. The time is truncated to midnight, so the time portion is always zero and should be ignored. Codes created through this API always have a value, because the create endpoint requires one and rejects a date earlier than today; `null` is possible on codes created by other means and means the start of the window is unbounded. Not applied as a filter by this endpoint — a code whose window has not yet opened is still listed. |
| `[].validTo` | string (date-time) | The last date on which the code can be used, again truncated to midnight. Required on create, where it must be a future date and on or after `validFrom`; `null` is possible on codes created by other means and means the window has no end. **This endpoint never filters on it.** A code whose `validTo` has passed appears in the default response as long as `active` is still `true`, so if you are showing customers what they can redeem, compare this date yourself. |
| `[].active` | boolean | The operator's on/off switch for the code, independent of the dates. This is the only thing `includeInactive` filters on. It defaults to off, and a code with no value set is returned as `false` and is therefore hidden unless you pass `includeInactive=true`. `true` does not mean the code is currently redeemable — check `validFrom` and `validTo` as well. |

## Sample response

```json title="200 OK"
[
  {
    "promoId": 12345,
    "code": "string",
    "validFrom": "2026-08-14T19:00:00Z",
    "validTo": "2026-08-14T19:00:00Z",
    "active": true
  }
]
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `500` | Internal server error | Any unexpected server-side failure while reading the codes. The body is empty and carries no detail. Retry; no change to the request avoids it. |
