Hello,
We are integrating a custom booking interface with the SimplyBook.me Admin API.
Authentication, addClient(), service retrieval, availability, and isPaymentRequired() are working successfully.
However, Admin API book() consistently fails with:
code: -32070
message: “Value is required and can’t be empty”
Test:
event_id = 94
unit_id = 2
client_id = 12
The service has required fields for:
- Pickup location
- Drop-off location
- Vehicle type
- Number of passengers
We send these fields through the “additional” parameter using their field name hashes and non-empty values according to the API documentation, but SimplyBook still reports one field as empty.
Please confirm the exact format expected by the Admin API book() method for these required Additional Fields, especially dropdown/list fields:
- label?
- option value?
- option ID?
- another internal identifier?
Please also confirm the correct API flow because isPaymentRequired() returns TRUE for event_id 94 and event_id 95.
This issue blocks real bookings through our custom API integration.
We can provide the raw request/response without API keys or secrets.
Thank you.
Hi,
Thanks for the details — this comes down to two things in how additional is built.
-
Field key. The key you use in additional must be the exact name value returned by the getAdditionalFields(event_id) method for that event (not a hash, and not the field’s id). It’s matched case-sensitively and byte-for-byte against additional. If the key doesn’t match exactly, the field is treated as not sent, its value resolves to an empty string, and — because the field is required — you get exactly the -32070 “Value is required and can’t be empty” error you’re seeing.
-
Dropdown / list field values. For a field with type: “select” (Pickup location, Drop-off location, Vehicle type, etc.), the allowed values are the field’s values property split by comma (each trimmed) — i.e. the exact option text as configured in the admin panel. There is no separate option ID or other internal identifier for these fields; the option’s literal text is the value you must send.
Recommended flow: right before calling book(), call:
getAdditionalFields(event_id)
and build your additional object directly from the response — using each field’s name as the key, and for select fields, one of the exact strings in that field’s values as the value. That avoids any mismatch with hardcoded names/values.
On isPaymentRequired(): that’s unrelated to the book() failure — it only reports whether the service has a price configured under the Paid Events plugin, and doesn’t block or change how book() works. You can create the booking via book() regardless, and handle payment/invoicing separately afterward (via additional.make_invoice / invoice_id / payment_required, or the Invoice API).
Best regards