Endpoints for managing membership programs including tiers, billing, credits, family plans, organizations, public enrollment, and the member portal.
Memberships
Get all memberships
GET /memberships
Retrieves all memberships for a customer with pagination and optional status filtering
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerId | query | string | Yes | The customer ID |
status | query | string | No | Filter by membership status |
tierId | query | string | No | Filter by tier ID |
page | query | integer | No | Page number |
limit | query | integer | No | Items per page |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved memberships |
400 | customerId is required |
500 | Server error |
Create a new membership
POST /memberships
Creates a new membership (staff-created). Can optionally create a new renter.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
tierId | string | Yes | |
memberType | string | No | |
memberId | string | No | |
renterId | string | No | Alias for memberId |
memberEmail | string | Yes | |
memberName | string | No | |
memberPhone | string | No | |
billingCycle | string | No | |
staffId | string | No | |
notes | string | No | |
createRenter | boolean | No | Create a new renter if true |
firstName | string | No | |
lastName | string | No |
Responses
| Code | Description |
|---|---|
201 | Membership created successfully |
400 | Missing required fields or member already has active membership |
404 | Tier not found |
500 | Server error |
Get a specific membership
GET /memberships/{membershipId}
Retrieves a specific membership with full details including tier and renter info
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved membership |
400 | customerId is required |
404 | Membership not found |
500 | Server error |
Cancel a membership
POST /memberships/{membershipId}/cancel
Cancels a membership. Can cancel immediately or at period end.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
cancelImmediately | boolean | No | If true, cancels immediately. Otherwise cancels at period end. |
Responses
| Code | Description |
|---|---|
200 | Membership canceled or scheduled for cancellation |
400 | customerId is required |
404 | Membership not found |
500 | Server error |
Reactivate a canceled membership
POST /memberships/{membershipId}/reactivate
Reactivates a membership that was canceled
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes |
Responses
| Code | Description |
|---|---|
200 | Membership reactivated |
400 | customerId is required |
500 | Server error |
Pause a membership
POST /memberships/{membershipId}/pause
Pauses a membership. Staff can use force=true to bypass tier policy restrictions.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
resumeAt | string | No | Optional date to auto-resume |
force | boolean | No | Bypass tier pause policy restrictions |
Responses
| Code | Description |
|---|---|
200 | Membership paused |
400 | customerId is required or pause not enabled or max pauses reached |
404 | Membership not found |
500 | Server error |
Resume a paused membership
POST /memberships/{membershipId}/resume
Resumes a membership that was paused
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes |
Responses
| Code | Description |
|---|---|
200 | Membership resumed |
400 | customerId is required or membership is not paused |
404 | Membership not found |
500 | Server error |
Get Stripe invoices and billing history for a membership
GET /memberships/{membershipId}/invoices
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | |
customerId | query | string | Yes | |
limit | query | integer | No |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved invoices and billing history |
400 | customerId is required |
404 | Membership not found |
Memberships - Billing
Add a free month to membership
POST /memberships/{membershipId}/billing/add-free-month
Extends the current period end date by one billing cycle without charging
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
reason | string | No | Reason for adding free month (for audit purposes) |
Responses
| Code | Description |
|---|---|
200 | Free month added successfully |
400 | customerId is required |
404 | Membership not found |
500 | Server error |
Change billing date
POST /memberships/{membershipId}/billing/change-date
Changes the billing date by updating the current period end
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
newBillingDate | string | Yes | New billing date (must be in the future) |
proRate | boolean | No | Whether to pro-rate the price difference |
reason | string | No |
Responses
| Code | Description |
|---|---|
200 | Billing date changed successfully |
400 | Invalid request |
404 | Membership not found |
500 | Server error |
Switch billing cycle
POST /memberships/{membershipId}/billing/switch-cycle
Switches between monthly and yearly billing cycles with pro-rating
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
newBillingCycle | string | Yes | |
proRate | boolean | No |
Responses
| Code | Description |
|---|---|
200 | Billing cycle switched successfully |
400 | Invalid request |
404 | Membership not found |
500 | Server error |
Change membership price
POST /memberships/{membershipId}/billing/change-price
Changes the recurring price for an individual membership
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
newPrice | number | Yes | New price in cents |
proRate | boolean | No | |
reason | string | No |
Responses
| Code | Description |
|---|---|
200 | Price changed successfully |
400 | Invalid request |
404 | Membership not found |
500 | Server error |
Refund a membership invoice payment
POST /memberships/{membershipId}/refund
Resend a membership invoice receipt email
POST /memberships/{membershipId}/invoices/{invoiceId}/resend
Memberships - Credits
Get credit balance and history
GET /memberships/{membershipId}/credits
Retrieves the credit balance and transaction history for a membership
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
customerId | query | string | Yes | The customer ID |
limit | query | integer | No | Number of history entries to return |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved credits |
400 | customerId is required |
404 | Membership not found |
500 | Server error |
Adjust membership credits
POST /memberships/{membershipId}/credits/adjust
Manual credit adjustment for a membership (staff only)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
amount | number | Yes | Positive to add, negative to deduct |
description | string | Yes | Reason for the adjustment |
staffId | string | No |
Responses
| Code | Description |
|---|---|
200 | Credit adjustment successful |
400 | Missing required fields or would result in negative balance |
404 | Membership not found |
500 | Server error |
Memberships - Family
Add a family member
POST /memberships/{membershipId}/family
Adds a family member to a membership
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
renterId | string | Yes | |
name | string | No | |
email | string | Yes |
Responses
| Code | Description |
|---|---|
200 | Family member added |
400 | Missing required fields or family members not enabled or max reached or already a member |
404 | Membership not found |
500 | Server error |
Remove a family member
DELETE /memberships/{membershipId}/family/{renterId}
Removes a family member from a membership
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
membershipId | path | string | Yes | The membership ID |
renterId | path | string | Yes | The renter ID to remove |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Family member removed |
400 | customerId is required |
404 | Membership not found or renter not a family member |
500 | Server error |
Memberships - Organizations
Get all organizations
GET /memberships/organizations
Retrieves all organizations for a customer
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved organizations |
400 | customerId is required |
500 | Server error |
Create an organization
POST /memberships/organizations
Creates a new organization for membership purposes
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
name | string | Yes | |
contactEmail | string | Yes | |
contactName | string | Yes | |
contactPhone | string | No | |
billingAddress | object | No | |
maxAuthorizedRenters | integer | No |
Responses
| Code | Description |
|---|---|
201 | Organization created successfully |
400 | Missing required fields |
500 | Server error |
Get organization by ID
GET /memberships/organizations/{orgId}
Retrieves a specific organization with its membership details
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved organization |
400 | customerId is required |
404 | Organization not found |
500 | Server error |
Update an organization
PATCH /memberships/organizations/{orgId}
Updates an existing organization's details
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
name | string | No | |
contactEmail | string | No | |
contactName | string | No | |
contactPhone | string | No | |
billingAddress | object | No | |
maxAuthorizedRenters | integer | No |
Responses
| Code | Description |
|---|---|
200 | Organization updated successfully |
400 | customerId is required |
500 | Server error |
Delete an organization
DELETE /memberships/organizations/{orgId}
Deletes an organization. Cannot delete if organization has an active membership.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Organization deleted successfully |
400 | customerId is required or organization has active membership |
500 | Server error |
Add authorized renter to organization
POST /memberships/organizations/{orgId}/members
Adds a renter to the organization's authorized renters list
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
renterId | string | Yes |
Responses
| Code | Description |
|---|---|
200 | Renter added to organization |
400 | Missing required fields or renter already authorized or max limit reached |
404 | Organization not found |
500 | Server error |
Get authorized renters for organization
GET /memberships/organizations/{orgId}/members
Retrieves all authorized renters for an organization with their details
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved members |
400 | customerId is required |
404 | Organization not found |
500 | Server error |
Remove authorized renter from organization
DELETE /memberships/organizations/{orgId}/members/{renterId}
Removes a renter from the organization's authorized renters list
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
renterId | path | string | Yes | The renter ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Renter removed from organization |
400 | customerId is required |
404 | Organization or renter not found |
500 | Server error |
Create membership for organization
POST /memberships/organizations/{orgId}/membership
Creates a membership for an organization
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
orgId | path | string | Yes | The organization ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
tierId | string | Yes | |
billingCycle | string | Yes |
Responses
| Code | Description |
|---|---|
201 | Membership created successfully |
400 | Missing required fields or tier doesn't support organizations or org already has membership |
404 | Organization or tier not found |
500 | Server error |
Memberships - Tiers
Get all membership tiers
GET /memberships/tiers
Retrieves all membership tiers for a customer, optionally filtered by active status
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerId | query | string | Yes | The customer ID |
activeOnly | query | boolean | No | Only return active tiers |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved tiers |
400 | customerId is required |
500 | Server error |
Create a new membership tier
POST /memberships/tiers
Creates a new membership tier with pricing and benefits
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
name | string | Yes | |
description | string | No | |
scope | string | No | |
locationIds | array | No | |
pricing | object | No | |
benefits | object | No | |
pausePolicy | object | No | |
familyOptions | object | No | |
allowedMemberTypes | array | No | |
displayOrder | integer | No |
Responses
| Code | Description |
|---|---|
201 | Tier created successfully |
400 | customerId and name are required |
500 | Server error |
Get a specific membership tier
GET /memberships/tiers/{tierId}
Retrieves a specific membership tier by ID
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tierId | path | string | Yes | The tier ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved tier |
400 | customerId is required |
404 | Tier not found |
500 | Server error |
Update a membership tier
PATCH /memberships/tiers/{tierId}
Updates an existing membership tier
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tierId | path | string | Yes | The tier ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
name | string | No | |
description | string | No | |
isActive | boolean | No | |
displayOrder | integer | No | |
pricing | object | No | |
benefits | object | No | |
pausePolicy | object | No | |
familyOptions | object | No |
Responses
| Code | Description |
|---|---|
200 | Tier updated successfully |
400 | customerId is required or no valid fields to update |
500 | Server error |
Deactivate a membership tier
DELETE /memberships/tiers/{tierId}
Soft-deletes (deactivates) a membership tier. Cannot delete if tier has active memberships.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tierId | path | string | Yes | The tier ID |
customerId | query | string | Yes | The customer ID |
Responses
| Code | Description |
|---|---|
200 | Tier deactivated successfully |
400 | customerId is required or tier has active memberships |
500 | Server error |
Memberships - Public
Get public membership tiers for a location
GET /memberships/public/tiers/{locationId}
Retrieves active membership tiers for a location (no authentication required)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
locationId | path | string | Yes | The location ID |
Responses
| Code | Description |
|---|---|
200 | Successfully retrieved tiers |
404 | Location not found |
500 | Server error |
Create checkout session for membership signup
POST /memberships/public/checkout
Creates a Stripe checkout session for membership signup. If renter has existing payment method, creates subscription directly.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | |
tierId | string | Yes | |
billingCycle | string | Yes | |
renterEmail | string | Yes | |
renterName | string | No | |
renterPhone | string | No | |
renterId | string | No | Optional existing renter ID |
successUrl | string | No | |
cancelUrl | string | No |
Responses
| Code | Description |
|---|---|
200 | Checkout session or subscription created |
400 | Missing required fields or Stripe not configured |
404 | Tier or location not found |
500 | Server error |
Check membership signup status
GET /memberships/public/status/{sessionId}
Check the status of a membership signup by checkout session ID
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionId | path | string | Yes | The Stripe checkout session ID |
Responses
| Code | Description |
|---|---|
200 | Membership status retrieved |
404 | Membership not found |
500 | Server error |
Member Portal
Get membership details
GET /portal/membership
Returns the current member's membership details, credits balance, tier information, and business info. Requires OTP session authentication.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Responses
| Code | Description |
|---|---|
200 | Membership details retrieved successfully |
401 | Unauthorized - invalid or missing OTP session |
404 | Membership not found |
500 | Internal server error |
Get credit transaction history
GET /portal/membership/credits
Returns the member's credit transaction history, sorted by most recent first
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
limit | query | integer | No | Maximum number of transactions to return |
Responses
| Code | Description |
|---|---|
200 | Credit transactions retrieved successfully |
401 | Unauthorized - invalid or missing OTP session |
500 | Internal server error |
Pause membership
POST /portal/membership/pause
Pauses the member's subscription if the tier's pause policy allows it. Pauses the Stripe subscription collection.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Responses
| Code | Description |
|---|---|
200 | Membership paused successfully |
400 | Pausing not allowed or membership not active |
401 | Unauthorized - invalid or missing OTP session |
404 | Membership not found |
500 | Internal server error |
Resume paused membership
POST /portal/membership/resume
Resumes a paused membership and reactivates Stripe subscription collection
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Responses
| Code | Description |
|---|---|
200 | Membership resumed successfully |
400 | Membership is not paused |
401 | Unauthorized - invalid or missing OTP session |
404 | Membership not found |
500 | Internal server error |
Cancel membership
POST /portal/membership/cancel
Schedules the membership for cancellation at the end of the current billing period. Respects minimum commitment periods.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Optional cancellation reason |
Responses
| Code | Description |
|---|---|
200 | Membership scheduled for cancellation |
400 | Cancellation not allowed, already canceled, or minimum commitment not met |
401 | Unauthorized - invalid or missing OTP session |
404 | Membership not found |
500 | Internal server error |
Get payment management link
GET /portal/membership/payment
Returns a Stripe Customer Portal URL where the member can update their payment method
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Responses
| Code | Description |
|---|---|
200 | Portal URL generated successfully |
400 | No payment information found or payment management unavailable |
401 | Unauthorized - invalid or missing OTP session |
500 | Internal server error |
Get member's bookings
GET /portal/bookings
Returns the member's booking history with optional filtering by status
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
limit | query | integer | No | Maximum number of bookings to return |
status | query | string | No | Filter bookings by status |
Responses
| Code | Description |
|---|---|
200 | Bookings retrieved successfully |
401 | Unauthorized - invalid or missing OTP session |
500 | Internal server error |
Get booking details
GET /portal/bookings/{rentalId}
Returns detailed information about a specific booking
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
rentalId | path | string | Yes | The booking rental ID |
Responses
| Code | Description |
|---|---|
200 | Booking details retrieved successfully |
401 | Unauthorized - invalid or missing OTP session |
403 | Access denied - booking belongs to different member |
404 | Booking not found |
500 | Internal server error |
Get saved payment methods
GET /portal/payment-methods
Returns the member's saved payment methods (credit cards) from Stripe
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
x-otp-session | header | string | Yes | OTP session token |
Responses
| Code | Description |
|---|---|
200 | Payment methods retrieved successfully |
401 | Unauthorized - invalid or missing OTP session |
500 | Internal server error |

