2 operations. Every schema and example on this page is generated from the platform contract.
The composed customer mini-store read: branding, the purchasable/menu items with optimized media, hero carousel, open/closed status (store timezone), Order & Collect availability (entitlement-gated), loyalty contract, and policies. A was-live-now-closed or billing-dark store returns a kind "dark" blocking payload instead; a never-live store 404s (its owner can preview with ?preview=1 + a Business Bearer token).
Set to "1" (with a Business Bearer token) for the store owner to preview a not-yet-live store.
The live mini-store payload, or the compact contact card when blocked.
Present only when the store is served "dark".
Present only when blocked.
Support contact shown on the dark blocking screen.
Customer-facing copy for the dark blocking screen.
curl -G "https://www.membber.com/api/v1/stores/8fb04ddc-0000-4000-8000-d0c50000008f"import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.GET("/api/v1/stores/{storeId}", {
params: { path: { storeId: "8fb04ddc-0000-4000-8000-d0c50000008f" } },
});
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.getStoreDetail(
path: .init(storeId: "8fb04ddc-0000-4000-8000-d0c50000008f")
).ok.body.json
print(response){
"store": {},
"blocked": true,
"served_state": "<served_state>",
"support_email": "alex@example.com",
"message": "Added at the front desk"
}Public, pre-login store discovery for the customer app: live, non-test stores with optional text search, nearby distance sort (Haversine when lat/lng are supplied), template / category filters, and keyset pagination. Only publicly displayable fields are returned, never PII or secrets.
Text search (>= 2 chars; otherwise browse-all).
Customer latitude, enables distance sort when paired with lng.
Customer longitude, enables distance sort when paired with lat.
Filter by store template (standard | gym); other values are ignored.
Filter by store_category.
Keyset cursor from the previous page (nextCursor).
Page size (default 30, hard-capped at 50).
curl -G "https://www.membber.com/api/v1/stores/discover"import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.GET("/api/v1/stores/discover");
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.discoverStores().ok.body.json
print(response){
"nextCursor": "<nextCursor>",
"stores": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"code": "EXAMPLE10",
"name": "Example name",
"description": "Added at the front desk",
"store_template": "<store_template>",
"store_category": "<store_category>",
"logo_url": "https://example.com/image.jpg",
"logo_blurhash": "<logo_blurhash>",
"brand_color": "<brand_color>",
"accent_color": "<accent_color>",
"primary_color": "<primary_color>",
"secondary_color": "<secondary_color>",
"address": "<address>",
"latitude": 1,
"longitude": 1,
"distance_m": 1,
"goal": 1,
"earned_voucher_title": "<earned_voucher_title>"
}
]
}