Booking with the Basket API

Postman Collection

The public bookings API is ideal for simple booking journeys however depending on your project requirements you may need to use the basket APIs instead. If you have a long sign up form and want to ensure that a customers’ selected time is held while they fill in their details prior to completing the booking process this can be achieved using the basket API. Additionally if you want to enable the customers to book multiple items simultaneously the basket API is appropriate.

An important difference with the booking API is that the baskets are stored against a session, so once a basket is created, subsequent requests for the basket must be correctly authenticated. The response for the basket creation call will include an Auth-Token header. The same Auth Token must be included in all subsequent calls.

If you expect the total journey to last more than the expiry time (5 minutes by default), you can see our tutorial for Long Booking Journeys

Basket API Sequence Diagram

Preparing to make a booking

Prerequirements: you need to know is the root company ID, which you should be able to get from the configuration.

The first part of a customer journey would involve searching for the branch in which the booking will take place Search Company API

Endpoint:

https://{host}/api/v5/company{root_company_id}/search

Request:

curl -X GET \
  https://example.jrni.com/api/v5/company/{root_company_id} \
  -H 'App-Id: 1234' \
  -F name=Child

Response:

{
    "total_entries": 1,
    "_embedded": {
        "companies": [
            {
                "id": 37001,
                "name": "Child",
                "website": "www.test.com",
                "multi_status": [
                    "no_show",
                    "checked_in",
                    "completed"
                ],
                "numeric_widget_id": 2811560,
                "currency_code": "GBP",
                "timezone": "Europe/London",
                "live": true,
                "created_at": "2015-04-27T12:20:24Z",
                "updated_at": "2018-10-18T11:45:45Z",
                "children_count": 0,
                "locale": "en",
                "available_locales": [
                    "en",
                    "de",
                    "es",
                    "fr",
                    "it",
                    "pl",
                    "en-GB",
                    "nl",
                    "en-US",
                    "xx",
                    "sv",
                    "sv-SE",
                    "ru",
                    "da"
                ],
                "membership_id": 37000,
                "_embedded": {
                    "settings": {
                        "has_services": true,
                        "has_people": true,
                        "payment_tax": 0,
                        "currency": "GBP",
                        "requires_login": false,
                        "has_wallets": false,
                        "has_question_groups": true,
                        "_links": {
                            "self": {
                                "href": "https://example.jrni.com/api/v5/37001/settings"
                            }
                        }
                    }
                },
                "_links": {
                    "parent": {
                        "href": "https://example.jrni.com/api/v5/company/37000"
                    },
                    "company_search": {
                        "href": "https://example.jrni.com/api/v5/company/37001/search?{company,address}{&page,per_page}",
                        "templated": true
                    },
                    "self": {
                        "href": "https://example.jrni.com/api/v5/company/37001"
                    },
                    "settings": {
                        "href": "https://example.jrni.com/api/v5/37001/settings"
                    },
                    "services": {
                        "href": "https://example.jrni.com/api/v5/37001/services{?exclude_links,availability}",
                        "templated": true
                    },
                    "categories": {
                        "href": "https://example.jrni.com/api/v5/37000/categories{/id}",
                        "templated": true
                    },
                    "addresses": {
                        "href": "https://example.jrni.com/api/v5/37001/addresses"
                    },
                    "book": {
                        "href": "https://example.jrni.com/api/v5/37001/basket/add_item{?event_id,member_id,event_chain_id,service_id,product_id,attachment_id,deal_id,package_id,bulk_purchase_id}",
                        "templated": true
                    },
                    "space_statuses": {
                        "href": "https://example.jrni.com/api/v5/37001/space_statuses"
                    },
                    "named_categories": {
                        "href": "https://example.jrni.com/api/v5/37001/named_categories"
                    },
                    "people": {
                        "href": "https://example.jrni.com/api/v5/37001/people"
                    },
                    "clinics": {
                        "href": "https://example.jrni.com/api/v5/37001/clinics/{/id}{?start_time,end_time,address_id,availability,start_date,end_date}",
                        "templated": true
                    },
                    "client_details": {
                        "href": "https://example.jrni.com/api/v5/37001/client_details"
                    },
                    "packages": {
                        "href": "https://example.jrni.com/api/v5/37001/packages"
                    },
                    "bulk_purchases": {
                        "href": "https://example.jrni.com/api/v5/37001/bulk_purchases"
                    },
                    "checkout": {
                        "href": "https://example.jrni.com/api/v5/37001/basket/checkout{?member_id,take_from_wallet}",
                        "templated": true
                    },
                    "total": {
                        "href": "https://example.jrni.com/api/v5/37001/purchase_totals/{total_id}",
                        "templated": true
                    },
                    "login": {
                        "href": "https://example.jrni.com/api/v5/login/37001"
                    },
                    "client": {
                        "href": "https://example.jrni.com/api/v5/37001/client"
                    },
                    "client_by_email": {
                        "href": "https://example.jrni.com/api/v5/37001/client/find_by_email/{email}",
                        "templated": true
                    },
                    "booking_text": {
                        "href": "https://example.jrni.com/api/v5/37001/booking_text"
                    },
                    "days": {
                        "href": "https://example.jrni.com/api/v5/37001/day_data{?month,week,date,edate,location,service_id,event_id,person_id,resource_id,people_ids,resource_ids,person_group_id}",
                        "templated": true
                    },
                    "email_password_reset": {
                        "href": "https://example.jrni.com/api/v5/login/37001/email_password_reset"
                    },
                    "facebook_login": {
                        "href": "https://example.jrni.com/api/v5/login/37001/facebook"
                    },
                    "available_integrations": {
                        "href": "https://example.jrni.com/api/v5/admin/37001/available_integrations"
                    },
                    "apps": {
                        "href": "https://example.jrni.com/api/v5/37001/apps{/app_name}{?page,per_page}",
                        "templated": true
                    },
                    "edit_translations": {
                        "href": "https://example.jrni.com/api/v5/admin/37001/translations/edit{?requested_locale}",
                        "templated": true
                    },
                    "times": {
                        "href": "https://example.jrni.com/api/v5/37001/times{?start_date,end_date,service_id,person_id,resource_id,merge_times,time_zone,only_available,ignore_booking}",
                        "templated": true
                    },
                    "baskets": {
                        "href": "https://example.jrni.com/api/v5/baskets"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "https://example.jrni.com/api/v5/company/37000/search?&page=1&per_page=30",
            "templated": true
        }
    }
}

Create a basket

The next step is to use our APIs to create a basket, you’ll require the company_id obtained above

Endpoint:

https://{host}/api/v5/{company_id}/baskets

Request:

curl -X POST \
  https://example.jrni.com/api/v5/baskets \
  -H 'App-Id: f6b16c23' \
  -H 'App-Key: f0bc4f65f4fbfe7b4b3b7264b655f5eb' \
  -F company_id=37001

Response:

{
    "company_id": 37001,
    "total_price": 0,
    "total_due_price": 0,
    "id": "183936bb-d7c0-4c76-96d6-cb6aa1a5220e",
    "_embedded": {
        "items": [],
        "items_removed": []
    },
    "_links": {
        "self": {
            "href": "https://example.jrni.com/api/v5/baskets/183936bb-d7c0-4c76-96d6-cb6aa1a5220e"
        },
        "service_items": {
            "href": "https://example.jrni.com/api/v5/baskets/183936bb-d7c0-4c76-96d6-cb6aa1a5220e/service_items"
        },
        "refresh": {
            "href": "https://example.jrni.com/api/v5/baskets/183936bb-d7c0-4c76-96d6-cb6aa1a5220e/refresh"
        },
        "checkout": {
            "href": "https://example.jrni.com/api/v5/baskets/183936bb-d7c0-4c76-96d6-cb6aa1a5220e/checkout"
        }
    }
}

Response headers:

Auth-Token: xyz

The next step is to pick a Service you want to book

Get Services API

Endpoint:

https://{host}/api/v5/{company_id}/services

Request:

curl https://example.jrni.com/api/v5/1/services -H App-Id:1234

Response:

{
  "total_entries": 2,
  "_embedded": {
    "services": [
      {
        "name": "Tennis Coaching",
        "description": "Individual coaching is the fastest way to improve your tennis, whether a beginner or experienced club player.",
        "durations": [
          30,
          60
        ],
        "prices": [
          1000,
          1500
        ],
        "listed_durations": [
          20,
          50
        ],
        "booking_time_step": 30,
        "duration_unit": "minute",
        "min_bookings": 1,
        "max_bookings": 2,
        "_links": {
          "self": "https://example.jrni.com/api/v5/1/services/1",
          "times": {
            "href": "https://example.jrni.com/api/v5/1/time_data?service_id=1{&event_id,date,end_date,location,person_id,resource_id,duration,single,num_resources,group_id,resource_ids,time_zone,ignore_booking,person_group_id,people_ids,is_admin}",
            "templated": true
          }
        }
      },
      {
        "name": "Tennis Coaching Day",
        "description": "Ideal for improvers and seasoned tennis players alike, this professional coaching day, is the perfect chance to sharpen skills and boost performance on the court.",
        "durations": [
          1
        ],
        "prices": [
          6000
        ],
        "listed_durations": [
          1
        ],
        "duration_unit": "day",
        "min_bookings": 1,
        "max_bookings": 1,
        "_links": {
          "self": "https://example.jrni.com/api/v5/1/services/2"
        }
      }
    ]
  },
  "_links": {
    "self": "https://example.jrni.com/api/v5/1/services"
  }
}

Fetch time

Once the customer has selected a service we can use the service_id along with a date to retrieve the available times.

Get Time API

Endpoint:

https://example.jrni.com/api/v5/{company_id}/times{?service_id,start_date,duration}

Request:

curl https://example.jrni.com/api/v5/1/times?service_id=1&start_date=2018-01-01 \
  -H App-Id:1234

Response:

{
  "_embedded": {
    "times": [
      {
        "start": "2018-01-01T09:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T09:00:00+01:00?service_id=1"
          }
        }
      },
      {
        "start": "2018-01-01T10:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T10:00:00+01:00?service_id=1"
          }
        }
      },
      {
        "start": "2018-01-01T11:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T11:00:00+01:00?service_id=1"
          }
        }
      },
      {
        "start": "2018-01-01T12:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T12:00:00+01:00?service_id=1"
          }
        }
      },
      {
        "start": "2018-01-01T13:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T13:00:00+01:00?service_id=1"
          }
        }
      },
      {
        "start": "2018-01-01T14:00:00+01:00",
        "available": true,
        "durations": [60],
        "prices": [],
        "_links": {
          "self": {
            "href": "https://example.jrni.com/api/v5/admin/1/times2018-01-01T14:00:00+01:00?service_id=1"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href: "https://example.jrni.com/api/v5/1/times?service_id=1&start_date=2018-01-01"
    }
  }
}

