US Payments: Integration Guide

This guide walks you through how to submit an outbound payment to an external account with a routing number and account number (RNAN) in sandbox.


Pre-requisites

  1. The implementation team has created a US customer for you in sandbox
  2. The implementation team has provided you with a product code for US accounts
  3. You have an API key set up

Step 1: Create an Account

Use the /POST Accounts API to open an account using your US customer ID. Modulr will create a US account and provide you with the unique routing number and account number used to identify the account.

Request

POST /customers/{customerId}/accounts
{
  "externalReference": "My First US Account",
  "currency": "USD",
  "productCode": "O21001MC"
}

Response (201)

You will receive a response providing the account ID, the routing number/account number, and the status.


    "id": "A2100HWRLB",
    "name": "My Corp",
    "balance": "0.00",
    "currency": "USD",
    "status": "ACTIVE",
    "identifiers": [
        {
            "type": "RNAN",
            "accountNumber": "00000006312795",
            "routingNumber": "000000000",
            "productId": "O21001MC"
        }
    ],
    "customerId": "C2144NC8",
    "customerName": "My Corp",
    "externalReference": "My First US Account",
    "accessGroups": [],
    "createdDate": "2026-10-02T08:20:35.825+0000",
    "directDebit": false,
    "securedFundingLimit": "0.00"
}
❗

Note that US accounts currently go straight to ACTIVE status. In the future, there will be an intermediate status


Step 2: Fund the account using the credit endpoint

Use the sandbox credit endpoint to fund your sandbox account with a PI_ACH_CREDIT, so that you can initiate an outbound payment.

  • Use the account ID from step 1
  • You only need to set the account type to RNAN, you do not need to add a routing number or account number.

Request

POST /credit
{
  "payerDetail": {
    "identifier": {
      "type": "RNAN"
    },
    "name": "Dom Dollar"
  },
  "type": "PI_ACH_CREDIT",
  "accountId": "A2100HWRLB",
  "amount": 10000,
  "description": "Cash Money"
}

Response (200)

You will receive a 200 response confirming the request.

200 OK
📘

Optional: Confirm account has been funded

Confirm the account has been funded by performing a balance check with the /GET accounts API. Use the account ID from step 1 in the request path.

(You can also do this by creating an integration notification for PAYIN events)

Request

GET /accounts/{accountID}

Response (200)

{
    "id": "A2100HWRLB",
    "name": "My Corp",
    "balance": "10000.00",
    "availableBalance": "0.00",
    "currency": "USD",
    "status": "ACTIVE",
    "identifiers": [
        {
            "type": "RNAN",
            "accountNumber": "00000006312795",
            "routingNumber": "000000000",
            "providerExtraInfo": {},
            "productId": "O21001MC"
        }
    ],
    "customerId": "C2144NC8",
    "customerName": "My Corp",
    "externalReference": "My First US Account",
    "accessGroups": [],
    "createdDate": "2026-10-02T08:20:35.825+0000",
    "directDebit": false,
    "securedFundingLimit": "0.00"
}

Step 3: Initiate an outbound payment

Option 1: Use an RNAN (Routing Number/Account Number) Destination

Use the payments API to initiate a payment from your account to a specific routing number and account number (RNAN).

  • If the payment is a worker payout, then set the categoryOfPayment to SALA
  • If the payment is a payout to a business (including your own business), then set the categoryOfPayment to CASH
  • For payments to RNAN destinations, you must choose one of SALA or CASH
  • For payments to RNAN desntinations, you must select currency as USD
  • The routing number must be 9 digits, and the account number must be 5-17 digits

Request

POST /payments

You will get a response confirming that the payment has been submitted

{
  "destination": {
    "type": "RNAN",
    "name": "Joseph Bloggs",
    "routingNumber": "345678910",
    "accountNumber": "987654321"
  },
  "sourceAccountId": "A2100HWRLB",
  "currency": "USD",
  "amount": 50,
  "reference": "My first payment",
  "categoryOfPayment": "CASH"
}

Response

{
    "id": "P2100QF5F5",
    "status": "VALIDATED",
    "createdDate": "2026-10-02T08:55:47.047+0000",
    "details": {
        "sourceAccountId": "A2100HWRLB",
        "destination": {
            "type": "RNAN",
            "accountNumber": "987654321",
            "routingNumber": "345678910",
            "name": "Joseph Bloggs"
        },
        "currency": "USD",
        "amount": 50,
        "reference": "My first payment",
        "includeBlockedAccount": false,
        "categoryOfPayment": "CASH"
    },
    "reference": "P2100QF5F5",
    "approvalStatus": "NOTNEEDED",
    "createdBy": "U2102YD4",
    "type": "PAYOUT",
    "currentUserCanApprove": false,
    "approvals": []
}

Option 2: Use a Beneficiary Destination

