DMCCA required API updates

Updates to the API calls to provide information required for DMCCA regulations.

For customers using our APIs to build their own member joining journey, or membership cancellation flow, these are the updates to our endpoints that will provide required information according to the legislation. This will be organised by updates information for: Invitation to purchase, pre-contract information, and cancellations.

This guide currently covers invitation to purchase and self-service cancellation. Pre-contract information will be added when it is available.

Invitation to purchase

An invitation to purchase is any stage where you provide the details and price of a membership and ask the consumer to take a step towards purchasing.

You must provide the following detail on any page with an invitation to purchase:

This information is fully available now through APIs: main characteristics of the product, identity of the trader, and business email address.

This information is partially available: total price, existence of the right to cancel.

Information which is coming soon: business or service address, remaining parts of the total price and right to cancel.

Main characteristics of the product

In Go Join we retrieve the main characteristics of the product from the membership type tag description under the Membership Facilities tag group. This gives a description of the type of membership available they are purchasing.

Use the POST/api/memberships/membership-types-by-tag-group to retrieve the membership types, the tag groups they are available in, and their description.

Use groupTag.description for the main characteristics of the product.

[
    {
        "groupTag": {
            "id": 11,
            "key": "Premium",
            "name": "Premium",

            "description": "Unlimited Access to our up-to-date gyms.",
            "sortOrder": 4,
            "isSecondary": false,
            "translations": []
        },
        "membershipTypes": [
            {
                "id": "SSUBRC0001",
                "description": "Premium Adult R C P",
                "applyToLinks": false,
                "minAge": null,
                "maxAge": null,
                "imageUrl": null,
                "minimumContractLength": {
                    "length": 12,
                    "lengthType": "Monthly",
                    "periodType": "ByPayment"
                },
                "renewal": null,
                "priceLevelId": "ADULT",
                "prices": {
                    "headlinePrice": {
                        "amount": "30.00",
                        "currency": "GBP",
                        "discount": null
                    },
                    "startUpFee": {
                        "amount": "0.00",
                        "currency": "GBP",
                        "discount": null
                    }
                },
                "tagGroups": [],
                "translations": []
            }
        ]
    }
]

Total price of the product

The total price of the product is calculated using the regular recurring price, the minimum contract term, and the pay now price.

For a recurring membership in Go Join we display the recurring price, the minimum number of payments, and the pay now price (if different from the recurring price) with details of what that includes, e.g. one-off fee and/or pro-rata month.

For a cash membership we simply display the total price including any one-off fees.

Details required to display the total price are provided in the POST/api/memberships/membership-types-by-tag-group and POST /api/pricing/memberships endpoints.

This portal does not yet publish a reference page for POST /api/pricing/memberships. The examples below show the pricing fields used by this guide, but the endpoint reference still needs source confirmation before publication.

The POST/api/memberships/membership-types-by-tag-group call provides the minimum contract term in the membership types object. This allows you to display the total number of months the member will be contracted to pay for along with the prices in the following call.

Use membershipTypes[].minimumContractLength for the number of payments required by the contract.

[
    {
        "groupTag": {
            "id": 11,
            "key": "Premium",
            "name": "Premium",
            "description": "Unlimited Access to our up-to-date gyms.",
            "sortOrder": 4,
            "isSecondary": false,
            "translations": []
        },
        "membershipTypes": [
            {
                "id": "SSUBRC0001",
                "description": "Premium Adult R C P",
                "applyToLinks": false,
                "minAge": null,
                "maxAge": null,
                "imageUrl": null,

                "minimumContractLength": {
                    "length": 12,
                    "lengthType": "Monthly",
                    "periodType": "ByPayment"
                },
                "renewal": null,
                "priceLevelId": "ADULT",
                "prices": {
                    "headlinePrice": {
                        "amount": "30.00",
                        "currency": "GBP",
                        "discount": null
                    },
                    "startUpFee": {
                        "amount": "0.00",
                        "currency": "GBP",
                        "discount": null
                    }
                },
                "tagGroups": [],
                "translations": []
            }
        ]
    }
]

The POST/api/pricing/memberships call provides the pricing information. This should be gathered from the membership object rather than the overview to ensure it's specific to the membership type.

