Integration Guide · API v1

SimpleERB Booking API

Check availability, create, change and cancel restaurant bookings from your own website, app or back-office system.

Base URLhttps://book.simpleerb.com
AuthBearer token (JWT)
Token lifetime2 hours
FormatJSON

01 Before you start

Getting your credentials

API access is issued per restaurant by the SimpleERB team. Credentials are not self-service — contact SimpleERB support and ask for API access for your restaurant(s). You will be given:

ItemWhat it is
API KeyYour API username
API SecretYour API password
Restaurant IDThe numeric ID of each restaurant you may access

One set of credentials can be linked to one or more restaurants. Every request that names a restaurantId must name a restaurant linked to your credentials — anything else is rejected with 401 Unauthorized.

Keep your secret server-side

Never embed the API Key or Secret in a browser, mobile app, or any client you do not control. If your secret is exposed, ask support to regenerate it — regenerating invalidates the old secret immediately.

02 Authentication

The API uses an OAuth-style resource owner password flow and returns a JWT bearer token.

Step 1 — request a token

POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=password&username={API Key}&password={API Secret}
curl -X POST https://book.simpleerb.com/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&username=YOUR_API_KEY&password=YOUR_API_SECRET"

Success

{
  "access_token": "eyJhbGciOiJI...",
  "token_type": "Bearer",
  "expires_in": 7200,
  "userName": "YOUR_API_KEY",
  "issued": "...",
  "expires": "..."
}

Invalid credentials

{
  "error": "invalid_grant",
  "error_description": "The user name or password is incorrect."
}
Check the body, not just the status

A failed login is returned with the JSON body above. Decide success by checking whether access_token is present (or whether error is present), rather than relying on the HTTP status code alone.

Step 2 — call the API

Send the token on every request:

Authorization: Bearer {access_token}

Token lifetime

Tokens are valid for 2 hours (expires_in = 7200 seconds).

Cache and reuse your token for its lifetime. Do not request a new token per API call — the token endpoint is rate limited, and a token-per-call pattern will lock you out. Keep the token in memory, refresh it when it is within ~5 minutes of expiry, and refresh immediately on a 401.

03 Bookings API

Base path /api/Bookings/v1. All routes require Authorization: Bearer. Request and response bodies are JSON with PascalCase property names.

Common response wrapper

Every Bookings endpoint returns:

FieldTypeNotes
IsSuccessFullbooleantrue when the operation succeeded
CallResultsstringHuman-readable result or error message
dataobject / boolean / nullThe payload — note the lowercase data

Always check IsSuccessFull before reading data.

GET/CheckStatus

Connectivity and credential check. Returns 200 OK with an empty body when your token is valid — a good first integration test and health probe.

curl https://book.simpleerb.com/api/Bookings/v1/CheckStatus \
  -H "Authorization: Bearer $TOKEN"
POST/isAvailable

Check whether a specific time can be booked, before attempting to create it.

{
  "RestaurantId": 4339,
  "BookingDateTime": "2026-07-20T19:30:00",
  "Covers": 4
}

Response

{
  "IsSuccessFull": true,
  "CallResults": "Timeslot is available for booking",
  "data": true
}

data is true when the slot can be booked, false when it cannot.

POST/createBooking

Creates a booking and the customer record behind it.

{
  "RestaurantId": 4339,
  "BookingDateTime": "2026-07-20T19:30:00",
  "Covers": 4,
  "Adults": 4,
  "Childs": 0,
  "Infants": 0,
  "CustomerTitle": "Mr",
  "CustomerFirstName": "John",
  "CustomerLastName": "Smith",
  "CustomerEmail": "john@example.com",
  "CustomerPhonePrefix": "+44",
  "CustomerPhone": "7700900123",
  "CustomerPhoneType": "Mobile",
  "CustomerSubscribedToNotifications": true,
  "OfferId": null,
  "SpecialRequests": "Window seat",
  "Notes": "Anniversary"
}
FieldRequiredNotes
RestaurantIdyesMust be a restaurant linked to your credentials
BookingDateTimeyesRestaurant-local time (see §5)
CoversyesTotal number of guests
Adults, Childs, InfantsrecommendedShould add up to Covers
CustomerFirstName, CustomerLastNameyesGuest name
CustomerEmailyesConfirmation emails are sent here
CustomerPhonePrefix, CustomerPhonerecommendedDialling code separate from the number
CustomerPhoneTypeoptionale.g. Mobile
CustomerTitleoptionale.g. Mr, Ms
CustomerSubscribedToNotificationsoptionalMarketing consent flag
OfferIdoptionalSet when booking against a published offer
SpecialRequests, NotesoptionalFree text shown to the restaurant

CustomerFirstname / CustomerLastname (lowercase n) are accepted as aliases for backward compatibility.

