Skip to main content
Create a booking when a customer books a court in your app, and cancel it when they cancel on your side. 1Club returns a bookingId you use to cancel or look the booking up later.

Create a booking

Requires the bookings:write scope.
Body fields:
  • areaId (required) - the area id from List areas
  • startTime, endTime (required) - ISO date-times, endTime after startTime
  • customer.email (required) - matches an existing contact or creates a new one
  • customer.firstName, customer.lastName, customer.phone (optional) - used when creating a new contact
  • payment.status (required) - paid (you collected the money) or unpaid (outstanding)
  • payment.amount (optional) - amount collected; defaults to the area’s price for the slot (max 1,000,000)
  • channel (optional) - a label stored for attribution
  • notes (optional)
Response (201 Created):

How payment is recorded

  • paid → 1Club records a paid booking transaction, settled against a dedicated External / API payment method (manual channel, no card charged). Counts as revenue and paid.
  • unpaid → 1Club records the transaction as outstanding. Counts as accrued revenue with nothing paid.
You keep ownership of collection and refunds. 1Club never charges a card for these bookings.

How contacts sync

Every booking belongs to a contact in the club’s 1Club CRM. You never create or manage contacts directly — there is no contacts endpoint. Instead, the customer object you send with each booking is resolved to a contact automatically, as a by-product of booking sync. This is deliberately one-way: partner → 1Club. 1Club never pushes contact changes back to you.

Matching and creation

1Club resolves the contact from customer.email:
  • Email is the identity key. It’s normalized (trimmed and lower-cased) and matched within the club’s organization. Matching is case-insensitiveAlex@Example.com and alex@example.com are the same contact.
  • Scoped per organization. Contacts belong to one organization. The same email booking at two different clubs (organizations) is two separate contacts — there is no global customer identity across clubs.
  • Match wins over create. If a contact with that email already exists, the booking links to it. If not, a new contact is created from the customer fields (firstName, lastName, phone; name is derived from first + last, falling back to the email when no name is given).
  • The booking stores the resolved contactId. From then on the booking, its revenue, and its history all roll up to that one contact in the CRM.
For an existing contact, 1Club matches by email and does not overwrite the stored name or phone with what you send. Treat contact profile fields as create-time only — sending a new phone on a later booking for the same email will not change the contact. (To correct contact details, edit the contact in 1Club.)

Guarantees

  • No duplicates. A unique constraint on (organization, lower(email)) plus a create-race retry means two bookings racing with the same new email still produce exactly one contact.
  • Consistent identity. Because matching is by normalized email, repeat customers always land on the same contact — their bookings accumulate rather than fragmenting.
  • Searchable immediately. A newly created contact is available in the CRM (searchable by name and email) as soon as the booking succeeds.

The full create flow

1

Validate the area

The areaId must be bookable through this API (active, public, bookable type). If not → 400.
2

Resolve the contact

Normalize customer.email (trim + lower-case), then match an existing contact in the organization or create one from the customer fields. An existing contact is reused as-is (name/phone not overwritten).
3

Create the booking

Link the resolved contactId and write the booking, re-checking availability atomically. If the slot was taken in the meantime → 409.
4

Record revenue & respond

Record the transaction (paid → settled, unpaid → outstanding) and return 201 with { bookingId, status, payment }.
Contact resolution runs before the booking write. So if the slot turns out to be taken (409) or the request is otherwise rejected, a contact just created for a first-time customer is kept — it isn’t rolled back. That’s harmless: it carries no booking, stays matched by email, and is reused on retry. Only the booking write re-checks availability atomically and rejects conflicts.

Common errors

  • 409 - the area is not available for the selected time.
  • 400 - the time is outside operating hours, the booking breaks a club booking policy, or the area is not bookable through this API.
  • 403 - the API key is missing the bookings:write scope.
  • 429 - rate limit exceeded (booking writes are throttled in addition to the standard per-org limit).

Cancel a booking

Requires the bookings:write scope. Cancels the booking by its 1Club id. No refund is issued by 1Club.
Response:
Cancelling is idempotent: cancelling an already-cancelled booking succeeds and returns the same response.

Look up a booking

Requires the bookings:read scope. Returns the current state of a booking, including its payment status.
A 404 means no booking with that id exists in your organization.