The OAuth2 Bearer Token Scheme, using JSON Web Tokens was selected as the primary authentication and authorisation method for MetaPack Options.

Using this method, the client does not need to expose secrets in an open channel, if calling the API from the browser directly.

Generate Token

This first stage - which should happen in the backend - involves replacing username / password, using HTTP Basic Authentication, with a JWT token, which represents the user and the permissions that it has in the system, as well as a TTL / expiration time which is parametrised and we recommend should match the typical checkout process duration.

An ill-intentioned end user may still use the browser developer tools to get hold of the token and generate traffic on behalf of the retailer, which we would bill. However, with an appropriate TTL this should be greatly minimised.

This operation is relatively slow, when compared to the actual /find call but it's impact on perceived website speed can be completely bypassed by preemptively generating the token before the end user has provided the necessary information to determine delivery options, for example, as soon as the user clicks the "Checkout" button. As soon as the backend process responsible for retrieving the token obtains it, it then needs to be exposed in the user browser, for example in the form of a cookie, so that the client side integration can use it to authorize /find calls immediately.


HTTP/1.1 200 OK
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy83TWJtdHNZVGFKMFA4RjRuMGx4dUk5Iiwic3ViIjoiL3JldGFpbGVycy80M2ZlMjFlYi04Zjg4LTRkZWEtODUwYy0xNDBhNzI5MDE2ZmQvYXBpS2V5cy8xSUYxQjVZT0FGUjU5QlRWOEY4V0lINkMyIiwic2NvcGUiOiJjYW4tcmV0cmlldmUtbG9jYXRpb25zIGNhbi1zZWFyY2gtbG9jYXRpb25zIGNhbi1tYW5hZ2Utb3BlbmluZy10aW1lcy1ydWxlcyBjYW4tc2VhcmNoLW9wdGlvbnMiLCJqdGkiOiJjZDU2MjhmMS1hY2RmLTQ2NzItYTRlYS0wZWI0NmNhOTRiOGIiLCJpYXQiOjE0ODcyNjE5NzksImV4cCI6MTQ4NzI2NTU3OX0.YTobXCQ1N0EEpqrz4baqnRsMkcAzMoeVpE9DvlRn5T0",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "can-retrieve-locations can-search-locations can-manage-opening-times-rules can-search-options"

The value for access_token is what to refer to as the JWT token, the remaining properties are purely informative.

POST /oauth HTTP/1.1
Authorization: Basic <base64(apiKeyId:apiKeySecret)>
Content-Type: application/x-www-form-urlencoded

$ curl -X POST -H "Authorization: Basic <base64(apiKeyId:apiKeySecret)>" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=client_credentials' "/oauth"
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials");
Request request = new Request.Builder()
  .addHeader("authorization", "Basic <base64(apiKeyId:apiKeySecret)>")
  .addHeader("content-type", "application/x-www-form-urlencoded")

Response response = client.newCall(request).execute();

(using OkHttp)

Find Options

With an access token, we can now perform a /find call.


See corresponding section.


Apart from the typical errors, the client will also receive the following, when performing a call after the token expires:

GET /find?<query string parameters> HTTP/1.1
Authorization: Bearer <bearer token>
$ curl -X GET -H "Authorization: Bearer <bearer token>" "/find?<query string parameters>"
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("/find?<query string parameters>")
  .addHeader("authorization", "Bearer <bearer token>")

Response response = client.newCall(request).execute();

(using OkHttp)

results matching ""

    No results matching ""