Authentication

Introduction

To use the TinEye API, each request must be authenticated. Requests are authenticated by computing a digital signature using the HMAC-SHA256 signature method. A client must sign each API request using a secret private key that only the client and the tineye API server know.

The TinEye API also makes use of timestamp information and a client-generated request ID to ensure that no one else may use the API on the client’s behalf.

Authenticating API requests

Each TinEye API request must include the following query string parameters:

api_key The public key provided to a client that allows the TinEye API to know which client is making the API request.
api_sig A HMAC-SHA256 signature of the request that is generated by the client using their private key.
nonce A unique random ID generated by the client to identify the request.
date The date and time when the request was made.

api_key

When signing up for access to the TinEye API, each client is provided with a public key and a private key string. The private key string is used to sign the request and must never be included in an API request. The public key must, however, be included in each request so that the system can determine the client’s private key to generate the same request signature to allow or reject the request.

api_sig

This is the request signature. Signing a request is described in detail in the next section.

nonce

Nonce means a “number used once”, which for the API means a unique random string used to identify a request. The nonce must a unique random string at least 8 characters long. The nonce is used to prevent a “man in the middle attack”, where someone tries to repeat a request that a client has already made.

date

The date is the Unix epoch timestamp, the whole number of seconds since January 1, 1970 00:00:00 GMT. Requests must be made within 15 minutes of the server time or a “Request time is too skewed from server time” error will occur.

Signing a request

When making a request to the TinEye API the client must first generate a digital signature for the request using their secret private key. This signature is included in the request along with the client public key. When the TinEye API receives the request, the system determines the client’s private key from the given public key. The system then attempts to generate the same signature using the client’s private key. If the generated signature matches the signature in the request, the request is accepted and the action is performed. Otherwise, the server will return an error message.

Since only the client and the server have access to the client’s secret private key, nobody else can generate a valid request signature on the client’s behalf.

To ensure that the client request signature and the signature generated by the server match, the steps described below must be followed by both parties.

Signing process

Each request must be signed using the HMAC-SHA256 algorithm. Furthermore, use the hex digest for the string generated by the HMAC-SHA256 algorithm.

The string to sign for a request is generated by concatenating request-specific strings together:

client private key +
HTTP_VERB +
Content-Type header +
uploaded image name +
date +
nonce +
request_url +
other query string parameters
client private key The secret key string that only the client and the API server know. Nobody else should have access to this key. The key is also the key used in the HMAC function to generate the signature.
HTTP_VERB GET or POST in uppercase.
Content-Type header The content-type for POST requests, with keywords in lowercase. The boundary string itself may contain uppercase letters. For GET requests use an empty string “”.
uploaded image name The name of the image uploaded for image search POST requests. The uploaded image name must be URL encoded and then lowercased when generating the string to sign. For requests that do not have an uploaded image, use an empty string “”.
date The Unix epoch timestamp when the request was made. An integer string.
nonce The client-generated random unique request ID, which must be at least 8 characters.
request_url The TinEye API URL used to make the request, up to but not including the ”?”.
other query string parameters
  • do not include the api_key, api_sig, date, image_upload or nonce query string parameters
  • URL encode the image_url value if that parameter is present in the request
  • convert parameter names to lowercase
  • sort the parameters alphabetically by parameter name (e.g., offset=0, image_url=http%3A%2F%2Fsomething.com%2Fi.jpg, limit=3 sorts to image_url=http%3A%2F%2Fsomething.com%2Fi.jpg, limit=3, offset=0)
  • join parameter pairs with ampersands and no spaces (e.g., key1=value1&key2=value2&...)

URL encoding

For Image URLs

The image_url parameter needs to be URL encoded before being hashed as part of the signature. Note that for image URLs we encode spaces as + instead of %20. For our purposes it must have non-alphanumeric characters encoded, including forward slashes (/) and percent signs (%), but not including the hyphen (-), period (.), tilde (~) and underscore (_). The encoding must be done with uppercase hexadecimal digits, e.g., %2F, not %2f, for a slash character.

For Uploaded Images

Similarly, the uploaded image names must be URL encoded before being hashed as part of the signature. Note that for uploaded image filenames, we encode spaces as + instead of %20. Non-alphanumeric characters must be encoded, including forward slashes (/) and percent signs (%), but not including the hyphen (-), period (.), tilde (~) and underscore (_). The URL encoded filename must also be lowercased before it is hashed.

Verify signature

To verify whether your generated HMAC-SHA256 signature is correct, please use this site:

Examples

GET request example

Client Keys and parameters:

- public key: LCkn,2K7osVwkX95K4Oy
- private key: 6mm60lsCNIB,FwOWjJqA80QZHh9BMwc-ber4u=t^
- offset: 0
- limit: 30
- image_url: https://tineye.com/images/meloncat.jpg
- date: 1490027472
- nonce: b51f8e899bfbb8811a82fbab34067d60

