---
title: Simulate inbound ACH
slug: tutorials/api/ach/simulate-inbound-ach
description: Walkthrough simulating incoming ACH via test tools.
docTags: 
createdAt: 2024-08-09T12:51:33.638Z
---

## What you will learn

✅ How to simulate in sandbox for ACH:

- Inbound originations
- Returns
- Corrections (NOC )

:::hint{type="info"}
If you are new to APIs and how the work we recommend you visit [API basics](docId\:pUTTCwQ5SKLzxYzIn5D1b).
:::

The tutorial uses these API endpoints:

| API                                                | Description                                                                                                                                         |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /v1/payments/simulated-inbound-originations` | Simulates sending funds sent via ACH to a Cross River account from another bank.<br />This endpoint can also be used to fund an account in sandbox. |
| `POST /v1/payments/simulated-inbound-returns`      | Simulates return of a payment from outside Cross River                                                                                              |
| `POST /v1/payments/simulated-inbound-corrections`  | Simulates a notification of change (NOC)                                                                                                            |

## Before you begin

Make sure you have:

- [API credentials](docId\:Z-MVwOV-p00-xX082NabK) for sandbox access
- Cross River account number
- For returns and corrections, payment IDs of completed payments

## Simulate ACH actions

Simulations allow you to test certain inbound payment flows in our sandbox environment. You can trigger these flows explicitly using the API endpoints outlined below, or, in the case of returns and corrections, automatically once an outbound payment completes. Automatic simulations are triggered by convention using the payment `purpose`field.

:::hint{type="warning"}
**IMPORTANT**
You can only simulate a return or NOC for a payment once it has updated to a status of **Complete**.
:::

Test *outbound&#x20;*&#x70;ayments using the [payment origination API endpoint](docId\:ILwmF5qnTMLo30D2H3rCH). The sandbox environment automatically takes the payment through the various statuses until it is **Complete**. Typically this process takes up to several minutes from start to finish.

**Where's my simulated payment?**

It is important to note that simulation requests are queued and processed asynchronously on a schedule. It typically takes a few minutes before they show up as new payment records.

### To simulate an inbound ACH payment

Inbound originations are payments that originate at another financial institution and are sent to a Cross River account.

These payments can have a `transactionType` of either *Push* (funds are being sent to your Cross River account) or *Pull* (funds are being taken from your Cross River account).

To simulate an inbound origination, manually trigger it using the simulated inbound originations endpoint.&#x20;

:::::WorkflowBlock
::::WorkflowBlockItem
Call `POST /v1/payments/simulated-inbound-originations`.

Required fields:

| Attribute                  | Description                                                                                                                                                                             | Value for simulation                                      |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `originatorRoutingNumber`  | Routing number of a bank outside Cross River                                                                                                                                            | 021000021                                                 |
| `originatorName`           | Name of bank account holder                                                                                                                                                             | Tom Smith                                                 |
| `originatorIdentification` | Identifier for the bank account                                                                                                                                                         | 99999999                                                  |
| `receiverAccountNumber`    | Account number of the sandbox account to receive the funds                                                                                                                              | Your sandbox account                                      |
| `receiverAccountType`      | Type of account receiving the funds. One of:<br />- Checking<br />- Savings<br />- GeneralLedger<br />- Loan                                                                            | The type of account your sandbox account is               |
| `receiverName`             | Name on the account receiving the funds                                                                                                                                                 | The name on your sandbox account                          |
| `secCode`                  | [Standard Entry Class](docId\:M8a5dbzFhH5TV1NytK9Aw) (SEC) code required by Nacha for every ACH transaction                                                                             | For the simulation we recommend using **PPD**             |
| `description`              | Description of the payment. Maximum 10 characters.                                                                                                                                      | <br />For the simulation we recommend writing **Testing** |
| `transactionType`          | Sending or requesting funds:<br />- Push (originator is sending funds—debit)<br />- Pull (originator is receiving funds—credit)<br />See [Payment types](docId:0papBZYBjF0LZPac8-tRW).  | Use **Push** if you are funding a sandbox account         |
| `amount`                   | Dollar amount of payment in positive integral cents. For example, $1.00 appears as 100.                                                                                                 |                                                           |
| `serviceType`              | Either [Standard](docId:0papBZYBjF0LZPac8-tRW) or <br />[Same Day](docId:0papBZYBjF0LZPac8-tRW)                                                                                         |                                                           |

See [Send an ACH](docId\:HLIqOJNMHJwJRI29Z0Ryt) for additional information.

:::CodeblockTabs
Sample request

```curl
curl --location 'https://sandbox.crbcos.com/ach/v1/payments/simulated-inbound-originations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
  "originatorRoutingNumber": "021000021",
  "originatorName": "Tom Smith",
  "originatorIdentification": "99999999",
  "receiverAccountNumber": "2819503463",
  "receiverAccountType": "Checking",
  "receiverName": "Jerry Penn",
  "receiverIdentification": "INV123",
  "secCode": "PPD",
  "description": "Testing",
  "transactionType": "Push",
  "amount": 1000,
  "serviceType": "SameDay",  
}'
```
:::
::::

::::WorkflowBlockItem
A successful API call returns a JSON response with the details of the payment.

:::CodeblockTabs
Sample response

```json
{
    "originatorRoutingNumber": "021000021",
    "originatorName": "Tom Smith",
    "originatorIdentification": "99999999",
    "receiverAccountNumber": "2819503463",
    "receiverAccountType": "Checking",
    "receiverName": "Jerry Penn",
    "receiverIdentification": "INV123",
    "secCode": "PPD",
    "description": "Testing",
    "transactionType": "Push",
    "amount": 1000,
    "serviceType": "SameDay",
    "settlementDays": 0
}
```
:::
::::
:::::

### To simulate an ACH return

You can simulate an ACH return with the simulation endpoint `POST /v1/payments/simulated-inbound-returns` or with the [Send an ACH](docId\:HLIqOJNMHJwJRI29Z0Ryt) API.

To use the simulation endpoint:

:::::WorkflowBlock
:::WorkflowBlockItem
Have ready the ID of the outbound payment you are simulating the return for (found in the response of the Send an ACH) and a [return code](docId\:oDtRP7ARfnpQuFEGy4Sfh).
:::

::::WorkflowBlockItem
Call `POST /v1/payments/simulated-inbound-returns`.

:::CodeblockTabs
POST /v1/payments/simulated-inbound-returns request

```curl
curl --location 'https://sandbox.crbcos.com/ach/v1/payments/simulated-inbound-returns' \
--data '{
  "returnCode": "R02",
  "previousPaymentId": "1b228f4c-26d4-4da0-b813-b34300e84b4e"
}'
```
:::
::::

::::WorkflowBlockItem
A successful API call returns a JSON response.

:::CodeblockTabs
POST /v1/payments/simulated-inbound-returns response

```json
{
    "returnCode": "R02",
    "previousPaymentId": "1b228f4c-26d4-4da0-b813-b34300e84b4e"
}
```
:::
::::
:::::

To simulate a return automatically using the [Send an ACH](docId\:HLIqOJNMHJwJRI29Z0Ryt) API:

:::::WorkflowBlock
:::WorkflowBlockItem
When you send the `POST /v1/payments` call, populate the `purpose` field (row 18 below) with **TEST\_RETURN\_RXX**, where **XX** is the [return code](docId\:oDtRP7ARfnpQuFEGy4Sfh) you wish to test.
:::

::::WorkflowBlockItem
:::CodeblockTabs
POST /v1/payments return request

```curl
curl --location 'https://sandbox.crbcos.com/ach/v1/payments' \
--header 'Idempotency-key: c10314ee-e737-4681-8e8d-f9cf547c9967' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
      "accountNumber": "2203250853",
      "receiver": {
        "routingNumber": "021000021",
        "accountNumber": "2151546989",
        "accountType": "Checking",
        "name": "Peter Griffin"
      },
      "secCode": "PPD",
      "description": "math tutor",
      "transactionType": "Push",
      "amount": 25000,
      "serviceType": "Standard",
      "purpose": "TEST_RETURN_R01"
}
```
:::
::::
:::::

*Contested* returns have to be anticipated or approved for acceptance. In that case, only the initial return event is listed as returned, and a subsequent webhook is applied. The dishonoring of the return relays the funds back to the returning source and no webhook launches for those or any other rejecting/dishonoring attempts.

Without your direct consent, no returns of any kind occur while outside of the 24-hour (Corporate return) or 60-day (Consumer return) time frame . Transactions received outside of both scenarios are subject to review and processing. For any claims issued to the Cross River ACH Operations team, a notice is provided to the Originating party for Proof of Authorization or any other corroborating documents that warrant the authorization of the debit entry. Your RM will also be advised of any matters for awareness.

### To simulate a correction

You can simulate an ACH NOC correction with the simulation endpoint `POST /v1/payments/simulated-inbound-corrections` or with the [Send an ACH](docId\:HLIqOJNMHJwJRI29Z0Ryt) API.

To use the simulation endpoint:

:::::WorkflowBlock
:::WorkflowBlockItem
Have ready the ID of the outbound payment you are simulating the correction for (found in the response of the Send an ACH), the correction and the [correction code](docId\:oDtRP7ARfnpQuFEGy4Sfh).
:::

::::WorkflowBlockItem
Call `POST /v1/payments/simulated-inbound-corrections`.

:::CodeblockTabs
POST /v1/payments/simulated-inbound-corrections request

```curl
curl --location 'https://sandbox.crbcos.com/ach/v1/payments/simulated-inbound-corrections' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
  "changeCode": "C04",
  "correctedData": "Peter G Griffen",
  "previousPaymentId": "04228e9c-361e-4005-b68f-b339008ae4dc"
}'
```
:::
::::

::::WorkflowBlockItem
A successful API call returns a JSON response.

:::CodeblockTabs
POST /v1/payments/simulated-inbound-returns response

```json
{
  "changeCode": "C04",
  "correctedData": "Peter G Griffen",
  "previousPaymentId": "04228e9c-361e-4005-b68f-b339008ae4dc"
}'
```
:::
::::
:::::

To simulate a NOC correction automatically using the [Send an ACH](docId\:HLIqOJNMHJwJRI29Z0Ryt) API:

:::::WorkflowBlock
::::WorkflowBlockItem
When you send the `POST /v1/payments` call, populate the `purpose` field (row 18 below) with **TEST\_NOC\_CXX**, where **XX** is the [correction code](docId\:oDtRP7ARfnpQuFEGy4Sfh) you wish to test.

Our example shows an outbound pull payment where an incorrect DFI account number correction (C01) will be automatically generated by the Cross River system after the outbound payment is complete.

:::CodeblockTabs
POST /v1/payments return request

```curl
curl --location 'https://sandbox.crbcos.com/ach/v1/payments' \
--header 'Idempotency-key: c10314ee-e737-4681-8e8d-f9cf547c9967' \
--header 'Content-Type: application/json' \
--data '{
      "accountNumber": "2203250853",
      "receiver": {
        "routingNumber": "021000021",
        "accountNumber": "2151546989",
        "accountType": "Checking",
        "name": "Peter Griffin"
      },
      "secCode": "PPD",
      "description": "math tutor",
      "transactionType": "Push",
      "amount": 25000,
      "serviceType": "Standard",
      "purpose": "TEST_NOC_C01",
}'
```
:::
::::
:::::

## Simulations explained

Since returns and NOCs can only be simulated after an outbound payment reaches a status of **Complete**, the outbound payment's service type will affect the timing of your simulations. An outbound payment with a *standard&#x20;*&#x73;ervice type would only allow you to simulate a return the following day via the simulation endpoint. If the simulation was done using the `purpose` field of the outbound payment, then you'd automatically receive the simulated inbound payment two business days after the payment is completed. Some SEC codes will also encounter this timing scenario, such as IATs which are restricted to a *standard&#x20;*&#x73;ervice type.

This is generally why you would encounter any scenarios where you’ve originated a payment but the status hasn’t changed to Complete in over 24 business hours. If you originated any payments yesterday, you can use the simulation endpoints to simulate any return code you want.

Our ACH domain in Sandbox is configured to simulate the bank’s processes around ACH origination, which means that generally no human intervention is needed to action a payment in order for it to be processed and moved to a status of Complete. We do not mark any payments as paid; once you originate a payment, assuming all systemic validations pass then Sandbox will simulate the payment being sent to the Fed and also simulate receiving an acknowledgment file from the Fed.

When a payment request is submitted to COS, the bank can reject the payment for various reasons. For example, a payment which was on hold for compliance reasons was rejected because the partner was unable to provide additional payment-related information.

Payments which are manually rejected by someone in Cross River do not include any details for the rejection. Payments which are systemically rejected will contain the reason within the payment details. For example, if a payment was rejected because the originator Cross River account had insufficient funds then you would see **NSF&#x20;**&#x61;s the `postingCode` within the payment details.
