Skip to main content
Optimization Protection

Public keys

A public key is a cipher that allows you to verify if the source of the callback notification is valid and from a secure J.P. Morgan system.

How public keys work

Step 1: Webhook notification delivery

Notifications sends the following headers as part of the webhook notification delivery:

  • Signature: Digital signature of the notification payload.
  • Key-ID: Key ID of the key pair used for the digital signature.
  • Signing algorithm: Algorithm used to generate the digital signature. The value will be EC (Elliptic Curve).

Step 2: Obtaining the public key

To verify the signature, the receiving party needs the public key of the key pair used to sign the payload. The public key can be obtained by following these steps:

  1. Use the public key endpoint (/public-keys) to access the public key.
  2. The API returns the response in JSON Web Key Set (JWKS) format.
  3. Check the expiry date and time of the public key in the value of the field exp to plan your key rotation ahead of time.
  4. Convert the JWKS format into PEM (Base64 encoded) format for the key with the EC kty (key type)

Step 3: Signature verification

To verify the signature, you must perform the following steps:

  1. Take the Base64 encoded key obtained from Step 2.
  2. Decode the Base64 encoded public key.
  3. Use the decoded public key to create a public key object with the EC algorithm using your preferred cryptography library.
  4. Decode the Base64 encoded signature received in the notification signature header.
  5. Use the verify signature functionality in your cryptography library to validate the decoded signature with your public key object and notification body using the SHA256withECDSA algorithm
Note

A few things to keep in mind:

  • The public key expires after 365 days from when it was created, not from when you retrieve it.
  • When the public key expires, you must retrieve the new public key information via GET /public-keys.
  • You can see the expiry date and time of the public key in the value of the field exp.

The following is an example of how you can retrieve the public key information.

HTTP method: GET

Endpoint: /public-keys

Scenario: Retrieving a public key

{
    "keys": [
        {
            "kid": "6599834191ad40b79a309d7a4702a1db",
            "kty": "RSA",
            "n": "0A6tY59w6ue-V54Abtvju7xcHyYdLGnbTyf2YvmFk9-D08ImUkrzVH4eANVzR-9ch3Ih3WvXqe52h1mtKLnAxlb4elg5WRMEJdEatUKyWRKJyiop4x7bk3b2OlTTqm83SITrLqp4BE35H05BQ1bPBFoSZLz3i2xQNzV4cOUOfdplR4iGiFrkUna1C9nGmgXcPayT-S6DasoKF_rhvoruoDXgitK6IjuIBBCe3Lt4XGK1_EJr4WTqTBlbnFD7WMqHMnXqQuXw6MgOTn5dstOOXIr8gqFaTtxyGDPWx4DMR4n4kd0VdYYHmQhumm5kKHzP0l6a1WKJHu0IdP45F-Bk5o61MMYvpzgTiEwcjOu70IrVZxx_DCZ9uE9KUBHjsnAkvwwY21waB6llNWBm4oLmGLbBb7IVP-enwFipFqsv9A_CWhu-gigyf6HIKJuvtFT3bD1n5LRFVoC-y_FAJs0vettPAwuTfWfjvzcPkV58wSdg4ulflgRAjgwB_eDE52cB",
            "e": "AQAB",
            "use": "sig",
            "exp": "2025-10-23T11:30:25.477Z"
        },
        {
            "kid": "4d56e5f1db9a430e8dd8b5d916aa72e9",
            "kty": "EC",
            "crv": "P-256",
            "x": "qNB5v_fJaN69N0EQU_ERDeGEjzGs7MWIXeXD1gKCPl0",
            "y": "msXtGZRc_qHXYMjI0AaJNAJ-lrf8hhpLPoDa7XSZZoM",
            "use": "sig",
            "exp": "2026-02-21T13:15:28.755Z"
        }
    ]
}