> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autodetailcrm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get membership plans

> Fetch the membership plans a customer can sign up for during booking.

Returns the membership plans the business has made bookable, so your booking flow can offer a membership alongside the job. Plans are returned cheapest first.

```
GET /api/public/booking/{token}/memberships
```

<Warning>
  Unlike the config, availability, and submit endpoints, this one does **not** send `Access-Control-Allow-Origin`. A browser calling it cross-origin is blocked by CORS. Fetch the plans from your own server and pass them to your page, rather than calling this endpoint from the customer's browser.
</Warning>

## Path parameters

<ParamField path="token" type="string" required>
  Your booking page token — either the booking slug (**Settings → Booking Page**) or the lead token (**Settings → Website Leads**). See [Authentication & tokens](/api-reference/introduction#authentication--tokens).
</ParamField>

## Response

Returns `200 OK`.

<ResponseField name="plans" type="array">
  The bookable plans, ordered by price ascending. Empty when the business offers none.

  <Expandable title="Plan fields">
    <ResponseField name="id" type="number">Plan identifier. Use this when submitting a booking.</ResponseField>
    <ResponseField name="name" type="string">Plan display name.</ResponseField>
    <ResponseField name="description" type="string">What the plan includes, as written by the business.</ResponseField>
    <ResponseField name="price" type="number">Recurring price per billing interval.</ResponseField>
    <ResponseField name="billing_interval" type="string">How often the plan bills — for example `month`.</ResponseField>
    <ResponseField name="binding_type" type="string">What the membership attaches to — for example `customer` or `vehicle`.</ResponseField>
    <ResponseField name="discount_percent" type="number">Discount applied to services not individually listed on the plan.</ResponseField>

    <ResponseField name="membership_plan_services" type="array">
      The services included in the plan.

      <Expandable title="Included service fields">
        <ResponseField name="service_id" type="number">The included service.</ResponseField>
        <ResponseField name="usage_limit" type="number">How many times it's included per interval.</ResponseField>
        <ResponseField name="discount_percent" type="number">Discount on that service beyond the included uses.</ResponseField>
        <ResponseField name="services" type="object">The service record, containing its `name`.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="businessType" type="string">The workspace's business type.</ResponseField>
<ResponseField name="currency" type="string">Currency the prices are expressed in.</ResponseField>

<Note>
  Only plans that are active, marked bookable, and visible are returned. A plan the business sells privately won't appear here — that's deliberate, not a missing record.
</Note>

## Errors

| Status | Code            | Meaning                                          |
| ------ | --------------- | ------------------------------------------------ |
| `400`  | `invalid_token` | The token doesn't match `^[a-zA-Z0-9_-]{1,255}$` |
| `404`  | `not_found`     | The token doesn't resolve to a workspace         |

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl https://app.autodetailcrm.com/api/public/booking/your-booking-slug/memberships
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    `https://app.autodetailcrm.com/api/public/booking/${token}/memberships`
  );
  const { plans, currency } = await res.json();
  ```
</CodeGroup>