Use memberships[].pricing.now.totalPrice for the amount to pay today. Use memberships[].pricing.now.breakdown[] for the payment types included today, such as regular, pro-rata or one-off payments. Use memberships[].pricing.recurring for the amount and frequency of recurring payments.

{
    "siteId": "WEST",
    "promotionCode": null,
    "overview": {},
    "memberships": [
        {
            "orderKey": 1,
            "id": "AD45A-RCP1",
            "description": "O/p Adu All Rcp",
            "coolingOffPeriod": 14,
            "translations": [
                {
                    "type": "name",
                    "culture": "cy-gb",
                    "text": "O/p Adu All Rcp WelshName"
                }
            ],
            "startDate": "2027-01-14T00:00:00Z",
            "endDate": "2027-02-13T00:00:00Z",
            "pricing": {

                "now": {
                    "totalPrice": {
                        "amount": "26.00",
                        "currency": "GBP",
                        "discount": null
                    },

                    "breakdown": [
                        {
                            "priceLevelId": "STAND",
                            "productId": "AD45A-RCP1",
                            "type": "regular",
                            "description": "O/p Adu All Rcp",
                            "translations": [],
                            "price": {
                                "amount": "25.00",
                                "currency": "GBP",
                                "discount": null
                            }
                        },
                        {
                            "priceLevelId": "STAND",
                            "productId": "ADMIN-15",
                            "type": "one-off",
                            "description": "Joining Fee",
                            "translations": [],
                            "price": {
                                "amount": "1.00",
                                "currency": "GBP",
                                "discount": null
                            }
                        }
                    ]
                },

                "recurring": {
                    "membershipId": null,
                    "headlinePrice": {
                        "amount": "25.00",
                        "currency": "GBP",
                        "discount": null
                    },
                    "frequency": "Monthly"
                }
            }
        }
    ],
    "timeStamp": "2026-01-26T09:43:21.0005666Z",
    "signature": "Avl79+nY/tLsR6JbnShgao6gD2wXzzs00vL9XOvLBQZ2KumdQbT3Q/mfo1Fs+qHQXdRIjTI8PK4EaOKdC5Ddsw=="
}

Existence of the right to cancel

You must inform the member if they have a right to cancel during the invitation to purchase. You do not need to provide details of how to cancel as that is done at a later stage.

There are two types of cancellation rights for memberships:

  1. During the cooling-off period - Any membership can be cancelled during the cooling off period if it exists. The DMCCA will enforce a minimum 14 day cancellation period.
    E.g. an annual up-front membership.
  2. Once any minimum term is complete for an auto-renewing membership - This applies to any recurring membership.
    E.g. a monthly membership with or without a minimum term.

Due to this, we have two values to check in endpoints to confirm whether any right to cancel exists. In Go Join we also clarify whether this is only during the cooling-off period or additional after any minimum period.

The POST/api/pricing/memberships call provides the cooling-off period in the membership object to indicate whether the selected membership has a cooling off period during which the membership can be cancelled. It also provides whether the membership is auto-renewing or a recurring membership; this indicates whether it can be cancelled after the cooling off period or if it will end on its own and therefore does not need to be cancelled.

Use memberships[].coolingOffPeriod for the cooling-off period. Use memberships[].pricing.recurring to identify whether the membership is auto-renewing or up-front only.

