Credential Rotation

Get in-depth info on how to rotate credentials through an API in Cards Connect

⚠️

Card Present Gateway

If you want to access information about our in-store offering, you may check the API specifications here: In-store Transactions Overview


To enhance security and comply with best practices, Cards Connect provides an API endpoint that allows for fully automated, client-driven credential rotation. This process enables a zero-downtime transition to a new credential, ensuring that service is never interrupted.

This page outlines the process for building an automated system to periodically rotate your API credentials.

The Rotation Process

The rotation mechanism involves creating a new credential and setting a defined expiry for the current (old) credential. This creates a graceful transition period during which both the old and new credentials can be valid, allowing your systems to seamlessly switch to the new key without service disruption.

An automated system should follow these steps:

  1. Generate New Key Pair: Your system must generate a new cryptographic key pair (private and public) in the standard JSON Web Key (JWK) format. The kid (Key ID) of this new key will serve as the unique identifier for your new credential and must not be the same as any of your existing or previous credential kids.
  2. Call the Rotate Credential Endpoint: Your system will make a PUT request to the rotation endpoint. This request must be signed using the current (soon-to-be-old) private key. The request specifies the public key of the new credential, the expiry date for the new credential, and a new, nearer expiry date for the current credential.
  3. Transition to New Key: Upon receiving a successful 201 Created response, the rotation is complete on the Cards Connect side. Your system should:
    • Securely store and begin using the new private key to sign all subsequent API requests.
    • The old key will remain valid until the CurrentKeyExpiry time you specified in the rotation request.
    • Once the old key has expired, it should be securely destroyed.

Endpoint Definition

To rotate the credential used to sign the current request, call the following endpoint:

PUT /api/v1/keys/credential/rotate-to/{keyId}

ParameterLocationDescription
keyIdPathThe Key ID (kid) of the new credential.

The request must be authenticated with a JWS signature generated using the current credential's private key.


Request Payload

The body of the request must contain the details for the new credential and the updated expiry for the current one.

FieldTypeDescriptionRequired
PublicKeyObjectA JWK representation of the new public key. See section 8.3.1 for details.Yes
ExpirationStringThe UTC date and time when the new credential will expire, in ISO 8601 format. This cannot be more than 365 days in the future.Yes
CurrentKeyExpiryStringThe new UTC expiry date and time for the current credential, in ISO 8601 format. We recommend a short overlap (e.g., 24-72 hours) to ensure a smooth transition. This cannot be more than 14 days in the future.Yes

Public Key Object

FieldTypeDescriptionRequired
KtyStringKey Type. Must be EC.Yes
KidStringKey ID. Must match the {keyId} in the URL.Yes
UseStringPublic Key Use. Must be sig.Yes
CrvStringCryptographic Curve. Must be P-256.Yes
XStringThe X coordinate for the EC key (Base64Url).Yes
YStringThe Y coordinate for the EC key (Base64Url).Yes

Sample Rotation Request

Here is an example of a PUT request to rotate from a credential with kid = e585e505-a8c2-4809-a46c-e5a0f6b43f9a to a new credential with kid = d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1.

Request: PUT /api/v1/keys/credential/rotate-to/d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1

Headers: Authorization: JWS <Signed with private key for e585e505...> Content-Type: application/json

{
  "PublicKey": {
    "Kty": "EC",
    "Kid": "d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1",
    "Use": "sig",
    "Crv": "P-256",
    "X": "usM_A8GveSS31e_f53t5v50_G8Z2p4e1e8R2v_Z1z4E",
    "Y": "n8t5v_A8GveSS31e_f53t5v50_G8Z2p4e1e8R2v_Z1z"
  },
  "Expiration": "2026-06-27T14:30:00Z",
  "CurrentKeyExpiry": "2025-06-28T14:30:00Z"
}

A successful request will return a 201 Created status code with an empty body. If the request fails, standard API error responses will be returned.