Behaviour

  • Availability is re-validated before saving. If the slot has gone, the response is IsSuccessFull: false and no booking is created.
  • Tables are assigned automatically.
  • The booking is rejected if the restaurant has reached its online cover allowance.
  • The confirmation email is sent to the customer automatically.
  • If the restaurant's rules require a deposit, the deposit workflow takes over the customer email and the response carries a DepositDueDate.

Success returns the created booking as a RestaurantBookingResponse in data.

POST/modifyBooking

Change the date, time or party size of an existing booking.

{
  "BookingId": 12345,
  "RestaurantId": 4339,
  "BookingDateTime": "2026-07-20T20:00:00",
  "Covers": 6
}

Availability is re-checked, the booking's time and turn time are recalculated, and an updated confirmation email is sent to the customer. Returns the updated booking.

BookingId is the Uid returned by createBooking or by the booking-list endpoints.

POST/cancelBooking
{
  "BookingId": 12345,
  "RestaurantId": 4339,
  "CancellationReason": "Customer request"
}

Marks the booking cancelled, records the reason against it, and sends the cancellation email to the customer.

04 Restaurant API

Base path /api/Restaurant/v1. All routes require Authorization: Bearer, and parameters are passed on the query string. These endpoints return their payload directly — they are not wrapped in IsSuccessFull / data, except for validation errors, which do use the wrapper.

Method & routePurpose
GET /CheckStatusConnectivity check → 200 OK
GET /getBasicInfoDetails of every restaurant your credentials can access
GET /getAvaialbillityForDate?requestdate=&restaurantId=&covers=2Bookable slots for one date
GET /getAvailabillityForDateRange?startDate=&endDate=&restaurantId=&covers=2Bookable slots across a range
GET /getBookingsForDate?requestdate=&restaurantId=Bookings taking place on a date
GET /getBookingsForDateRange?startDate=&endDate=&restaurantId=Bookings taking place in a range
GET /getBookingsAddedForDate?requestdate=&restaurantId=Bookings created on a date (includes cancelled)
GET /getBookingsAddedForDateRange?startDate=&endDate=&restaurantId=Bookings created in a range (includes cancelled)
Spelling

getAvaialbillityForDate and getAvailabillityForDateRange are spelled exactly as shown. The misspellings are intentional and preserved for backward compatibility — copy them literally.

Dates are passed as yyyy-MM-dd (or a full ISO date-time), and covers defaults to 2 if omitted:

?requestdate=2026-07-20&restaurantId=4339&covers=2

Start here: getBasicInfo

Call this first. It returns the restaurants your credentials are linked to, so you can confirm which IDs to use:

curl "https://book.simpleerb.com/api/Restaurant/v1/getBasicInfo" \
  -H "Authorization: Bearer $TOKEN"

Each entry contains RestaurantUID (the value to send as restaurantId / RestaurantId), Name, address fields, TelNo1, EmailAddress and WebAddress.

Date range limits

To protect response times, ranges are capped:

Endpoint groupMaximum span
Availability — getAvaialbillityForDate, getAvailabillityForDateRange92 days
Bookings — getBookingsForDate…, getBookingsAddedForDate…366 days

Dates must fall between 2000-01-01 and 2100-01-01. A request outside these limits returns 400 Bad Request:

{
  "IsSuccessFull": false,
  "CallResults": "Date range must start on or after 2000-01-01, end on or
                  before 2100-01-01, and span at most 92 days.",
  "data": null
}

Split longer periods into several calls.

05 Dates & times

Bookings are stored internally in UTC, but the API speaks restaurant-local time for everything a guest would recognise as a booking time. Audit timestamps stay in UTC.

Field / parameterTime zone
BookingDateTime, BookingEndDateTime (requests and responses, both APIs)restaurant-local
Availability slot BookingStartDateTime / BookingEndDateTimerestaurant-local
requestdate / startDate / endDate on getBookingsForDate / …ForDateRangerestaurant-local
requestdate / startDate / endDate on getBookingsAddedForDate / …ForDateRangeUTC
DateCreated, DateModified, CancellationDate, DepositDueDateUTC

Values carry no offset suffix (2026-07-20T19:30:00), so treat them as wall-clock times in the zone above rather than parsing them as UTC instants. In practice:

  • A slot returned by an availability call can be posted straight back to createBooking unchanged.
  • A booking returned by getBookingsForDate shows the same time you booked it for.
  • Do not apply your own time-zone conversion to booking times.

06 Rate limits

Limits apply per API user — per calling IP for the token endpoint — in a rolling one-minute window:

EndpointLimit
POST /token10 requests / minute
getAvaialbillityForDate, getAvailabillityForDateRange60 requests / minute
All other /api/Bookings/v1 and /api/Restaurant/v1 routes300 requests / minute

Exceeding a limit returns 429 Too Many Requests with a Retry-After header giving the number of seconds to wait.

Recommendations

  • Cache your token for its full 2 hours.
  • Cache availability results for short periods rather than re-querying per page view.
  • Prefer one range call over many single-date calls.
  • On 429, wait for the Retry-After interval and retry — do not retry immediately.