GET Request URL, without signature but with encoded image_url parameter:

https://api.tineye.com/rest/search/?api_key=LCkn,2K7osVwkX95K4Oy&offset=0&limit=30&image_url=https%3A%2F%2Ftineye.com%2Fimages%2Fmeloncat.jpg&date=1490027472&nonce=b51f8e899bfbb8811a82fbab34067d60

String to Sign:

6mm60lsCNIB,FwOWjJqA80QZHh9BMwc-ber4u=t^GET1490027472b51f8e899bfbb8811a82fbab34067d60https://api.tineye.com/rest/search/image_url=https%3A%2F%2Ftineye.com%2Fimages%2Fmeloncat.jpg&limit=30&offset=0

HMAC-SHA256 Signature:

4485dc94325d07af9129c610c750aeee2f7ba394278c0ba324fad7e543817eb4

GET Request URL, with signature:

https://api.tineye.com/rest/search/?api_key=LCkn,2K7osVwkX95K4Oy&offset=0&limit=30&image_url=https%3A%2F%2Ftineye.com%2Fimages%2Fmeloncat.jpg&date=1490027472&nonce=b51f8e899bfbb8811a82fbab34067d60&api_sig=4485dc94325d07af9129c610c750aeee2f7ba394278c0ba324fad7e543817eb4

POST request example

Client Keys and parameters:

- public key: LCkn,2K7osVwkX95K4Oy
- private key: 6mm60lsCNIB,FwOWjJqA80QZHh9BMwc-ber4u=t^
- offset: 0
- limit: 30
- image data filename: meloncat.jpg
- date: 1490028412
- nonce: 2872eeee260c59b67cda01c36686f056

POST Request Without Signature:

This is what an image search POST request to https://api.tineye.com/rest/search/ may look like:

POST /rest/search/ HTTP/1.1
Host: api.tineye.com
User-Agent: <my user agent or uploader lib>
<other headers>
Content-Length: 3549
Content-Type: multipart/form-data; boundary=d8b4f160da95---------------d8b4f160da95

--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="image_upload"; filename="meloncat.png"
Content-Type: application/octet-stream

<the POSTed image meloncat.jpg>
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="api_key"

LCkn,2K7osVwkX95K4Oy
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="date"

1490028412
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="limit"

30
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="offset"

0
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="nonce"

2872eeee260c59b67cda01c36686f056
--d8b4f160da95---------------d8b4f160da95--

Important Notes

  • The Content-Type header value to use for signing in this example is
    multipart/form-data; boundary=d8b4f160da95---------------d8b4f160da95
  • The boundary string for any one search may be different from this example.

  • Be sure to end the final POST boundary line with two hyphens (–).

  • Each of the boundary separators has two hyphens (–) before the boundary value specified in the Content-Type header.

  • The filename in the image_upload part is not URL encoded, but it is encoded where it appears in the string to sign.

String to Sign:

6mm60lsCNIB,FwOWjJqA80QZHh9BMwc-ber4u=t^POSTmultipart/form-data; boundary=d8b4f160da95---------------d8b4f160da95meloncat.jpg14900284122872eeee260c59b67cda01c36686f056https://api.tineye.com/rest/search/limit=30&offset=0

HMAC-SHA256 Signature:

902fb2baa48e058a6e9d0203d427b1015a2873e1c293530a2997d8c0dfad1bbe

POST Request With Signature:

POST /rest/search/ HTTP/1.1
Host: api.tineye.com
User-Agent: <my user agent or uploader lib>
<other headers>
Content-Length: 3549
Content-Type: multipart/form-data; boundary=d8b4f160da95---------------d8b4f160da95

--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="image_upload"; filename="meloncat.jpg"
Content-Type: application/octet-stream

<the POSTed image meloncat.jpg>
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="api_key"

LCkn,2K7osVwkX95K4Oy
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="date"

1490028412
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="limit"

30
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="offset"

0
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="nonce"

2872eeee260c59b67cda01c36686f056
--d8b4f160da95---------------d8b4f160da95
Content-Disposition: form-data; name="api_sig"

902fb2baa48e058a6e9d0203d427b1015a2873e1c293530a2997d8c0dfad1bbe
--d8b4f160da95---------------d8b4f160da95--

Signing algorithm libraries

The TinEye API uses the HMAC-SHA256 algorithm for signing requests. Libraries for the HMAC algorithm can be found below. Please note: The TinEye API only accepts the SHA256 hashing algorithm with HMAC.

We do not provide support for any of the following libraries. Please contact the authors directly about any problems.

Python docs.python.org/library/hmac.html Note that you must call for SHA256 explicitly; it is not the default.
PHP secure.php.net/manual/en/function.hash-hmac.php
Ruby ruby-hmac.rubyforge.org/
Javascript github.com/Caligatio/jsSHA/
.NET msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256.aspx