HMAC Identity Verification (Lookup Key)
This article is intended for admins who enable identity verification and developers who implement the signing and key-management logic on their servers.
Overview
Identity verification confirms that a logged-in user in your application is who they claim to be before Gainsight PX accepts data for that user. Your server signs a checksum using a shared secret key, and Gainsight PX validates that checksum on every identify call.
This method protects the complete identify payload, including all user and account fields, from unauthorized changes. It also supports nonce rotation to prevent previously generated checksums from being reused indefinitely.
The lookup key method for HMAC identity verification must be enabled for your subscription. Contact Gainsight Support to request access. If you use the user hash method, refer to HMAC Identity Verification (User Hash) article instead.
Three concepts drive this method:
- Lookup key: A value you generate and register with Gainsight PX. You send this in every identify call.
- Nonce: A value Gainsight PX generates and maps to your lookup key. You use it to build the string you sign, but you never send it in an identify call.
- Checksum: The HMAC-SHA256 signature you compute and send with each identify call, so Gainsight PX can confirm the payload has not been altered.
This method is available in the Gainsight PX WebSDK.
Prerequisites
Confirm the following before you register a key:
- Feature enabled: The HMAC dynamic key feature must be enabled for your subscription from Administration > SECURITY > Identity verification.

- API key: You need a Gainsight PX API key to call the registration, retrieval, rotation, and deletion endpoints. Pass it in the
X-APTRINSIC-API-KEYheader. - Subscription secret key: You need your subscription secret key to compute the checksum. This is the same secret key used for other Gainsight PX server-side signing.
Key Considerations
Design your integration around these operational rules:
- Key limit: Each subscription can have a maximum of 25 active keys.
- Key and nonce TTL: Each key-nonce pair expires 90 days after creation. Plan to rotate keys before they expire.
- Cache the nonce: Cache the nonce on your server after registration, and use your cached copy to generate checksums. Do not retrieve the nonce for each identify call.
- Propagation delay: Allow approximately two minutes after registration or rotation before signing identify calls with the new nonce.
- Rate limits: Every key-management endpoint (register, retrieve, rotate, and delete) is rate limited. Design your integration so key management happens occasionally, not as part of your regular request flow.
How HMAC Identity Verification Works
At a high level, the flow is:
- Register a Key and Get a Nonce: Register a lookup key with Gainsight PX and receive a nonce in return. Cache the nonce on your server. Do this once per key, or again ahead of a planned rotation.
- Generate the HMAC Checksum: Generate the checksum by signing a canonical string that includes your user fields, your account fields, and the nonce.
- Send the Identify Call: Send the lookup key and the checksum in your identify call.
- Verify the Payload: Gainsight PX resolves the nonce associated with the lookup key, rebuilds the canonical string, and verifies the checksum.
If the cached nonce is unavailable, use the nonce retrieval API to recover it. Do not retrieve the nonce as part of the regular identify flow. For more information, refer to the Retrieve a Nonce section.
Do not send the nonce in the identify call. Send the lookup key in the nonceKey field.
Implement HMAC Identity Verification
Complete the following steps to implement HMAC identity verification in your application.
Register a Key and Get a Nonce
Register a lookup key to receive a nonce from Gainsight PX.
Endpoint
POST /v1/subscription/identify/nonce
Authentication
X-APTRINSIC-API-KEY: <your-api-key>
Request
POST /v1/subscription/identify/nonce
{
"key": "my-random-lookup-key-abc123"
}
Response
{
"key": "my-random-lookup-key-abc123",
"nonce": "9d1e4b72-cc38-4f01-b883-2a5f0d916e44",
"createdAt": 1755000000000,
"createdBy": "user@example.com",
"expiresAt": 1762776000000
}
Registering a key that already exists does not overwrite it. If you submit a key that is already registered, the request fails with a 409 KEY_ALREADY_EXISTS error. For more information on how to issue a new nonce for an existing key, refer to the Rotate a Key section.
Cache the nonce on your server after registration. You use the nonce to generate checksums for subsequent identify calls.
A newly registered key takes approximately two minutes to reach Gainsight PX. Identify calls signed with its nonce are rejected until propagation completes, even though the key already shows a status of ACTIVE.
Generate the HMAC Checksum
Ensure that you follow the specified field order and formatting when building the canonical string. Incorrect ordering or formatting causes the identify call to fail verification.
Build the canonical string in this exact order:
- Sort your user fields alphabetically by field name, and list each as
field=value. - Sort your account fields alphabetically by field name, and list each as
field=value. - Append the nonce as the final segment, in the form
nonce=<nonce-value>. - Join all segments with a pipe (
|) character.
Example
User fields:
email=jane.doe@acme.com firstName=Jane id=user-001 lastName=Doe
Account fields
id=acme-corp plan=enterprise
Canonical string
email=jane.doe@acme.com|firstName=Jane|id=user-001|lastName=Doe|id=acme-corp|plan=enterprise|nonce=9d1e4b72-cc38-4f01-b883-2a5f0d916e44
Checksum
checksum = HMAC-SHA256(yourSubscriptionSecretKey, canonicalString)
Sign the canonical string with your subscription secret key, not with the nonce. The nonce is part of the string being signed; it is never used as the signing key. A checksum signed with the nonce is rejected.
Field values are not escaped or encoded before they are joined. Send them exactly as they appear in your identify call, including any values that contain a | or = character.
Send the Identify Call
Pass the checksum and your lookup key in the identify call, as a single options object: the fourth argument, after the integration context.
aptrinsic("identify",
{
"id": "user-001",
"email": "jane.doe@acme.com",
"firstName": "Jane",
"lastName": "Doe"
},
{
"id": "acme-corp",
"plan": "enterprise"
},
null,
{
checksum: "<computed-checksum>",
nonceKey: "my-random-lookup-key-abc123"
}
);
checksumis the value you computed in the previous step.nonceKeycontains your lookup key, not the nonce.
If you send the identify request directly, rather than through the WebSDK helper, the checksum value is carried in a field named payloadChecksum on the wire. nonceKey keeps the same name in both places.
Manage Lookup Keys
After you implement HMAC identity verification, you can retrieve, rotate, or delete lookup keys as needed.
Retrieve a Nonce
Use this endpoint to recover a nonce or review your registered keys, for example after a server restart.
Endpoint
GET /v1/subscription/identify/nonce
Authentication
X-APTRINSIC-API-KEY: <your-api-key>
- Pass
?key=<your-key>to retrieve a single key. - Omit the
keyparameter to return every key registered for your subscription.
Single-key Response
{
"key": "my-random-lookup-key-abc123",
"nonce": "9d1e4b72-cc38-4f01-b883-2a5f0d916e44",
"createdAt": 1755000000000,
"expiresAt": 1762776000000,
"lastModifiedAt": 1755000000000,
"createdBy": "user@example.com",
"lastModifiedBy": "user@example.com",
"status": "ACTIVE"
}
List Response (No Key Parameter)
{
"keys": [ /* one entry per key, same shape as above */ ],
"total": 3,
"cap": 25
}
This endpoint is rate limited. Use it for recovery only. Do not call it on every identify call, or in real time during normal application use. Cache the nonce locally instead.
Rotate a Key
Rotate a lookup key to generate a new nonce for the existing key, without changing the key name. Because key-nonce pairs expire after 90 days, plan to rotate before expiration.
Rotating a key generates a new nonce for that key and invalidates the previous one.
A rotated key takes approximately two minutes to reach Gainsight PX. There is also a two-minute grace period after rotation during which identify calls signed with the old nonce are still accepted, to cover requests already in flight. Re-sign your identify calls with the new nonce once propagation completes, and do not rely on the grace period lasting longer than two minutes.
Endpoint
PUT /v1/subscription/identify/nonce/{key}
Authentication
X-APTRINSIC-API-KEY: <your-api-key>
API Errors
| HTTP Status | Error Code | Meaning |
|---|---|---|
| 400 | N/A | The key field is missing or empty in a register request. |
| 401 | N/A | Your API key is missing or invalid. |
| 403 | FEATURE_DISABLED | The HMAC dynamic key feature is not enabled for your subscription. |
| 404 | N/A | No key was found for the value you provided. This means the key was never registered, or it has expired. |
| 409 | KEY_ALREADY_EXISTS | You submitted a key that is already registered. Use rotate instead. |
| 409 | CAP_EXCEEDED | Your subscription has reached its maximum of 25 active keys. |
| 409 | CONCURRENT_MODIFICATION | Two rotation requests for the same key were submitted at the same time. Retry the rotation. |
Error responses are returned in a consistent structure: status, errorMessage, errorCode, and timestamp.
Troubleshoot Identify Calls Rejected with a Generic Error
Gainsight PX returns the same generic rejection for several distinct causes: an incorrect nonce, a tampered payload, a key that has not finished propagating, or a missing checksum. Work through this checklist:
- Confirm you signed with your subscription secret key, not the nonce.
- Confirm the canonical string field order matches exactly: sorted user fields, then sorted account fields, then
nonce=<value>. - Confirm you sent the lookup key (
nonceKey), not the nonce itself, in the identify call. - Confirm the key has finished propagating (allow two minutes after registration or rotation).
- Confirm the key has not expired (90-day TTL).