07 Errors

StatusMeaningWhat to do
200 OKRequest processed. For the Bookings API, still check IsSuccessFull.—
400Invalid input (bad date range, invalid booking request). CallResults explains why.Fix the request
401Missing, expired or invalid token — or a restaurantId your credentials cannot access.Refresh the token; verify the ID via getBasicInfo
429Rate limit exceeded.Wait for Retry-After, then retry
500Unexpected server error.Retry once; if it persists, send support the RequestId

Unexpected server errors return JSON:

{
  "IsSuccessFull": false,
  "CallResults": "An unexpected error occurred.",
  "RequestId": "00-4bf92f3577b34da6a3ce929d0e0e4736-01"
}
Log the RequestId

Quoting RequestId in a support ticket lets us find the exact request in our logs.

08 Response reference

RestaurantBookingResponse

Returned by createBooking, modifyBooking, cancelBooking and the booking-list endpoints.

FieldTypeNotes
UidintBooking ID — use as BookingId in later calls
RestaurantIdint
BookingDateTimedate-timeRestaurant-local
BookingEndDateTimedate-timeRestaurant-local
ArrivalTimedate-time / nullSet when the guest is marked as arrived
StayTimeintTurn time in minutes
Covers, Adults, Childs, InfantsintParty breakdown
BookingReferencestringReference shown to the guest
BookingStatusintSee the status table below
CustomerobjectCustomerId, CustomerTitle, CustomerFirstName, CustomerLastName, CustomerEmail, CustomerPhonePrefix, CustomerPhone, CustomerPhoneType, CustomerSubscribedToNotifications
Depositobject / nullDeposit record when one applies
TableReservedstringAssigned tables, e.g. "T4 T5"
Notesstring
IsManagerBookingbooltrue when entered by restaurant staff
BookingInformationarrayNotes / history entries against the booking
DepositHistoryarrayDeposit history entries
DateCreated, DateModifieddate-timeUTC
Deleted, NoShow, Cancelled, UserCancelledbool
CancellationDatedate-time / nullUTC
CancelledBystring
BookingSourcestringChannel the booking came from
DepositDueDatedate-time / nullUTC — set when a deposit is outstanding

BookingStatus values

ValueMeaning
1Open
2Seated
3Check dropped
4Not yet seated
5No show
6Table dirty

Cancelled bookings are flagged by the Cancelled field, not by BookingStatus.

Booking-list response

{
  "startDate": "2026-07-20T00:00:00",
  "endDate": "2026-07-21T00:00:00",
  "RestaurantName": "The Example Kitchen",
  "RestaurantId": 4339,
  "restaurantBookingResponses": [ { "Uid": 12345, … } ]
}

Availability response

{
  "startDate": "2026-07-20T00:00:00",
  "endDate": "2026-07-20T00:00:00",
  "restaurant": { "RestaurantUID": 4339, "Name": "The Example Kitchen", … },
  "availableSlots": [
    {
      "BookingStartDateTime": "2026-07-20T19:30:00",
      "BookingEndDateTime": "2026-07-20T21:30:00",
      "BookingDuration": 120,
      "Covers": 4,
      "MaxCovers": 8,
      "BookingTables": [
        { "AreaId": 12, "AreaName": "Main Restaurant",
          "TableIds": [101, 102], "TableNo": "4" }
      ]
    }
  ]
}

startDate, endDate, restaurant, availableSlots and restaurantBookingResponses are lowercase-initial; all other properties are PascalCase.

09 Typical flow

  1. POST /tokenObtain and cache a token.
  2. GET /api/Restaurant/v1/getBasicInfoConfirm your restaurant IDs.
  3. GET /api/Restaurant/v1/getAvaialbillityForDateShow bookable times to the guest.
  4. POST /api/Bookings/v1/isAvailableRe-check the chosen slot at the moment of booking.
  5. POST /api/Bookings/v1/createBookingCreate the booking; store the returned Uid.
  6. POST /api/Bookings/v1/modifyBooking · cancelBookingHandle later changes.
  7. GET /api/Restaurant/v1/getBookingsForDateRangeReconcile bookings into your system.

Go-live checklist

  • Token cached and refreshed on expiry, never requested per call
  • 429 handled with Retry-After back-off
  • 401 triggers a token refresh and one retry
  • Booking times sent and read as restaurant-local, with no extra conversion
  • Date ranges kept within the 92-day / 366-day caps
  • IsSuccessFull checked on every Bookings API call
  • RequestId logged from any 500 response
  • API Secret stored server-side only

10 Support

For credentials, restaurant IDs, quota changes, or help with a failing request, contact SimpleERB support. When reporting a problem please include:

  • The endpoint and full request, with the secret redacted
  • The UTC timestamp of the request
  • The full response body, including RequestId if present
  • Your API Key — never your API Secret