Alternatively, you can create a beneficiary with a routing number and account number using the /POST Beneficiaries API.

  • The routing number must be 9 digits, and the account number must be 5-17 digits

Request

POST customers/{Customer ID}/beneficiaries
{
  "destinationIdentifier": {
    "type": "RNAN",
    "routingNumber": "123456789",
    "accountNumber": "12345678"
  },
  "name": "Joe Bloggs",
  "defaultReference": "Payout"
}

Response (201)

{
    "id": "B21008FCZP",
    "name": "Joe Bloggs",
    "destinationIdentifier": {
        "type": "RNAN",
        "accountNumber": "12345678",
        "routingNumber": "123456789"
    },
    "defaultReference": "Payout",
    "status": "ACTIVE",
    "created": "2026-10-02T08:38:03.262+0000",
    "approvalRequired": false,
    "customerId": "C2144NC8",
    "updated": "2026-10-02T08:38:03.264+0000",
    "approvalStatus": "APPROVED",
    "accessGroups": [],
    "createdBy": "U2102YD4"
}

You can then initiate a payment from your account to the beneficiary.

  • If the payment is a worker payout, then set the categoryOfPayment to SALA

  • If the payment is a payout to a business (including your own business), then set the categoryOfPayment to CASH

  • For payments to RNAN destinations, you must choose one of SALA or CASH

  • For payments to RNAN desntinations, you must select currency as USD

Request

You will get a response confirming your payment has been submitted.

POST /payments
{
  "destination": {
    "type": "BENEFICIARY",
    "id": "B21008FCZP"
  },
  "sourceAccountId": "A2100HWRLB",
  "currency": "USD",
  "amount": 50,
  "reference": "My first payment",
  "categoryOfPayment": "CASH"
}

Response (201)

{
    "id": "P2100QF5AK",
    "status": "VALIDATED",
    "createdDate": "2026-10-02T08:42:59.059+0000",
    "details": {
        "sourceAccountId": "A2100HWRLB",
        "destination": {
            "type": "BENEFICIARY",
            "id": "B21008FCZP"
        },
        "currency": "USD",
        "amount": 50,
        "reference": "My first payment",
        "includeBlockedAccount": false,
        "categoryOfPayment": "CASH"
    },
    "reference": "P2100QF5AK",
    "approvalStatus": "NOTNEEDED",
    "createdBy": "U2102YD4",
    "type": "PAYOUT",
    "currentUserCanApprove": false,
    "approvals": []
}

Step 4: Track payment to completion

Option 1: Poll for the payment

You can use the Use the GET Payments API with the payment ID as a query parameter to retrieve and check the status of your payment.

Request

GET /payments?ids={payment ID}

Response (200)

{
    "content": [
        {
            "id": "P2100QF5C6",
            "status": "PROCESSED",
            "createdDate": "2026-10-02T08:47:31.031+0000",
            "details": {
                "sourceAccountId": "A2100HWRLB",
                "destination": {
                    "type": "BENEFICIARY",
                    "id": "B21008FCZP"
                },
                "currency": "USD",
                "amount": 50,
                "reference": "My first payment",
                "includeBlockedAccount": false,
                "categoryOfPayment": "CASH"
            },
            "reference": "P2100QF5C6",
            "approvalStatus": "NOTNEEDED",
            "message": "SUCCESSfrom MOCK",
            "schemeInfo": {
                "name": "ACH"
            },
            "createdBy": "U2102YD4",
            "type": "PAYOUT",
            "currentUserCanApprove": false,
            "approvals": []
        }
    ],
    "size": 1,
    "totalSize": 1,
    "page": 0,
    "totalPages": 1
}

Option 2: Listen for Webhook notifications

By subscribing to Payout Notifications, you can listen for status updates to the payment you submitted. Click here to find out how to set up your webhook.

{
    "EventName": "PAYOUT",
    "EventId": "19126ff1-e8a3-4a8d-9469-d5bf337c2117",
    "EventTime": "2026-10-02T08:47:32+0000",
    "PaymentId": "P2100QF5C6",
    "AccountId": "A2100HWRLB",
    "TransactionId": "T2100HSW87",
    "TransactionType": "PO_ACH_CREDIT",
    "Reference": "My first payment",
    "Amount": "50",
    "Status": "PROCESSED",
    "DateTime": "2026-10-02T08:47:31+0000"
}

Payment statuses

Click here for more information on payment statuses

Payment StatusDescriptionState
SUBMITTEDRequest has been accepted - will go to internal validation.Transient
VALIDATEDRequest internally validated - request has been validated and now is queued to be sent to external payment systems.Transient
PENDING_FOR_DATERequest awaiting processing date.Transient
PENDING_FOR_FUNDSRequest awaiting funds.Transient
PROCESSEDRequest processed and successfully sent to destination payment system.Final
CANCELLEDPayment request has been cancelled.Final


Did this page help you?