Use partner HMAC authentication when your backend calls Meridian directly with a Meridian API Key and Secret.
This is the mechanism that proves partner identity. It is required for POST /v1/auth/token and for any other API operation that supports partner-key authentication.
Partner-authenticated requests use these headers:
| Header | Required | Use |
|---|
X-Meridian-Api-Key | Yes | Issued by Meridian for the environment |
X-Meridian-Program-Id | Yes | Identifies the program context for the request |
X-Meridian-Timestamp | Yes | Timestamp used to validate request freshness and the signature |
X-Meridian-Signature | Yes | HMAC SHA-256 signature for the request |
X-Meridian-User-Id | MULTI_USER only | Identifies the Meridian user targeted by the request |
For SINGLE_USER integrations, omit X-Meridian-User-Id. Meridian uses the single configured user for that partner key.
When to send X-Meridian-User-Id
Your integration model determines whether X-Meridian-User-Id is required:
MULTI_USER: required on partner-key calls
SINGLE_USER: must be omitted on partner-key calls
This rule applies to token creation and to other partner-key API calls that accept direct partner authentication.
Constructing the signature
Meridian authenticates partner-key requests with an HMAC SHA-256 signature.
X-Meridian-Program-Id is required on the request, but it is not part of the canonical string used for signing.
Canonical string
Build the canonical string by concatenating these values in this exact order:
API Key
Timestamp
HTTP method
Request path
Request body
For example, for POST /v1/auth/token:
- the method is
POST
- the path is
/v1/auth/token
- the body is the exact JSON string sent on the wire
If there is no request body, use an empty string for the body portion of the canonical string.
How to compute the signature
- Read your Meridian API Key and API Secret for the environment you are calling.
- Generate a timestamp in milliseconds and send it as
X-Meridian-Timestamp.
- Serialize the JSON request body exactly as it will be sent.
- Concatenate the API Key, timestamp, method, path, and serialized body to form the canonical string.
- Compute the HMAC SHA-256 of that canonical string using your API Secret as the key.
- Hex-encode the result and send it as
X-Meridian-Signature.
Example
If your request is:
POST /v1/auth/token
X-Meridian-Api-Key: mer_test_123
X-Meridian-Program-Id: prog_abc123
X-Meridian-User-Id: user_123
X-Meridian-Timestamp: 1735689600000
Content-Type: application/json
{ "grant_type": "client_credentials" }
Then the canonical string is:
mer_test_1231735689600000POST/v1/auth/token{"grant_type":"client_credentials"}
Compute the HMAC SHA-256 of that canonical string using your API Secret, then hex-encode the output and send the result in X-Meridian-Signature.
Example code
import crypto from "crypto";
const apiKey = process.env.MERIDIAN_API_KEY;
const apiSecret = process.env.MERIDIAN_API_SECRET;
const programId = process.env.MERIDIAN_PROGRAM_ID;
const method = "POST";
const path = "/v1/auth/token";
const timestamp = Date.now().toString();
const body = JSON.stringify({
grant_type: "client_credentials",
});
const canonical = apiKey + timestamp + method + path + body;
const signature = crypto
.createHmac("sha256", apiSecret)
.update(canonical)
.digest("hex");
const headers = {
"Content-Type": "application/json",
"X-Meridian-Api-Key": apiKey,
"X-Meridian-Program-Id": programId,
"X-Meridian-User-Id": "user_123",
"X-Meridian-Timestamp": timestamp,
"X-Meridian-Signature": signature,
};
Token minting flow
Use POST /v1/auth/token when your backend needs a Meridian access token for a user.
SINGLE_USER: omit X-Meridian-User-Id; Meridian uses the user configured for that partner integration
MULTI_USER: include X-Meridian-User-Id to identify the target Meridian user
Depending on your flow, the token request body can:
- use
client_credentials for a target user
- use
refresh_token to exchange a refresh token for a new access token
For a first-time MULTI_USER flow, create the Meridian user first with POST /v1/auth/users, then mint the token for that userId.
If POST /v1/auth/users fails because externalId already belongs to an existing Meridian user, retry token creation only if you already know the stored userId from your own customer-to-user mapping.
Partner-key access beyond token minting
Some Meridian Accounts endpoints support direct partner-key authentication in addition to JWT bearer authentication. When the OpenAPI for an endpoint lists both partner API Key security and JWT security, your backend may call that endpoint directly with HMAC-signed partner credentials.
For client-facing account access, prefer JWT bearer authentication even when partner-key auth is technically supported.
Common authentication errors
The most common causes of HMAC authentication failures are:
- omitting
X-Meridian-Api-Key or another required partner header
- concatenating canonical string fields in the wrong order
- signing a different JSON string than the one actually sent
- including
X-Meridian-Program-Id in the canonical string
- sending
X-Meridian-User-Id for a SINGLE_USER integration
- omitting
X-Meridian-User-Id for a MULTI_USER integration
- using a timestamp outside the allowed 60-second window
- using Sandbox credentials against production, or production credentials against Sandbox
The signature is sensitive to field order, whitespace, and request path. If
the request body or path differs from what you signed, Meridian will reject
the request.