Reserve the time

The next step is to add the time to the basket:

Endpoint:

curl -X POST \
  https://example.jrni.com/api/v5/baskets/62c7b799-9800-4a96-b206-af67f7fb33f6/service_items \
  -H 'App-Id: f6b16c23' \
  -H 'App-Key: f0bc4f65f4fbfe7b4b3b7264b655f5eb' \
  -H 'Auth-Token:{Auth-Token}' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F company_id=37001 \
  -F service_id=48317 \
  -F 'start=2019-10-31T09:00:00+00:00'
{
    "id": "aacc9c16041dbc60",
    "type": "service_item",
    "company_id": 37001,
    "service_id": 48317,
    "person_id": 15285,
    "duration": 60,
    "start": "2019-10-31T09:00:00+00:00",
    "expires": "2019-10-03T13:31:15Z",
    "_links": {
        "self": {
            "href": "https://example.jrni.com/api/v5/baskets/62c7b799-9800-4a96-b206-af67f7fb33f6/service_items/aacc9c16041dbc60"
        },
        "company": {
            "href": "https://example.jrni.com/api/v5/company/37001"
        },
        "service": {
            "href": "https://example.jrni.com/api/v5/37001/services/48317"
        },
        "person": {
            "href": "https://example.jrni.com/api/v5/37001/people/15285"
        }
    }
}

