API Guide

Authorization

All authenticated endpoints use HMAC-SHA256 signature verification. Each request must include three custom headers that prove your identity and protect against replay attacks.

HMAC-SHA256 Authentication

All authenticated endpoints use HMAC-SHA256 signature verification. Each request must include three custom headers that prove your identity and protect against replay attacks.

Required Headers

HeaderDescription
X-Public-KeyYour business public key. Identifies which business is making the request.
X-TimestampCurrent Unix timestamp in seconds. Requests older than 5 minutes are rejected.
X-SignatureHMAC-SHA256 signature of the request (see below).

Generating the Signature

The signature is an HMAC-SHA256 hash of a signing string, using your private key as the secret.
Signing string format:
{timestamp}\n{METHOD}\n{path}\n{body}
ComponentDescriptionExample
timestampSame value sent in X-Timestamp1709836800
METHODUppercase HTTP methodGET
pathFull URI including query string, with leading //api/v1/events?count=5
bodyRaw request body (empty string for GET)(empty)
Components are joined by literal newline characters (\n).

Authentication Errors

StatusCodeDescription
401MISSING_CREDENTIALSOne or more required headers are missing.
401REQUEST_EXPIREDX-Timestamp is more than 5 minutes from server time.
401INVALID_CREDENTIALSPublic key not found, or signature does not match.
403ACCOUNT_INACTIVEBusiness account exists but is not active.

cURL

PUBLIC_KEY="your-public-key"
PRIVATE_KEY="your-private-key"
TIMESTAMP=$(date +%s)
PATH_URI="/api/v1/events?count=5"

# Build signing string: timestamp\nMETHOD\npath\nbody
SIGNATURE=$(printf '%s\n%s\n%s\n' "$TIMESTAMP" "GET" "$PATH_URI" \
  | openssl dgst -sha256 -hmac "$PRIVATE_KEY" | awk '{print $2}')

curl -H "X-Public-Key: $PUBLIC_KEY" \
     -H "X-Timestamp: $TIMESTAMP" \
     -H "X-Signature: $SIGNATURE" \
     "https://backend.localbusiness.pro$PATH_URI"

Node.js

const crypto = require("crypto");

const publicKey = "your-public-key";
const privateKey = "your-private-key";
const timestamp = Math.floor(Date.now() / 1000).toString();
const method = "GET";
const path = "/api/v1/events?count=5";
const body = "";

// Build signing string: timestamp\nMETHOD\npath\nbody
const signingString = `${timestamp}\n${method}\n${path}\n${body}`;
const signature = crypto
  .createHmac("sha256", privateKey)
  .update(signingString)
  .digest("hex");

const response = await fetch(`https://backend.localbusiness.pro${path}`, {
  headers: {
    "X-Public-Key": publicKey,
    "X-Timestamp": timestamp,
    "X-Signature": signature,
  },
});

console.log(await response.json());

Python

import hmac, hashlib, time, requests

public_key = "your-public-key"
private_key = "your-private-key"
timestamp = str(int(time.time()))
method = "GET"
path = "/api/v1/events?count=5"
body = ""

# Build signing string: timestamp\nMETHOD\npath\nbody
signing_string = f"{timestamp}\n{method}\n{path}\n{body}"
signature = hmac.new(
    private_key.encode(), signing_string.encode(), hashlib.sha256
).hexdigest()

response = requests.get(
    f"https://backend.localbusiness.pro{path}",
    headers={
        "X-Public-Key": public_key,
        "X-Timestamp": timestamp,
        "X-Signature": signature,
    },
)
print(response.json())

PHP

<?php
$publicKey = 'your-public-key';
$privateKey = 'your-private-key';
$timestamp = time();
$method = 'GET';
$path = '/api/v1/events?count=5';
$body = '';

// Build signing string: timestamp\nMETHOD\npath\nbody
$signingString = $timestamp . "\n" . $method . "\n" . $path . "\n" . $body;
$signature = hash_hmac('sha256', $signingString, $privateKey);

$ch = curl_init('https://backend.localbusiness.pro' . $path);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "X-Public-Key: $publicKey",
    "X-Timestamp: $timestamp",
    "X-Signature: $signature",
]);

$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));