Changelog¶
This page tracks new endpoints, breaking changes, and deprecations in the bsport Public API. Entries are ordered newest first.
2026¶
October 2026¶
V2 invoices link a reverse invoice to the invoice it refunds¶
V2 invoices now return source_invoice_id. On a reverse invoice it is the id of the invoice it
refunds. It is null on every other invoice and on the reverse invoices of partial pass refunds,
which are not linked to an invoice. It appears in /api/v2/management/invoices/
responses, in the invoice that invoice items expand with expand[]=invoice_id, and in the
invoice.created and invoice.updated webhook payloads. It carries the same value as
source_invoice_id in the Back Office invoice webhooks.
See your API key and its usage¶
GET /api/v2/monitoring/me/ returns the API key making the call (client_id, company or
franchise, expires_at) and its successful calls per UTC calendar month over the last 12
months. A franchise key also gets the calls made on each company of its franchise. See
Check your API key and usage.
From this release, a franchise-key call made on a company counts on that company as well as on the franchise. Company months before it leave out franchise-key calls.
Test deliveries and secret rotation for webhook registrations¶
Two operations join the V2 Webhook Registrations endpoint:
POST /api/v2/management/webhook-registrations/{id}/test/sends one signed sample delivery to the registration's URL, once and without retry, and returnsis_delivered,http_statusandfailure_reason. It works on inactive registrations and follows the registration's payload version. It is limited to 5 calls per minute per company.POST /api/v2/management/webhook-registrations/{id}/rotate-secret/replaces the signing secret and returns the registration with its newsigning_secret. The previous secret stops working at once.
signing_secret now changes on rotation, and updated_at also records it. Registrations still
cannot be deleted: send is_active=false to stop deliveries. See
Test a registration and
Rotate the signing secret.
Rejected credentials return 401¶
An invalid, expired or revoked API key (the JWT sent in X-Api-Key) now returns 401 with
an empty body and a WWW-Authenticate: ApiKey header, on V1 and V2. It previously returned
403 with "Authentication credentials were not provided.", the same response as a request
without credentials. If your integration treats 403 as an invalid key, handle 401 as well.
A request without credentials still returns 403. See
Errors and status codes.
The V2 Beta entries below change existing V2 fields and filters in place. Field changes apply to V2 REST responses and to V2 webhook payloads; filter changes apply to V2 REST requests. V1 is unchanged. See Dates, time zones and amounts for the rules they follow.
V2 datetimes keep a numeric UTC offset¶
A zero UTC offset is now written +00:00, never Z, in every V2 datetime. Companies at UTC+0
see the change: UTC companies, and the UK, Ireland and Portugal in winter. Parse datetimes with
an ISO 8601 parser that accepts both forms.
Class bookable_from, bookable_until and cancelable_until now use the company's time zone,
like starts_at, instead of the venue's. The moment they describe is unchanged.
V2 days derived from a moment use the company's day¶
Client joined_date and client subscription first_billing_date and last_billing_date are now
days in the company's time zone, not in UTC. A client who joined at 00:30 on March 11, 2026, in
Paris now has joined_date 2026-03-11, the day joined_after_date and joined_before_date
match. A billing date in a time zone above UTC+12 no longer shows the day before.
X-Timezone-Name applies to V2 requests¶
With a company or franchise API key, a V2 GET request now uses the time zone
X-Timezone-Name names for response datetimes, for the days derived from them, and for the
filter datetimes and days you send without an offset. Write requests, requests without the
header and requests with an unknown time zone name keep the company's time zone, as before. V1
and webhooks keep the company's time zone.
V2 invoice line amounts are decimal strings¶
The amounts in invoice line_items.data are now decimal strings in major currency units, like
the other invoice amounts: tax_included_unit_amount, tax_included_amount, voucher_applied,
line_total, and tax_breakdown.total_tax and tax_breakdown.unit_tax. 4900 becomes
"49.00". tax_breakdown.rate becomes a decimal-string percentage: 20.0 becomes "20.000".
V2 coupon discount value is a decimal string¶
Coupon discount.value is now a decimal string, like the value you send: 10.5 becomes
"10.50".
V2 gift-card range amounts are decimal strings¶
Gift-card minimum_amount and maximum_amount are now decimal strings in responses: 10
becomes "10.00". Requests accept a decimal string or a number, and still refuse an amount with
cents.
V2 class passes rename base_price to price¶
Class passes, their webhooks and the class pass a client class pass expands with
expand[]=class_pass_id return their price as price, like appointment passes and products.
price is now a decimal string, "56.00" instead of 56.0, and base_price, which
carried the same amount, is removed. Creating a class pass takes price; a request that still
sends base_price is refused with a 400. Sort with ordering=price: ordering=base_price is
ignored.
V2 class and appointment period filters are renamed¶
The classes and appointments lists name their start-time bounds after the starts_at field
they filter: period_start becomes starts_after and period_end becomes starts_before.
The defaults are unchanged: from now to 30 days from now, each bound on its own. A plain
date is read as midnight in the company's time zone. The old names are ignored, not refused,
so a request that still sends them gets the default window.
V2 booking date filters take a timestamp¶
The bookings list filters now take the type of the field they filter, a timestamp:
| Before | After |
|---|---|
created_after_date |
created_after |
created_before_date |
created_before |
class_started_after_date |
class_start_after |
class_started_before_date |
class_start_before |
A plain date is still accepted, read as midnight in the company's time zone:
created_before=2026-03-11 now leaves out March 11, which created_before_date=2026-03-11
included. Send 2026-03-11T23:59:59.999999 to keep the whole day. The old names are ignored, not
refused, so a request that still sends them returns unfiltered results.
Versioned webhook registrations¶
New webhook registrations always use the V2 REST endpoint and the V2 event catalogue.
V1 registration creation is retired:
POST on /api/v1/management/webhook-registrations/ returns 410 with code WHR-002.
MCP creates webhook registrations through V2.
Existing registrations retain their immutable V1 payload contract, including registrations
previously created through a V2 route. Reads and updates remain available. New V2 deliveries use
canonical event names such as class.updated, V2 resource shapes, and payload header date
2026-10-06; existing V1 deliveries retain their historical names and date 2026-08-22.
Retries and replay preserve the registration's version.
See webhook setup and existing V1 registrations.
Invoice webhooks in V2¶
V2 registrations support invoice.created and invoice.updated with the same unexpanded Invoice
representation as the V2 retrieve endpoint, including grouped line_items. Invoice-item
creation, updates, and deletion also produce invoice.updated; reassignment can notify both
invoices. These events report current state at delivery time, not payment lifecycle transitions.
Existing V1 registrations and legacy Backoffice invoice payloads remain unchanged.
See Invoice events for trigger boundaries and migration guidance.
Appointment, service, and venue webhooks (V2 only)¶
The V2 catalogue adds appointment creation, updates and cancellation transitions; service
creation and updates; and venue creation, updates and removal from a company's catalogue.
Current-state payloads use the same unexpanded representation as the corresponding V2 REST
endpoint. venue.deleted contains only the venue ID and does not imply global venue deletion.
Existing V1 registrations retain their original contracts; new V1 registrations remain retired.
V2 appointments whose client is no longer addressable are omitted from lists, return 404 on retrieval, and are not delivered by webhook. Membership-plan and billing-plan events are not part of this catalogue.
Class pass and product webhooks (V2 only)¶
New V2 registrations can subscribe to class_pass.created, class_pass.updated,
client_class_pass.created, client_class_pass.updated, product.created, and
product.updated. Deliveries use the corresponding unexpanded V2 REST resource.
V2 client class passes require a client in the class pass owner's company. Passes without that client are omitted from lists, return 404 for detail requests, and skip webhook delivery. Their underlying pass and V1 behavior are unchanged.
Updates cover related data as well as the resource row and can repeat an unchanged current representation. Treat them as refresh notifications, not incremental credit or stock movements. These events do not confirm payment or emit expiration transitions from the clock. Existing V1 registrations keep their historical catalogue. See the resource mapping.
API V2 is available¶
V2 is a separate contract under /api/v2/. It adds endpoints for scheduling, catalogue,
finance and messaging, and uses consistent field names. V1 keeps working until
January 15, 2027.
New integrations use V2: see Getting started. Existing integrations follow Migrate from V1 to V2.
Migration is not only a URL change
On classes, service_id and teacher_id keep their names but identify different
records in V2. Requests still return 200, so a stored V1 ID can match the wrong
class. Reload your service and teacher mappings before you switch.
New operations in V2. All paths are under /api/v2/management/. Read the table by
area.
| Area | Operations |
|---|---|
| Classes | POST /classes/, PATCH /classes/{id}/, POST /classes/{id}/cancel/, GET /classes/{id}/spots/, GET /classes/{id}/waitlist/ |
| Appointments | POST /appointments/, POST /appointments/{id}/cancel/, read /appointment-services/ and /appointment-slots/ |
| Services and levels | Read /services/ and /levels/. They resolve the service_id and level_id values on classes |
| Venues and teachers | PATCH /venues/{id}/, POST and PATCH /teachers/{id}/pay-rates/, read /teacher-pay-rates/ |
| Clients | PATCH /clients/{id}/. PATCH and DELETE on /client-notes/{id}/, /tags/{id}/ and /tag-groups/{id}/ |
| Passes | /class-passes/, /client-class-passes/ with enable and disable, /appointment-passes/, /client-appointment-passes/ with PATCH and disable |
| Retail and promotions | /products/, /coupons/ (discount codes), /coupon-usages/ (read only), /gift-cards/. State changes use dedicated actions: enable and disable for products and gift cards, disable only for discount codes |
| Finance | Read /invoices/ and /invoice-items/ |
| Communications | POST /communications/ to queue an email or SMS, GET /communications/ and GET /communications/{id}/ for processing status |
Expand related resources. Supported list and detail endpoints accept repeatable
expand[] query parameters. Expandable ID fields are replaced in place by the related
resource, with dot notation for up to two levels. See
Pagination and filtering.
What changes from V1. The migration guide has every table. The main changes:
/passes/and/client-passes/become/class-passes/and/client-class-passes/. V2 has no aliases for the old paths.- Spelling and naming are consistent:
is_canceled,cancelable_until,current_waitlist_size,is_bookable_by_clients,venue_id,firstname,lastnameandphone_number. - Bookings use
class_id,class_idsandclient_class_pass_id. Thesession_*,location_idandclient_pass_idnames are not exposed. - Client creation takes
client_referenceinstead ofmembership, and tag creation requires acolor. - Subscriptions use
subscription_template_id,subscription_termsand theclass_passbenefit type.
For side effects of writes, such as clearing a substitute teacher or disabling a product, read V2 workflows and field conventions.
MCP and webhooks. MCP tools are generated from the V2 operations, with V2 field names and IDs. Webhook payloads depend on the registration. New registrations are always created through V2 and deliver V2 payloads with canonical event names. Existing registrations keep delivering V1 payloads and historical event names, and do not change. To move an event to V2 payloads, create a new registration for it and disable the old one. See Webhook event payloads and the migration guide.
Sunset dates. Read the table by route group.
| Routes | Replacement | Removal date |
|---|---|---|
Legacy V1 routes: bookings, members, contracts, billing_plans, payment_packs, consumer_payment_packs |
See the replacements in Deprecated legacy routes | November 30, 2026 |
| All other V1 routes | The V2 endpoint listed in the migration guide | January 15, 2027 |
June 2026¶
New endpoints: classes, appointments, venues, and teachers¶
Four read endpoints are now available, giving partners structured access to schedule data.
| Endpoint | Description |
|---|---|
GET /api/v1/management/classes/ |
List and retrieve class sessions |
GET /api/v1/management/appointments/ |
List and retrieve booked appointments |
GET /api/v1/management/venues/ |
List and retrieve venue information |
GET /api/v1/management/teachers/ |
List and retrieve teacher profiles |
Classes endpoint (June 6):
- Full list and detail views for group fitness sessions
- Filters: service_id, venue_id, teacher_id, period_start, period_end
- Renamed fields: date_start -> starts_at, duration_minute -> duration_in_minutes, effectif -> max_capacity, validated_booking_count -> current_bookings, activity_id -> service_id
Appointments endpoint (June 3-4): - List and detail views for private 1-on-1 sessions - Service filter support
Venues endpoint (May 13 - June): - List, retrieve, and create venues - Latitude and longitude validation - Timezone management per venue
Teachers endpoint (May 27 - June):
- List and detail views for instructor profiles
- Filter by is_disabled
- Teacher profile information (name, email, phone, bio, profile picture)
Client passes stability (June 10-11):
- Improved query performance for the /client-passes/ endpoint
- Better handling at scale
Large unfiltered result sets can still time out. See
[Rate limits and bulk data sync](guides/06-rate-limits.md) for the filters to apply.
Deprecated legacy routes¶
The legacy V1 routes outside /api/v1/management/ are deprecated. Updated in
October 2026: the removal date is November 30, 2026, and the list covers all six route
groups, not only bookings and consumer_payment_packs.
| Deprecated route | Replacement |
|---|---|
/api/v1/bookings/ |
/api/v1/management/bookings/ (V1) or /api/v2/management/bookings/ (V2) |
/api/v1/consumer_payment_packs/ |
/api/v1/management/client-passes/ (V1) or /api/v2/management/client-class-passes/ (V2) |
/api/v1/payment_packs/ |
/api/v1/management/client-passes/ (V1) or /api/v2/management/client-class-passes/ (V2) |
/api/v1/members/ |
/api/v1/management/clients/ (V1) or /api/v2/management/clients/ (V2) |
/api/v1/contracts/ |
/api/v1/management/subscriptions/ (V1) or /api/v2/management/subscriptions/ (V2) |
/api/v1/billing_plans/ |
/api/v1/management/client-subscriptions/ (V1) or /api/v2/management/client-subscriptions/ (V2) |
The management endpoints return the same core data with consistent pagination, filtering, and identifier alignment with the rest of the Public API.
Removal date: November 30, 2026
These paths stop working after November 30, 2026. If your integration still calls them, migrate before that date.
Migration steps:
- Replace the path in your HTTP client.
- Verify that response field names match your downstream mapping (field names may differ between the old and new endpoints).
- Re-run your integration tests against the new paths.
May 2026¶
Venue management endpoints¶
Create, list and retrieve operations for company venues:
POST /api/v1/management/venues/- Create a new venueGET /api/v1/management/venues/- List venuesGET /api/v1/management/venues/{id}/- Retrieve venue details
V1 has no operation to update a venue. PATCH /api/v2/management/venues/{id}/ is available
in V2.
New capabilities (May 13-19): - Validate latitude and longitude boundaries - Timezone configuration per venue
Teacher endpoints¶
Instructor management through the public API:
GET /api/v1/management/teachers/- List teachers with filtering optionsGET /api/v1/management/teachers/{id}/- Retrieve individual teacher profile- Filter by
is_disabled
Bookings updates¶
Enhanced bookings endpoint:
GET /api/v1/management/bookings/- List bookings with client context- Permission-based access control: only view bookings for your clients
client_idfilter to list the bookings of one client
Tag support¶
Extended tagging to client records:
POST /api/v1/management/clients/{id}/tag/- Add a tag to a clientPOST /api/v1/management/clients/{id}/untag/- Remove a tag from a client
April 2026¶
Management namespace and field renaming¶
Launched the new /api/v1/management/ namespace with standardized field names across all endpoints.
New endpoint paths (April 1):
- All core endpoints moved to /api/v1/management/ (old paths deprecated but functional)
- Consistent pagination, filtering, and response structure
Field name standardization (April 1, 13):
- Standardized all field names for consistency across the API
- Examples: date_* -> *_at, boolean fields -> is_* prefix
Applied to all endpoints: - Clients, bookings, billing plans, client subscriptions, client passes
Client subscriptions and billing plans (April 16): - Updated field names and structure for clarity
Rate limiting¶
All endpoints now enforce rate limiting:
- Limit: 20 requests per second per company per endpoint
- Max page size: 100 results per request
- Applies to all public endpoints
See Rate limits and bulk data sync for patterns on handling rate limits in bulk operations.
March 2026¶
Back Office webhook reference published (legacy)¶
The first webhook articles documented registrations configured in Back Office under
Settings > Webhook. Those webhooks use the legacy registration system and payloads:
- Member webhook (
member-create,member-update) - Booking webhook (
booking-create,booking-update,booking-delete) - Billing plan webhook (
billing_plan-create,billing_plan-update) - Offer webhook (
offer-create,offer-update) - Coach webhook (
associated_coach-create,associated_coach-update,associated_coach-delete) - Invoice webhook (
invoice-finalize,invoice-pay) - Tag webhook (
tag-create,tag-update,tag-delete)
These are not the current Public API webhook contract. New integrations must use registrations created through the Public API and the current event catalogue.
February 2026¶
No public API changes.
January 2026¶
Initial Public API release¶
Core endpoints for reading and creating data:
Client management:
- POST /api/v1/clients/ - Create client records
- GET /api/v1/clients/ - List clients with filtering and pagination
- GET /api/v1/clients/{id}/ - Retrieve individual client details
Bookings:
- POST /api/v1/bookings/ - Create bookings
- GET /api/v1/bookings/ - List bookings
Passes and subscriptions:
- GET /api/v1/client-passes/ - List client passes (purchase history)
- GET /api/v1/client-subscriptions/ - List client subscriptions
- GET /api/v1/contracts/ - List subscription contract products
- GET /api/v1/passes/ - List pass products
Authentication:
- API key authentication with X-Api-Key, X-Client-ID, X-Company-ID headers
- Support for single company and franchise (multi-company) access
Documentation: - OpenAPI specification with endpoint descriptions - Getting started guide - Authentication guide - Pagination and filtering reference
API Evolution¶
The Public API launched in January 2026 with core CRUD endpoints for clients and bookings. Over the following six months, the API expanded with:
- More resources: Schedule data (classes, appointments), team data (teachers, venues)
- Better structure: Management namespace with consistent field naming
- Performance controls: Rate limiting to prevent abuse
- Event support: Webhooks for near-real-time integrations
- Improved filtering: Support for date ranges, tags, and resource relationships
The API maintains backward compatibility: old endpoints are deprecated but remain functional, giving partners time to migrate to the new management namespace.