Skip to main content

HMAC Authentication

HMAC (Hash-based Message Authentication Code) is the authentication method used to secure requests to the Mekari POS API.

Overview​

An HMAC credential consists of a Client ID and a Client Secret, which are tied to a single company. You can only access data belonging to the company associated with your credentials.

To make an authenticated API request, you generate an HMAC-SHA256 signature from the request details and attach it to the Authorization header along with a Date header.

info

To obtain HMAC credentials for Mekari POS, create an application on the Mekari Developer portal. Each application is scoped to one company and one Mekari product.

Authorization Header​

Every API request must include an Authorization header with the following format:

Authorization: hmac username="<client_id>", algorithm="hmac-sha256", headers="date request-line", signature="<signature>"
ParameterDescription
usernameYour application's Client ID
algorithmDigital signature algorithm used to create the signature, in this case hmac-sha256
headersList of HTTP header names, separated by a single space character, used to sign the request. In this case date and request-line
signatureBase64-encoded HMAC-SHA256 signature generated from the request

Generating the Signature​

The signature is an HMAC-SHA256 hash of a payload string, encoded in Base64. The payload is constructed from the Date header value and the request line.

Pseudocode:

date_string    = current_datetime_in_rfc7231_format()
request_line = "<HTTP_METHOD> <path> HTTP/1.1"
payload = "date: <date_string>\n<request_line>"
digest = hmac_sha256(payload, client_secret)
signature = base64_encode(digest)

The request line uses the full path on the gateway, starting with /v2/mekari-pos/v2. See Query string for how the query is handled.

Concrete example for a POST request to /v2/mekari-pos/v2/categories:

date_string    = "Fri, 09 Oct 2026 10:30:00 GMT"
request_line = "POST /v2/mekari-pos/v2/categories HTTP/1.1"
payload = "date: Fri, 09 Oct 2026 10:30:00 GMT\nPOST /v2/mekari-pos/v2/categories HTTP/1.1"
digest = hmac_sha256(payload, "<YOUR_CLIENT_SECRET>")
signature = base64_encode(digest)

Query string​

MAG (the Mekari API gateway) applies two rules when it checks the signature of a request that has a query string:

  • If you sign the path with the query, for example GET /v2/mekari-pos/v2/customers?limit=50 HTTP/1.1, the signature is valid only for exactly that query.
  • If you sign the path without the query, for example GET /v2/mekari-pos/v2/customers HTTP/1.1, the signature is valid for any query on that path.

The code examples below sign the path only, so one signature works with any query.

For language-specific implementations, see the code examples:

Date Header​

Every request must include a Date header containing the current UTC datetime in RFC 7231 format.

Date: Fri, 09 Oct 2026 10:30:00 GMT

The Date header value must match the datetime used when generating the signature. A clock skew tolerance of 300 seconds is enforced — if the difference between the Date header and the server's current time exceeds 5 minutes, the request is rejected.

warning

Always generate the Date header value and signature at the same time. Using a stale or pre-computed date causes authentication failures.

Complete Request Example​

A fully authenticated POST request in cURL format that creates a product category:

curl --request POST 'https://api.mekari.com/v2/mekari-pos/v2/categories' \
--header 'Authorization: hmac username="<YOUR_CLIENT_ID>", algorithm="hmac-sha256", headers="date request-line", signature="<SIGNATURE>"' \
--header 'Date: Fri, 09 Oct 2026 10:30:00 GMT' \
--header 'Content-Type: application/json' \
--header 'X-User-ID: <A_USER_ID_FROM_GET_USERS>' \
--header 'Idempotency-Key: <A_UNIQUE_KEY_PER_REQUEST>' \
--data-raw '{"name": "Beverages"}'

Required headers summary:

HeaderRequiredDescription
AuthorizationAlwaysHMAC signature string
DateAlwaysCurrent UTC datetime in RFC 7231 format
Content-TypeRequests with a bodyapplication/json
X-Outlet-IDOutlet endpoints (see the API reference)The outlet id from GET /outlets
X-User-IDWrites (POST, PUT, PATCH, DELETE), with exceptions (see below)The acting staff user's id from GET /users. See Outlets and Acting User
Idempotency-KeyWrites that create a record; not used on quotes and approvalsA unique key per request, so a retry never creates a duplicate. See Idempotency

X-User-ID is optional on POST /orders, and not needed on PUT /order-source and the webhook endpoint calls. It is also optional on POST /returns/quote, POST /returns and POST /refunds in one narrow case: your own partner order, refunded to your partner rail, with no approval needed. Every other write needs it. See Outlets and Acting User for the rules.

Idempotency-Key is required on the POST calls that create a record (for example POST /orders, POST /returns), optional on PUT, PATCH and DELETE, and not used on quotes (POST /returns/quote, POST /exchanges/quote) and POST /approvals/.... See Idempotency.

Code Examples​

Set up HMAC authentication in your preferred language: