Purchase API - authentication

The Purchase API uses client signing in order to secure your data and prevent any malicious requests. The steps below indicate how to use your API keys to sign your request and successfully authenticate. For complete code examples, see the appendix.

Task 1: Generate a checksum for the request content

In order to allow verification of the content of your request, you need to provide a SHA-256 checksum of your message content. In the pseudo-code below, the message_content variable contains the contents of the message you plan to send (this is the message body, without any headers). If your message content is empty (as is often the case for GET requests), substitute an empty string '' for the content:

Pseudocode for generating a message content checksum:

content_checksum = HexEncode(SHA256(message_content))

Sample content checksum for the string "sample payload":

eee57820203860ea469843dfba7bbb970021cae59fcc6e99056937bdec33fd02

Task 2: Collect Signature Elements

The unsigned request consists of a number of elements that you concatenate together into a single string ready for signing.

The first element is the request type you wish to use (GET, PUT, POST, DELETE) in all upper-case.

POST

The second element is the URI of the request itself, in canonical form. The canonical URI is the URI-encoded version of everything in the URI from the HTTP host, including any question mark character (?) and all query string parameters (if any). Normalize URI paths according to RFC 3986 by removing redundant and relative path components and convert everything to lower-case (except where upper-case is required in any parameters). In our case, we have:

https://purchase.api.abebooks.com/v1/orders

The third element exists to reduce the possibility of replay attacks (someone submitting your request again at a future time). To create this element, you construct a string containing the timestamp for this request. This timestamp should be expressed in ISO 8601 format (YYYY-MM-DDThh:mm:ssZ) using UTC. Your request is valid for five minutes from this timestamp.

2017-09-18T23:25:35Z

The fourth element is the content_checksum calculated in Task 1.

eee57820203860ea469843dfba7bbb970021cae59fcc6e99056937bdec33fd02

Task 3: Create the final string

To generate the final string used to create a request signature, you must concatenate all of these elements together, placing a single newline character between each. Using the examples above, pseudo-code to create the final string would be:

action = 'POST'
uri = 'https://purchase.api.abebooks.com/v1/orders'
abe_date = '2017-09-18T23:25:35Z'
content_checksum = 'eee57820203860ea469843dfba7bbb970021cae59fcc6e99056937bdec33fd02'
final_string = action + '\n' + uri + '\n' + abe_date + '\n' + content_checksum

Task 4: Generate the request signature

Before you can sign the final string, you will need a set of valid Purchase API credentials. These credentials consist of an access-key and a secret-key which can be obtained from https://www.abebooks.com/servlet/PurchaseApiKeys. In this example, assume the following credentials were obtained:

secret_key = '9ea20986-8f49-42f1-aa27-63EXAMPLEKEY'
access_key = 'EXAMPLEACCESSKEY'

Once you have the final string prepared, you generate the request signature by using the secret-key with a SHA-256 HMAC algorithm. Using the final_string from the code above, Pseudo-code is shown below

abe_signature = HMAC(secret_key, final_string, hashlib.sha256).hexdigest()

Signature for the example in Task 3:

35922da3a3b457cc0a7510fd7ae1be15e93b0dcc4cdb0db5ba87434a182fc585

Task 5: Submit the Request

With the signature in hand, you are ready to submit your request to the API. To do so, call the API with the appropriate request type (GET, POST) as used in your signing, and request the URI you signed, including all parameters. In your request, provide three extra headers. The first is the Abe-Date that you used during the signature. The second is your Purchase API access-key Abe-Access-Key. The third is the Abe-Signature which you calculated above. Finally in Abe-RequestId you must include a unique ID that can be used to reference the request. (It is strongly recommended to use GUIDs for this purpose.)

The full HTTP request for the example shown above will look something like the following:

POST https://purchase.api.abebooks.com/v1/orders' HTTP/1.1
Abe-Date: 2017-09-18T23:25:35Z
Abe-Access-Key: EXAMPLEACCESSKEY
Abe-Signature: 9b6156bdd88cddf86fee8bab59533fdb23bf3887a890b62bba606d36396e6100
Abe-RequestId: f27d1de5-e37e-4760-b00c-d539cd7ce68e

sample content