Skip to content

Cancellations ​

Two partner operations after confirm: cancel (free the slot, mark CANCELLED) and refund (mark REFUNDED, free the slot if it was still BOOKED).

Auth: the owning partner’s x-api-key. Another partner’s booking → 403 UNAUTHORIZED. Missing id → 404.

Neither call moves money at a payment processor. If you charged the customer, you refund them.

idempotency_key is required. Reusing that key for a different booking or for the other operation (cancel vs refund) is 409 IDEMPOTENCY_KEY_MISMATCH.

Cancel a booking ​

http
POST /api/v1/bookings/{bookingId}/cancel
Content-Type: application/json
x-api-key: <your-api-key>

{ "reason": "customer request", "idempotency_key": "cancel-9f2a-…" }

200: { "message": "Booking cancelled successfully" }.

A second cancel without a matching stored key, after the booking is already CANCELLED, is 409 INVALID_HOLD_STATE. A retry with the original key is 200.

Refund a booking ​

http
POST /api/v1/bookings/{bookingId}/refund
Content-Type: application/json
x-api-key: <your-api-key>

{ "reason": "customer request", "idempotency_key": "refund-9f2a-…" }

200: { "message": "Booking refunded successfully" }.

Which state allows which call ​

Booking statusCancelRefund
BOOKED200 → CANCELLED, slot freed200 → REFUNDED, slot freed
CANCELLED409 INVALID_HOLD_STATE (200 if it is a retry with the original key)200 → REFUNDED (marks a cancelled booking as refunded)
REFUNDED409 INVALID_HOLD_STATE409 INVALID_HOLD_STATE (200 if it is a retry with the original key)

The reason you send is stored and passed on in the webhook details; if you send none, a default is used: "Customer request" for a cancel, "Manager initiated refund" for a refund (the same text whoever refunds). Do not parse it.

Release a hold ​

Not a booking. See Holds: POST /api/v1/partner/holds/{holdId}/cancel.

Start in the sandbox. Production access is granted after certification. Access requests and integration support: hello@venuesetu.com