Metre Client API
OpenAPI-ready security guide
Metre Client API layers RSA + AES + HMAC on top of standard OpenAPI endpoints. This documentation walks through the integration guide, describes the security protocol, and explains the core workflows implemented in the `examples/cpp-client` code base.
100%
OpenAPI™
Standards compliant
C++ / Go / JS
Client SDKs
Generate instantly
Resilient
Heartbeat
Replay-safe tokens
Overview
The Metre Client API is designed for OpenAPI-first adoption while enforcing an encrypted handshake. Every critical POST request encrypts the payload with RSA-OAEP-SHA256 + AES-256-GCM, signs it with HMAC-SHA256, and bundles the membership information (token/expiresAt) inside a signed response that both client and server verify.
Security Protocol
Required headers
- Content-Type: application/json
- Authorization: Bearer <token>
- X-Metre-Timestamp: UNIX seconds
Encrypted payload
{
"appId": 1,
"data": "BASE64_AES_GCM_ENCRYPTED",
"signature": "HEX_HMAC_SHA256",
"timestamp": 1708000000
}Encryption steps
- Serialize the business payload to JSON, chunk it into at most 190 byte segments, and encrypt each chunk using RSA-OAEP-SHA256. Join the Base64 segments with colon separators.
- Build the string
signData = {appId}{plain}{timestamp}and HMAC-SHA256 it with the app secret; send the hex digest as `signature`. - Send both `data` and `signature`. The server decrypts first and then verifies the signature.
Signed response
{
"code": 0,
"data": {
"data": "{"token":"...","expiresAt":...}",
"signature": "HEX_HMAC"
}
}Compare `HMAC-SHA256(data.data, appSecret)` to `data.signature`. Only after the match should you trust the token + expiresAt fields.
Workflows
1. Fetch RSA public key
Call `GET /api/client/apps/{appId}/info` to retrieve the RSA-2048 public key, AES key, and HMAC secret used for all downstream requests.
2. Encrypted login + HMAC
For `POST /api/client/auth/login`, AES-256-GCM encrypt the payload and include an HMAC-SHA256 signature over `appId + plain + timestamp` to prevent tampering. The endpoint supports both account login (`email/password`) and card login (`mode=card` + `key/code` + `deviceId`), and the app-level `security_settings.login_mode` controls which path is enabled.
3. Verify membership signature
The server responds with `data.payload` (containing token/expiresAt/membership). Clients must verify its HMAC signature using the shared app secret before trusting membership data.
SDK Implementation Guide
Refer to examples/cpp-client/main.cpp for real code. Reuse the RSA+AES+HMAC steps and validate the signed membership before calling `challenge`, `heartbeat`, `recharge`, or `announcement`.
def make_client_request(payload, public_key, app_secret, app_id):
timestamp = int(time.time())
encrypted = rsa_encrypt(json.dumps(payload), public_key)
sign_data = f"{app_id}{json.dumps(payload)}{timestamp}"
signature = hmac.new(app_secret.encode(), sign_data.encode(), hashlib.sha256).hexdigest()
return {
"appId": app_id,
"data": encrypted,
"signature": signature,
"timestamp": timestamp,
}Additional Details
Challenge & Heartbeat
POST `/api/client/auth/challenge` to receive a program, execute it to compute a result, and submit `heartbeat` with `X-Metre-Challenge-Id` and `X-Metre-Challenge-Result` headers to keep the token alive.
Recharge
POST `/api/client/auth/recharge` consumes a metre card (card key). The request requires a valid token; the server signs the updated membership in the response.
Announcement / Variables
These endpoints deliver notices and runtime variables to clients; calls must include a membership-backed token.
OpenAPI Registry
Document the encrypted payload format alongside OpenAPI specs so SDK generators and teams understand the client handshake.