Note: the expires attribute in the payload above - This attribute represents the time in which the item will no longer be reserved

  • The time is configurable - consult our implementation team about the ShardSetting configuration - expire_held_items. (/v5/public_api#/Company/getCompanyCompanyIdSearch)
  • You can refresh the expiry time with the Basket#Refresh API . See the tutorial for Long Booking Journeys

Submit the customer details

(don’t forget to submit the auth token)

Endpoint:

https://{host}/api/v5/{company_id}/client

Request:

curl https://example.jrni.com/api/v5/1/client -H App-Id:1234 -H Auth-Token:{Auth-Token} -X POST \
 -d '{
   "first_name": "John",
   "last_name": "Doe",
   "email": "jdoe@example.com"
 }'

Response:

{
  "id": 1295,
  "first_name": "John",
  "last_name": "Doe",
  "email": "jdoe@example.com"
}

Checkout basket

Use the ID of the created customer in the payload of the request and use the Auth-Token header from the add item response.

Note It is considered a good practice to refresh the basket before checking out to make sure you still have a claim to all the items

Endpoint:

https://{host}/api/v5/{company_id}/basket/checkout

Request:

curl https://example.jrni.com/api/v5/1/basket/checkout -H App-Id:1234 \
  -H Auth-Token:xyz -X POST \
  -d '{
    "client": {
      "id": 1295
    }
  }'