8 operations. Every schema and example on this page is generated from the platform contract.
Identical semantics to the merchant commit (no contact, no charges, 7-day undo).
curl -X POST "https://www.membber.com/api/v1/admin-import/commit" \
-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",
"job_id": "bb2be0dd-0000-4000-8000-d0c5000000bb"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/commit", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
job_id: "bb2be0dd-0000-4000-8000-d0c5000000bb"
},
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.adminImportCommit(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
jobId: "bb2be0dd-0000-4000-8000-d0c5000000bb"
))
).ok.body.json
print(response){
"started": true
}Same wave guards as the merchant button; audit records the admin.
initialreminderreminder2curl -X POST "https://www.membber.com/api/v1/admin-import/invites" \
-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",
"job_id": "bb2be0dd-0000-4000-8000-d0c5000000bb",
"wave": "initial"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/invites", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
job_id: "bb2be0dd-0000-4000-8000-d0c5000000bb",
wave: "initial"
},
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.adminImportInvites(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
jobId: "bb2be0dd-0000-4000-8000-d0c5000000bb",
wave: .initial
))
).ok.body.json
print(response){
"sent": 1,
"already_claimed": 1,
"no_email": 1,
"failed": 1
}Job state + the store’s active gym plans for mapping.
draftparsingmappedpreviewedimportingdonefailedundoneclientsautopayspassesvisitsmapcreateskipRe-card funnel, present once the import is committed.
curl -G "https://www.membber.com/api/v1/admin-import/jobs" \
-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/admin-import/jobs", {
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.adminImportGetJob(
query: .init(storeId: "6659c139-0000-4000-8000-d0c500000066")
).ok.body.json
print(response){
"state": {
"job": {
"id": "00000d1b-0000-4000-8000-d0c500000000",
"store_id": "6659c139-0000-4000-8000-d0c500000066",
"source": "<source>",
"status": "draft",
"counts": {},
"dry_run_report": {},
"committed_at": "<committed_at>",
"undo_deadline": "<undo_deadline>",
"created_at": "<created_at>"
},
"files": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"kind": "clients",
"original_name": "<original_name>",
"row_count": 1,
"created_at": "<created_at>"
}
],
"plan_matches": [
{
"source_name": "<source_name>",
"action": "map",
"matched_plan_id": "1c4475d6-0000-4000-8000-d0c50000001c"
}
],
"progress": {
"total": 1,
"done": 1,
"counts": {}
},
"funnel": {
"imported_members": 1,
"claimed": 1,
"active_billing": 1,
"awaiting": 1,
"monthly_value_pence": 1500,
"invites": {
"initial_at": "<initial_at>",
"initial_sent": 1,
"reminder_at": "<reminder_at>",
"reminder_sent": 1,
"reminder2_at": "<reminder2_at>",
"reminder2_sent": 1
}
}
},
"plans": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"name": "Example name",
"price_pence": 1500,
"billing_cycle": "<billing_cycle>"
}
]
}Creates or resumes the draft job with acting_admin_id recorded.
draftparsingmappedpreviewedimportingdonefailedundoneclientsautopayspassesvisitsmapcreateskipRe-card funnel, present once the import is committed.
curl -X POST "https://www.membber.com/api/v1/admin-import/jobs" \
-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"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/jobs", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066"
},
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.adminImportCreateJob(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066"
))
).ok.body.json
print(response){
"state": {
"job": {
"id": "00000d1b-0000-4000-8000-d0c500000000",
"store_id": "6659c139-0000-4000-8000-d0c500000066",
"source": "<source>",
"status": "draft",
"counts": {},
"dry_run_report": {},
"committed_at": "<committed_at>",
"undo_deadline": "<undo_deadline>",
"created_at": "<created_at>"
},
"files": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"kind": "clients",
"original_name": "<original_name>",
"row_count": 1,
"created_at": "<created_at>"
}
],
"plan_matches": [
{
"source_name": "<source_name>",
"action": "map",
"matched_plan_id": "1c4475d6-0000-4000-8000-d0c50000001c"
}
],
"progress": {
"total": 1,
"done": 1,
"counts": {}
},
"funnel": {
"imported_members": 1,
"claimed": 1,
"active_billing": 1,
"awaiting": 1,
"monthly_value_pence": 1500,
"invites": {
"initial_at": "<initial_at>",
"initial_sent": 1,
"reminder_at": "<reminder_at>",
"reminder_sent": 1,
"reminder2_at": "<reminder2_at>",
"reminder2_sent": 1
}
}
},
"plans": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"name": "Example name",
"price_pence": 1500,
"billing_cycle": "<billing_cycle>"
}
]
}Idempotent upsert; decided_by records the admin.
mapskipcurl -X POST "https://www.membber.com/api/v1/admin-import/plan-match" \
-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",
"job_id": "bb2be0dd-0000-4000-8000-d0c5000000bb",
"source_name": "<source_name>",
"action": "map",
"plan_id": "e28fa9f1-0000-4000-8000-d0c5000000e2"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/plan-match", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
job_id: "bb2be0dd-0000-4000-8000-d0c5000000bb",
source_name: "<source_name>",
action: "map",
plan_id: "e28fa9f1-0000-4000-8000-d0c5000000e2"
},
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.adminImportPlanMatch(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
jobId: "bb2be0dd-0000-4000-8000-d0c5000000bb",
sourceName: "<source_name>",
action: .map,
planId: "e28fa9f1-0000-4000-8000-d0c5000000e2"
))
).ok.body.json
print(response){
"ok": true
}Internal-admin store picker for the white-glove import.
Name/code search; empty lists recent gym stores.
curl -G "https://www.membber.com/api/v1/admin-import/stores" \
-H "Authorization: Bearer $MEMBBER_TOKEN"import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.GET("/api/v1/admin-import/stores");
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.adminImportStores().ok.body.json
print(response){
"stores": [
{
"id": "00000d1b-0000-4000-8000-d0c500000000",
"name": "Example name",
"code": "EXAMPLE10",
"store_template": "<store_template>",
"is_test": true,
"status": "<status>"
}
]
}Same protections as the merchant undo (claimed members kept).
curl -X POST "https://www.membber.com/api/v1/admin-import/undo" \
-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",
"job_id": "bb2be0dd-0000-4000-8000-d0c5000000bb"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/undo", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
job_id: "bb2be0dd-0000-4000-8000-d0c5000000bb"
},
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.adminImportUndo(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
jobId: "bb2be0dd-0000-4000-8000-d0c5000000bb"
))
).ok.body.json
print(response){
"ok": true,
"deleted": 1,
"kept": 1
}Same staging pipeline as the merchant wizard; nothing written live.
clientsautopayspassesvisitsclientsautopayspassesvisitsclientsautopayspassesvisitscurl -X POST "https://www.membber.com/api/v1/admin-import/upload" \
-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",
"file_name": "<file_name>",
"content": "<content>"
}'import { createMembberClient } from "@membber/sdk-ts";
const membber = createMembberClient({
getAccessToken: () => process.env.MEMBBER_TOKEN,
});
const { data, error } = await membber.raw.POST("/api/v1/admin-import/upload", {
body: {
store_id: "6659c139-0000-4000-8000-d0c500000066",
file_name: "<file_name>",
content: "<content>"
},
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.adminImportUpload(
body: .json(.init(
storeId: "6659c139-0000-4000-8000-d0c500000066",
fileName: "<file_name>",
content: "<content>"
))
).ok.body.json
print(response){
"job_id": "bb2be0dd-0000-4000-8000-d0c5000000bb",
"kind": "clients",
"summary": {
"kind": "clients",
"total": 1,
"valid": 1,
"warnings": 1,
"errors": 1,
"issue_counts": {}
}
}