Receive payment hold notification via webhook
In this tutorial, you will learn how to receive payment hold notifications via webhook. By the end, you will understand:
- The types of notifications you receive
- How events reach your application
- How to interpret the notification body for each event
Before you begin
To process a payment hold notification request, you need the following:
- A registered and fully onboarded developer account on the J.P. Morgan Payments Developer Portal.
- A callback REST endpoint to receive payment hold events through webhooks. Work with your technical implementation manager to configure this endpoint.
Processing a payment hold placed event
A hold placed event occurs when a payment triggers a J.P. Morgan rule that requires the payment to be reviewed. This event is sent only once per hold. When receiving this event via webhook, your application should persist the hold to your own storage so it can be presented to your users for decisioning.
Sample response:
{
"specversion": "1.0",
"id": "7d2a159b-9c3a-4db2-bd03-e64047c32917",
"time": "2026-02-01T14:15:22Z",
"type": "com.jpmorgan.payments.payment.hold.placed.v1",
"source": "api.payments.jpmorgan.com/trust-safety/v1",
"dataschema": "urn:com.jpmorgan.payments/payment-hold",
"data": {
"id": "06bca14f-1fc0-4cd7-9e0b-8bb7e06334f7",
"status": "PENDING",
"substatus": "PENDING_ACTION_CLIENT",
"cutOffAt": "2026-02-06T14:15:22Z",
"rules": [
{
"id": "59be9844-3a70-4fbc-8d58-9637c1b34b18",
"name": "Client ABC Rule for Suspicious Beneficiary",
"effectiveAt": "2019-08-24"
}
],
"payment": {
"requestedExecutionDate": "2026-02-01",
"paymentIdentifiers": {
"endToEndId": "E2E3000113WEBXX"
},
"value": {
"currency": "USD",
"amount": "10.50"
},
"transferType": "DEBIT",
"paymentType": "WIRE",
"debtorAgent": {
"financialInstitutionIds": [
{
"id": "CHASUS33XXX",
"idType": "BIC"
}
]
},
"debtor": {
"name": "Nicholas Tesla",
"account": {
"accountNumber": "987654321",
"accountCurrency": "USD"
},
"postalAddress": {
"type": "HOME",
"addressLines": [
"10007 S. Lake Drive"
],
"streetName": "10007 Lake Dr",
"postalCode": "48035",
"city": "Clinton Township",
"countrySubDivision": "MI",
"country": "US"
}
},
"creditor": {
"name": "Comrade Musics",
"account": {
"accountNumber": "123456011",
"accountCurrency": "USD"
},
"postalAddress": {
"country": "US"
}
}
}
}
}When you receive this event, persist the hold to your storage. You can then present it to your users for decisioning. While you persist most fields as-is for display, build specific processing logic around the key fields described below.
| Fields | Description |
|---|---|
data.status and data.substatus |
These fields indicate whether the hold is awaiting a decision from your users or from the bank.
|
data.cutOffAt |
The date and time by which you must decision the hold. After this time, the system automatically cancels the hold. Build logic to prioritize holds approaching their cutoff, or send alerts to notify users about hold pending expiration. |
data.payment |
Contains the full payment instruction, including amount, beneficiary, debtor, and payment type. You may use these fields to prioritize holds based on transaction amount or beneficiary, or route holds differently based on payment type (For example, WIRE, ACH, RTP(U.S.). |
data.id |
The unique hold identifier. Pass this field when calling the API to decision the hold. |
Processing a payment hold amended event
A hold Amended event occurs when an existing hold's state changes. You may receive multiple events for the same hold as its state evolves. This event triggers in scenarios such as:
| Scenario | Change | Result |
|---|---|---|
| ACH payment distributed |
|
The ACH payment was distributed while hold active. You should still decision the hold since that can affect funds recovery process. |
| Hold reassigned to bank review | Substatus changes from PENDING_ACTION_CLIENT to PENDING_ACTION_JPM |
J.P. Morgan is reviewing the hold. Clients can no longer act on the hold. You create this state if you have an outage in your application and you need J.P. Morgan to release the hold so it can be paid or canceled. |
These are illustrative use cases you can expand. Your application should use the status, substatus and decision fields to reason about hold changes rather than assuming a fixed set of scenarios.
Sample response:
{
"specversion": "1.0",
"id": "b2d4e6f8-1a3c-5d7e-9f0b-2c4d6e8a0b12",
"time": "2026-02-11T11:00:00Z",
"type": "com.jpmorgan.payments.payment.hold.ammended.v1",
"source": "api.payments.jpmorgan.com/trust-safety/v1",
"dataschema": "urn:com.jpmorgan.payments/payment-hold",
"data": {
"id": "253f67f3-b640-44cb-aabd-2cc348b52678",
"status": "PENDING",
"substatus": "PENDING_ACTION_JPM",
"distribution": {
"isDistributed": true,
"distributedAt": "2026-02-11T10:45:00Z"
}
}
}When you receive this event, unlike the hold Amended event, this event contains only fields that may change after hold creation: status, substatus, and decision. It does not include full payment details or other hold fields, as they remain unchanged from the original hold Amended event. When you receive this event do the following:
- Locate the hold: The hold should already exist in your database from the original hold amended event. Use the hold identifier to locate the stored hold.
- Capture the current state: Extract the current status and substatus from your database before applying the update. This allows you to build state transition logic, such as detecting when a hold moves from
PENDING_ACTION_CLIENTto ¨. - Update the hold: Apply the new field values from the event to your stored hold.
- Trigger downstream actions: Based on the state change, consider these actions:
| State change | Suggested action |
|---|---|
| Hold moved to bank review | Alert users that they can no longer act on this hold. |
| Hold approved or rejected | Notify users that the payment has been released or canceled. |
| Display or routing changes | Update dashboard categorization or priority. |
If your application receives a hold amended event but cannot find the hold in your database, retrieve the full hold details by calling the Retrieve Details of a Payment hold API. See API reference for more information.
Processing a payment hold closed event
A payment hold closed event indicates that J.P. Morgan has either:
- Decisioned a high risk hold through its review.
- Changed the decision made on a previously decisioned hold based on client feedback.
- For instance, client may inform J.P. Morgan a previously approved hold was actually fraudulent.
- Since we change our database as a result, you’ll receive a notification with the update.
These updates both relate to the decision made on a hold. As such, the updated fields include:
- status
- substatus
- decision
Sample response:
{
"specversion": "1.0",
"id": "b4d82e1f-6a93-4c7b-8e2d-9f1a3c5d7b60",
"time": "2026-02-05T11:20:00Z",
"type": "com.jpmorgan.payments.payment.hold.closed.v1",
"source": "api.payments.jpmorgan.com/trust-safety/v1",
"dataschema": "urn:com.jpmorgan.payments/payment-hold",
"data": {
"id": "06bca14f-1fc0-4cd7-9e0b-8bb7e06334f7",
"status": "REJECTED",
"substatus": "REJECTED_FRAUD_JPM",
"decision": {
"source": "API",
"rejectReason": "FRAUD",
"fraud": {
"type": "BUSINESS_EMAIL_COMPROMISE"
}
}
}
}