What is a Transaction?

A Transaction in the GrailPay ACH API initiates the movement of funds between two users — typically a payer ( sender ) and a payee ( recipient ) — via the ACH network. It represents the debit leg of the transfer, capturing the withdrawal of funds from the payer’s bank account. Once processed, the transaction will result in a corresponding Payout, which reflects the credit leg — the delivery of funds to the payee. Each transaction is uniquely identified by a uuid and includes metadata such as the amount, participants, and processing status. Transactions can represent:
  • Business to Business payments
  • Business to Person disbursements
  • Person to Business collections
Once created, the transaction enters a processing pipeline that will debit the payer’s bank account and credit the payee’s bank account, subject to ACH network rules and timing.

Overview

Creating a transaction involves initiating a fund transfer between two parties — a payer (sender) and a payee (recipient). Both parties must be onboarded and must have valid, connected bank accounts within the GrailPay system. When a transaction is successfully created, the API returns a unique uuid that can be used to track its status or retrieve its details later. This guide outlines the required fields, entity prerequisites, and common validation scenarios encountered when initiating a transaction.

Failure Simulation

GrailPay provides support for simulating transaction failures in the sandbox environment, allowing you to test how your integration responds to various ACH return scenarios. To simulate a failure, include the failure_simulation parameter in the request payload when creating a transaction. This parameter accepts one of the following values:
  • beforePayout – Simulates an ACH failure before the credit (payout) is sent to the destination bank.
  • afterPayout – Simulates an ACH failure after the payout has been sent.
Both scenarios will result in a transaction failure with an ACH return code of R01 (Insufficient Funds), allowing you to test failure-handling logic at different points in the transaction lifecycle.

Testing

To test transactions in GrailPay’s sandbox environment, you’ll need two entities:
  • One with a connected bank account to act as the payer
  • One with a connected bank account to act as the payee
For more information on creating accounts in our sandbox environment, see the Technical Overview guide. You can provide these details when creating test users via the following endpoints: This setup allows you to perform end-to-end transaction testing — including creation, settlement, and simulated failure — without using real financial data.
Every transaction created within the GrailPay system requires that at least one party (either the payer or payee) has successfully completed KYB verification. This means one side of the transaction must be a registered Merchant.

Step 1: Confirm Participants Are Onboarded

Before creating a transaction, both the payer and payee must exist in the system as valid users (i.e. persons or businesses). Each must meet the following criteria:
  • Successfully onboarded using the appropriate flow
  • Possess a valid uuid
  • Have an active, connected bank account (manual or Plaid-linked)
You will reference these participants using:
  • payer_uuid — the sender of funds
  • payee_uuid — the recipient of funds
If either party is missing or has an invalid account, the transaction will be rejected.

Step 2: Determine Transaction Type and Amount

Each transaction must include:
  • amount — The dollar value to be transferred
  • speed — Indicates processing tier (e.g., standard or sameday, if available in your integration)
Optional fields include:
  • client_reference_id — Optional reference ID from your system
  • description — Optional metadata for reporting
All amounts must be denominated in USD and specified in cents (e.g., $10.00 = 1000).

Step 3: Submit the Transaction

To initiate the transaction, send a POST request to the following endpoint: /3p/api/v1/transactions with the required fields. Upon success, the API will return a uuid representing the newly created transaction. This can be used to fetch status updates or cancellation requests. See the Create Transaction OpenAPI documentation for the full schema, including all required and optional fields.

Step 4: Monitor the Transaction Status

Once submitted, a transaction may move through multiple states depending on processing speed, ACH timing, and risk evaluation. Possible states include:
  • CAPTURE_PENDING
  • CAPTURE_ACH_PENDING
  • CAPTURE_ACH_FAILED
  • CANCELED
  • IN_PAYOUT
To see a full list of states and their definitions, refer to the Transaction States documentation. To monitor the state of a transaction, you can use one of the following methods:
  • Webhook Notifications: Set up webhooks to receive real-time Webhook Events on transaction status changes.
  • API Polling: Use the GET /3p/api/v2/transactions/{transaction_uuid} endpoint to fetch the current status of a specific transaction.
To fully monitor the lifecycle of a funds transfer, it’s important to understand that a Transaction only represents the debit leg of the movement. The Payout, which delivers funds to the payee, follows its own processing lifecycle and status updates.We strongly recommend subscribing to both the Transaction and Payout webhook events to accurately track the complete flow of funds — from initiation to settlement.

Questions?

If you’re encountering any issues, contact your GrailPay integration support contact or open a support request via the portal.

Resources

Below you will find some helpful resources to assist with understanding how transactions work in GrailPay.