Skip to main content
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.

Required headers

Partner-authenticated requests use these headers:
HeaderRequiredUse
X-Meridian-Api-KeyYesIssued by Meridian for the environment
X-Meridian-Program-IdYesIdentifies the program context for the request
X-Meridian-TimestampYesTimestamp used to validate request freshness and the signature
X-Meridian-SignatureYesHMAC SHA-256 signature for the request
X-Meridian-User-IdMULTI_USER onlyIdentifies 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:
  1. API Key
  2. Timestamp
  3. HTTP method
  4. Request path
  5. 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

  1. Read your Meridian API Key and API Secret for the environment you are calling.
  2. Generate a timestamp in milliseconds and send it as X-Meridian-Timestamp.
  3. Serialize the JSON request body exactly as it will be sent.
  4. Concatenate the API Key, timestamp, method, path, and serialized body to form the canonical string.
  5. Compute the HMAC SHA-256 of that canonical string using your API Secret as the key.
  6. 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.