{
    "siteId": "WEST",
    "promotionCode": null,
    "overview": {},
    "memberships": [
        {
            "orderKey": 1,
            "id": "AD45A-RCP1",
          	"description": "O/p Adu All Rcp",

            "coolingOffPeriod": 14,
            "translations": [
                {
                    "type": "name",
                    "culture": "cy-gb",
                    "text": "O/p Adu All Rcp WelshName"
                }
            ],
            "startDate": "2027-01-14T00:00:00Z",
            "endDate": "2027-02-13T00:00:00Z",
            "pricing": {
                "now": {
                    "totalPrice": {
                        "amount": "26.00",
                        "currency": "GBP",
                        "discount": null
                    },
                  "breakdown": [
                        {
                            "priceLevelId": "STAND",
                            "productId": "AD45A-RCP1",
                            "type": "regular",
                            "description": "O/p Adu All Rcp",
                            "translations": [],
                            "price": {
                                "amount": "25.00",
                                "currency": "GBP",
                                "discount": null
                            }
                        },
                        {
                            "priceLevelId": "STAND",
                            "productId": "ADMIN-15",
                            "type": "one-off",
                            "description": "Joining Fee",
                            "translations": [],
                            "price": {
                                "amount": "1.00",
                                "currency": "GBP",
                                "discount": null
                            }
                        }
                    ]
                },

                "recurring": {
                    "membershipId": null,
                    "headlinePrice": {
                        "amount": "25.00",
                        "currency": "GBP",
                        "discount": null
                    },
                    "frequency": "Monthly"
                }
            }
        }
    ],
    "timeStamp": "2026-01-26T09:43:21.0005666Z",
    "signature": "Avl79+nY/tLsR6JbnShgao6gD2wXzzs00vL9XOvLBQZ2KumdQbT3Q/mfo1Fs+qHQXdRIjTI8PK4EaOKdC5Ddsw=="
}

Optional

The POST/api/memberships/membership-types-by-tag-group call provides the minimum contract term. This is optional to include when the membership can be cancelled if there is a right and there is a minimum term. In Go Join, we let members know that they can cancel after the minimum term if it exists.

Use membershipTypes[].minimumContractLength to identify the period after which a member can cancel.

[
    {
        "groupTag": {
            "id": 11,
            "key": "Premium",
            "name": "Premium",
            "description": "Unlimited Access to our up-to-date gyms.",
            "sortOrder": 4,
            "isSecondary": false,
            "translations": []
        },
        "membershipTypes": [
            {
                "id": "SSUBRC0001",
                "description": "Premium Adult R C P",
                "applyToLinks": false,
                "minAge": null,
                "maxAge": null,
                "imageUrl": null,

                "minimumContractLength": {
                    "length": 12,
                    "lengthType": "Monthly",
                    "periodType": "ByPayment"
                },
                "renewal": null,
                "priceLevelId": "ADULT",
                "prices": {
                    "headlinePrice": {
                        "amount": "30.00",
                        "currency": "GBP",
                        "discount": null
                    },
                    "startUpFee": {
                        "amount": "0.00",
                        "currency": "GBP",
                        "discount": null
                    }
                },
                "tagGroups": [],
                "translations": []
            }
        ]
    }
]

Trader details

All of these details are or will be available using the GET/api/configuration/system/groups call. Here are the details mapped to the groups to pass into the call and the unique config key to identify them.

Trader detailConfig KeyGroup
Identity of the trader"Operator_TradingName"13
Business email address"Join_HelpEmail"11
Business or service address"Join_BusinessAddress"11

Cancellations

If you build your own account area for members, two endpoints let a member cancel an auto-renewing membership online, or cancel a membership during its cooling-off period, without contacting the operator.

  1. Call Get member memberships and payment information for the signed-in member. Each membership carries a cancellation object.
  2. Use cancellation.allowed to decide whether to offer a cancel option for that membership, and cancellation.reasonID to choose what to tell the member. When allowed is false, reasonID says why: for example 2 when someone else pays for the membership, so only they can cancel it.
  3. When reasonID is 7, the membership is inside its cooling-off period and cancelling ends it immediately. When it is 8, cancelling stops the membership renewing and the member keeps it until a date they choose from cancellation.cancellationDates. Each date is the last day they keep access, and the list already accounts for the member's notice period and any minimum term.
  4. Show the member the outcome and ask them to confirm, then call Cancel a membership for the paying member with the chosen date, or no date for an immediate cancellation.
[
    {
        "id": "DANSKESUB",
        "membershipRef": 3014,
        "paidByMember": {
            "id": 1003,
            "name": "Banky McDanske-Face"
        },
        "cancellation": {
            "allowed": true,
            "reason": "This membership will stop renewing and remain active until its cancellation takes effect",
            "reasonID": 8,
            "cancellationDates": ["2026-10-16", "2026-11-16", "2026-12-16"]
        }
    }
]

After a successful cancellation the platform emails the member a confirmation and notifies the operator's staff. Neither endpoint issues a refund: where a member cancelling in the cooling-off period is owed money, the operator's staff process it, so do not tell the member a refund has been made.

This page as markdown · All pages · llms.txt