Authentication

Authentication is needed if you want to be able to do an API write operation, like edit a user's profile information or upload an item (pin) for example.

API Endpoint

https://www.historypin.org/en/api/

API Pair and Token

The API Pair is a combination of user's API key and user's API shared secret. Currently this is the only way to authenticate through the API programatically.

API Key

The API key is a 64 character string randomly generated for user's account.

Example

API_KEY = 'e519f7e8481e2002f9874cf10ac19bfca533704746d02b98ee9f9f6baa3231d8'

API Shared Secret

The API shared secret is a 32 character string randomly generated for user's account.

Example

API_SECRET = '4a37d542252bd03300a8e79131f9624c'

NOTE: This string MUST be kept secret at all times otherwise it will compromise user's security. It must be used ONLY when generating the API Token

Get your API keys

API Keys can be taken from user's profile edit view in the section "API Settings" at the bottom of the page.

If the fields are empty, the API pair can be generated by clicking "Generate API Pair"

API Token

The API Token is a hash that validates the user sending the request.

It is generated by concatenating all request path and request data in specific way. First all key and values are concatenated into a pair with =. then all pairs are ordered alphabetically and concatenated with &.

Example

Request Data, Path:

Request data consists of data send through query string and post data .

api_path = 'user/get_edit.json'

data = {
    'id'              : 19,
    'example_variable': 123,
    'api_key'         : 'e519f7e8481e2002f9874cf10ac19bfca533704746d02b98ee9f9f6baa3231d8',
}

Concatenate key and value. Order alphabetically

data = [
    'api_key=e519f7e8481e2002f9874cf10ac19bfca533704746d02b98ee9f9f6baa3231d8',
    'api_path=user/get_edit.json',
    'example_variable=123',
    'id=19',
]

Concatenate pairs

BODY = 'api_key=e519f7e8481e2002f9874cf10ac19bfca533704746d02b98ee9f9f6baa3231d8&api_path=user/get_edit.json&example_variable=123&id=19'

Generate Token

For the token generation we use HMAC with SHA256 as digest module and the shared secret is our crypto key. After that the API Token is send with the request variables as get argument.

api_token = hmac.new(API_SECRET), BODY, hashlib.sha256).hexdigest()
api_token = '0083a327ee8f63e9f57829dc58214bd63a078c7fcd69f369d54e4fd28a7df7d3' # Example Token

Code Example

import hmac, hashlib
from collections import OrderedDict

API_SECRET = '4a37d542252bd03300a8e79131f9624c'

data = {
    'id'              : 19,
    'example_variable': 123,
    'api_key'         : 'e519f7e8481e2002f9874cf10ac19bfca533704746d02b98ee9f9f6baa3231d8',
    'api_path'        : 'user/get_edit.json',
}

BODY = '&'.join(['{}={}'.format(k, v) for k, v in OrderedDict(sorted(data.items() + postdata.items())).items()])

api_token = hmac.new(API_SECRET, BODY, hashlib.sha256).hexdigest()

Sending Requests

Code Example

import hmac, hashlib, requests
from collections import OrderedDict

from requests.api import post

def api_call(path, querydata = {}, postdata = {}, api_key = '', api_secret = ''):
    BASE = 'https://www.historypin.org/en/api/'

    querydata['api_key'] = api_key
    BODY = '&'.join(['{}={}'.format(k, v) for k, v in OrderedDict(sorted(querydata.items() + postdata.items() + [('api_path', path)])).items()])
    api_token = hmac.new(api_secret, BODY, hashlib.sha256).hexdigest()
    querystring = '&'.join(['{}={}'.format(k, v) for k, v in querydata.items()])
    url = '{}{}?{}&api_token={}'.format(BASE, path, querystring, api_token)

    return requests.post(url, data = postdata)


response = api_call(
    path = 'comments/post.json',
    postdata = {
        'item_id' : 1089880,
        'copy': 'lorem ipsum dolor cit amet...',
    },
    api_key = 'e519f7e848189b352f7d8231e907bcb1b7e4360f1898d740f62b9fe041e61481',
    api_secret = 'd883a3e32a7865c088ed2d97d1896e32',
)

print(response.content)