Skip to main content
Every request to the Futuur API must be authenticated. Authentication uses HMAC-SHA512 signatures generated from your public/private key pair. There are no bearer tokens or session cookies — each request is independently signed.

Get your API keys

Sign up at futuur.com and generate your keys from your account settings. You receive two keys:
  • Public key — included in every request as the Key header. Safe to log.
  • Private key — used to sign requests. Never share or log this value.

Required headers

Every authenticated request must include these three headers:
HeaderValue
KeyYour public key
TimestampCurrent Unix timestamp (seconds since epoch)
HMACSHA-512 hexdigest of the signed parameter string

Signing process

1

Collect parameters to sign

Gather all request parameters — query string parameters for GET requests, body parameters for POST requests — plus Key (your public key) and Timestamp (current Unix timestamp as an integer).
2

Sort alphabetically by key name

Sort all parameters (including Key and Timestamp) alphabetically by their key name. For example: Key, Timestamp, category sorts to Key, Timestamp, category — but if you have amount, it would come before Key.
3

URL-encode the sorted parameters

Join the sorted key-value pairs as a URL-encoded query string, for example:
Key=YOUR_PUBLIC_KEY&Timestamp=1234567890&category=5
4

Sign with your private key

Compute an HMAC-SHA512 digest using your private key as the secret and the URL-encoded string as the message. Use the hex digest (not base64).
hmac.new(private_key_bytes, encoded_params_bytes, sha512).hexdigest()
5

Add headers to your request

Include Key, Timestamp, and HMAC as request headers. Do not include the parameters again in the query string separately — they are already encoded in the signature.

Code examples

import hashlib
import hmac
import datetime
from collections import OrderedDict
from urllib.parse import urlencode

PRIVATE_KEY = "your_private_key"
PUBLIC_KEY = "your_public_key"

# Collect all request parameters plus Key and Timestamp
params = {
    "Key": PUBLIC_KEY,
    "Timestamp": int(datetime.datetime.utcnow().timestamp()),
    "category": 5,  # any query/body params for this request
}

# Sort alphabetically and URL-encode
params_to_sign = OrderedDict(sorted(params.items()))
encoded_params = urlencode(params_to_sign).encode("utf-8")
encoded_private_key = PRIVATE_KEY.encode("utf-8")

# Compute HMAC-SHA512
hmac_signature = hmac.new(encoded_private_key, encoded_params, hashlib.sha512).hexdigest()

# Build headers
headers = {
    "Key": PUBLIC_KEY,
    "Timestamp": str(params["Timestamp"]),
    "HMAC": hmac_signature,
}

# Make the request
import requests
response = requests.get(
    "https://api.futuur.com/events/",
    params={"category": 5},
    headers=headers,
)

GET vs. POST requests

  • GET requests: include all query string parameters in the parameter set you sign (in addition to Key and Timestamp).
  • POST requests: include all body parameters in the parameter set you sign. Do not mix query and body parameters.
If your GET request has no additional parameters (e.g., GET /me/), you still sign just Key and Timestamp.

Common errors

ErrorCause
InvalidHMACKeyThe public key in the Key header is not recognized. Check for typos or use the wrong key.
InvalidHMACSignatureThe computed signature does not match. Common causes: wrong sort order, missing parameters in the signed set, encoding mismatch, or using the wrong private key.
MissingTimestampThe Timestamp header is absent or malformed.
ExpiredTimestampThe timestamp is too far from the server’s current time. Ensure your system clock is synchronized (NTP).
Never include your private key in client-side code or commit it to version control. Treat it with the same care as a password.