3 operations. Every schema and example on this page is generated from the platform contract.
The REAL upcoming slots (reflecting recurrence + exceptions) for the Business "manage upcoming slots" surface. Read-only. Cancelling an occurrence is DELETE /api/v1/collection-windows.
Store whose upcoming slots to list (also authorises the merchant).
Horizon in days (default 14). The server shows at least the store’s full book-ahead window.
Store-local YYYY-MM-DD start of the window. Default: today.
Store-local YYYY-MM-DD end of the window (inclusive). Default: from + the horizon. Span clamped to 180 days.
Pass 'true' to merge in what the store's RULES would produce beyond the release horizon (origin='planned') plus occurrences the merchant closed (origin='cancelled'), and to fill in rule_max_orders/overridden on every row. Planned rows are never bookable. Default: materialised only.
truefalseYYYY-MM-DD.
HH:MM.
HH:MM.
Has at least one order → cannot be cancelled.
Day is hidden from customers (closing date-override OR a Closed/collect-off weekday).
Orders already holding a place in this slot. Real for capped AND uncapped slots.
The slot’s capacity, or null when the store runs this slot uncapped.
Places still free, or null when uncapped (no meaningful remainder).
'materialised' = a real, released slot. 'planned' = the store's rules WOULD produce it but the book-ahead horizon has not reached it, NOT bookable, it has no row. 'cancelled' = the merchant closed this one occurrence (present so the close can be undone).
materialisedplannedcancelledReal, released, open, not full, not a closed day. The one flag a merchant surface renders on.
Merchant stopped NEW orders for this occurrence. Orders already in it are untouched.
What the merchant’s RULE alone gives this slot ("usually 5"), so a per-slot override reads as a difference. null = the rule is uncapped. Only sent when include_planned=true.
This occurrence carries a per-slot override, i.e. there is something for "back to normal" to undo. Only sent when include_planned=true.
curl -G "https://www.membber.com/api/v1/collection-slots" \
-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/collection-slots", {
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.listCollectionSlots(
query: .init(storeId: "6659c139-0000-4000-8000-d0c500000066")
).ok.body.json
print(response){
"slots": [
{
"slot_date": "<slot_date>",
"start_time": "<start_time>",
"end_time": "<end_time>",
"booked": true,
"closed_day": true,
"booked_count": 1,
"max_orders": -9007199254740991,
"orders_remaining": -9007199254740991,
"origin": "materialised",
"bookable": true,
"paused": true,
"rule_max_orders": -9007199254740991,
"overridden": true
}
]
}The undo for setCollectionSlotOverride: removes the per-occurrence capacity/pause override and re-syncs the materialised slot to the rule. Never refuses, removing a constraint is always allowed, so when the rule’s cap sits below what is already booked the remainder clamps to 0 rather than blocking the undo. Idempotent. Inputs are supplied as query parameters.
Store that owns the occurrence (also authorises the merchant).
YYYY-MM-DD of the occurrence.
HH:MM start time of the occurrence.
The state of ONE collection occurrence after a write, enough to reconcile the row in place.
YYYY-MM-DD.
HH:MM.
HH:MM, or null when the occurrence has no rule to take it from.
Effective capacity for this occurrence; null = uncapped.
What the merchant’s rule alone gives it; null = the rule is uncapped.
false = taking new orders.
Orders already in it. REAL, never derived from a cap.
Is there anything for "back to normal" to undo?
Has the occurrence been released as a real, bookable row yet?
true when an override existed and was removed; false = nothing to undo (not an error).
curl -X DELETE "https://www.membber.com/api/v1/collection-slots/override?store_id=6659c139-0000-4000-8000-d0c500000066&slot_date=%3Cslot_date%3E&start_time=%3Cstart_time%3E" \
-H "Authorization: Bearer $MEMBBER_TOKEN" \
-H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678"import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.DELETE("/api/v1/collection-slots/override", {
params: { query: { store_id: "6659c139-0000-4000-8000-d0c500000066", slot_date: "<slot_date>", start_time: "<start_time>" } },
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.clearCollectionSlotOverride(
query: .init(storeId: "6659c139-0000-4000-8000-d0c500000066", slotDate: "<slot_date>", startTime: "<start_time>")
).ok.body.json
print(response){
"occurrence": {
"slot_date": "<slot_date>",
"start_time": "<start_time>",
"end_time": "<end_time>",
"max_orders": -9007199254740991,
"rule_max_orders": -9007199254740991,
"paused": true,
"booked_count": 1,
"overridden": true,
"materialised": true
},
"cleared": true
}Writes a durable per-occurrence override (store_collection_slot_overrides) that the slot generator re-applies every time slots are materialised, so it SURVIVES resync_collection_slots, which deletes and regenerates unbooked slots whenever any rule is edited. Pausing stops NEW orders only; orders already in the slot are untouched and the booking RPC answers a paused slot with its own code. Refuses with 409 SLOT_CAPACITY_BELOW_BOOKED (carrying the real booked count) rather than clamping when the new capacity is below what is already booked. Idempotent (last write wins on one row).
Store that owns the occurrence (also authorises the merchant).
YYYY-MM-DD of the occurrence.
HH:MM start time of the occurrence.
How this ONE occurrence's capacity behaves. 'inherit' = follow the rule again, 'unlimited' = take any number, 'fixed' = hold exactly max_orders. OMIT to leave the capacity exactly as it is.
inheritunlimitedfixedRequired when capacity_mode='fixed'. At least 1, 0 is not a capacity; to stop new orders, pause.
true = take no NEW orders (existing ones are untouched). OMIT to leave this facet as it is.
The state of ONE collection occurrence after a write, enough to reconcile the row in place.
YYYY-MM-DD.
HH:MM.
HH:MM, or null when the occurrence has no rule to take it from.
Effective capacity for this occurrence; null = uncapped.
What the merchant’s rule alone gives it; null = the rule is uncapped.
false = taking new orders.
Orders already in it. REAL, never derived from a cap.
Is there anything for "back to normal" to undo?
Has the occurrence been released as a real, bookable row yet?
curl -X PUT "https://www.membber.com/api/v1/collection-slots/override" \
-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",
"slot_date": "<slot_date>",
"start_time": "<start_time>"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.PUT("/api/v1/collection-slots/override", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
slot_date: "<slot_date>",
start_time: "<start_time>"
},
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.setCollectionSlotOverride(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
slotDate: "<slot_date>",
startTime: "<start_time>"
))
).ok.body.json
print(response){
"occurrence": {
"slot_date": "<slot_date>",
"start_time": "<start_time>",
"end_time": "<end_time>",
"max_orders": -9007199254740991,
"rule_max_orders": -9007199254740991,
"paused": true,
"booked_count": 1,
"overridden": true,
"materialised": true
}
}