2 operations. Every schema and example on this page is generated from the platform contract.
Merchant promo codes for the Business-app promo-codes screen: every code for the store with its discount type, value, scope, redemption limits, active window, status and redemption count. Ordered newest first; archived codes are excluded unless include_archived is true.
Store whose promo codes to list (also authorises the merchant).
Include archived promo codes when 'true'. Archived rows are excluded by default.
truefalsepercentfixed_amountfree_itemfixed_priceactivepausedarchivedcurl -G "https://www.membber.com/api/v1/promo-codes" \
-H "Authorization: Bearer $MEMBBER_TOKEN" \
--data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066"import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.GET("/api/v1/promo-codes", {
params: { query: { store_id: "6659c139-0000-4000-8000-d0c500000066" } },
});
if (error) {
// Typed error envelope: { error: { code, message, requestId } }
throw new Error(`${error.error.code}: ${error.error.message}`);
}
console.log(data);import MembberSwift
let client = MembberClient(
serverURL: MembberClient.productionServerURL,
tokenProvider: { session.accessToken }
)
let response = try await client.api.listPromoCodes(
query: .init(storeId: "6659c139-0000-4000-8000-d0c500000066")
).ok.body.json
print(response){
"promo_codes": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"store_id": "6659c139-0000-4000-8000-d0c500000066",
"code": "EXAMPLE10",
"description": "Added at the front desk",
"discount_type": "percent",
"discount_value": 1,
"free_item_id": "494b4af4-0000-4000-8000-d0c500000049",
"applies_to": "<applies_to>",
"target_item_id": "a7f2b119-0000-4000-8000-d0c5000000a7",
"fixed_price_pence": 1500,
"min_spend_pence": 1500,
"max_redemptions": 1,
"per_customer_limit": 1,
"stackable_with_voucher": true,
"starts_at": "<starts_at>",
"expires_at": "<expires_at>",
"status": "active",
"redemption_count": 1,
"created_by": "<created_by>",
"created_at": "<created_at>",
"updated_at": "<updated_at>"
}
]
}Merchant creates a promo code from the Business-app promo-codes screen: discount type + value (or free item / fixed price), scope, min spend, redemption limits, voucher-stacking and active window. The service validates every field (code shape, discount coherence, free-item ownership, window sanity) and the unique index on lower(code) per store prevents a duplicate (returns CODE_EXISTS 409). Writes an admin audit row. Faithful migration of the legacy POST promo-codes.
Store the promo code belongs to (also authorises the merchant).
The promo code text (normalised + validated by the service).
Optional merchant-facing description.
The kind of discount this code applies.
percentfixed_amountfree_itemfixed_pricePercent (1-100) or pence, depending on discount_type. Ignored for free_item / fixed_price.
The store-owned menu item given free (free_item type only).
Discount scope: whole basket (default) or a single target item ('item').
basketitemThe store-owned menu item the discount targets (item scope only).
The pinned price in pence (fixed_price type only).
Minimum basket spend in pence for the code to apply.
Total redemptions allowed across all customers (null = unlimited).
Redemptions allowed per customer (null = no per-customer limit).
Whether this code can stack with a loyalty voucher.
ISO timestamp the code becomes active (null = immediately).
ISO timestamp the code expires (null = never).
Initial status (defaults to active in the DB when omitted).
activepausedarchivedpercentfixed_amountfree_itemfixed_priceactivepausedarchivedcurl -X POST "https://www.membber.com/api/v1/promo-codes" \
-H "Authorization: Bearer $MEMBBER_TOKEN" \
-H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
-H "Content-Type: application/json" \
-d '{
"store_id": "6659c139-0000-4000-8000-d0c500000066",
"code": "EXAMPLE10",
"discount_type": "percent"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/promo-codes", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
code: "EXAMPLE10",
discount_type: "percent"
},
headers: { "Idempotency-Key": crypto.randomUUID() },
});
if (error) {
// Typed error envelope: { error: { code, message, requestId } }
throw new Error(`${error.error.code}: ${error.error.message}`);
}
console.log(data);import MembberSwift
let client = MembberClient(
serverURL: MembberClient.productionServerURL,
tokenProvider: { session.accessToken }
)
let response = try await client.api.createPromoCode(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
code: "EXAMPLE10",
discountType: .percent
))
).ok.body.json
print(response){
"id": "00000d1b-0000-4000-8000-d0c500000000",
"store_id": "6659c139-0000-4000-8000-d0c500000066",
"code": "EXAMPLE10",
"description": "Added at the front desk",
"discount_type": "percent",
"discount_value": 1,
"free_item_id": "494b4af4-0000-4000-8000-d0c500000049",
"applies_to": "<applies_to>",
"target_item_id": "a7f2b119-0000-4000-8000-d0c5000000a7",
"fixed_price_pence": 1500,
"min_spend_pence": 1500,
"max_redemptions": 1,
"per_customer_limit": 1,
"stackable_with_voucher": true,
"starts_at": "<starts_at>",
"expires_at": "<expires_at>",
"status": "active",
"redemption_count": 1,
"created_by": "<created_by>",
"created_at": "<created_at>",
"updated_at": "<updated_at>"
}