# Payments API Changelog

## 2026.10.6.1

### What's new:
When a FedNow payout fails and the money is sent again as a Fast ACH payout, the two payouts are
now linked. A new `failover` object on the payout shows the link in both directions, and the
payout-failed webhook is now sent after the replacement has been created, so it already carries
it.

### Why it matters:
An integrator that receives a payout-failed event for a FedNow payout can now find the
replacement payout from the event itself, and from the replacement can get back to the original,
instead of matching the two by payee and amount. Payouts created before this release are not
backfilled, so `failover` is null on them.

### Highlights:
- `failover.superseded_by` on the failed payout holds the replacement payout's UUID; `failover.supersedes` on the replacement holds the failed payout's UUID; `failover` is null when there is no link
- `failover` appears in the v3 payout list and fetch responses, v3 payout webhooks, and the legacy payout and transaction webhooks
- The payout-failed webhook for a FedNow payout is sent after the Fast ACH replacement is created, so it includes the link
- Older payouts are not backfilled

## 2026.10.5.1

### What's new:
A person can now be deleted on v3 with `DELETE /api/v3/people/{uuid}`. The person and their
connected bank accounts are marked as scheduled for deletion, and are soft-deleted after 70 days
provided there has been no recent activity on their bank accounts.

### Why it matters:
Partners migrating off the deprecated v1 and v2 delete-user endpoints now have a v3 equivalent.
Deletion is deliberately not immediate: the request is accepted with 202, the person is left out
of list responses and can no longer transact or be refunded while scheduled, and the removal
happens only once the waiting period has passed with no activity, so a person with a return still
possible is not removed under it.

### Highlights:
- `DELETE /api/v3/people/{uuid}` marks the person and their connected bank accounts as scheduled for deletion and returns 202 Accepted
- A person scheduled for deletion is omitted from v3 list responses and cannot be the party to a new transaction or refund
- After 70 days the person and their bank accounts are soft-deleted; accounts linked through an aggregator are unlinked or removed at the aggregator where applicable
- If any of the person's bank accounts has had activity within the lookback window, the person stays scheduled and is checked again on the next run
- 403 is returned for a person belonging to another vendor, a token without the delete ability, a user that is not a person, and a person already scheduled for deletion

## 2026.10.1.3

### What's new:
The `POST /api/v3/transactions` endpoint now requires `payor_uuid` in place of `payer_uuid`,
matching the `payor` object that v3 responses and webhooks already use.

### Why it matters:
The rename is a breaking change for anyone already calling the v3 Create Transaction endpoint with
`payer_uuid`: the request is rejected until the field is renamed. v1, v2 and third-party transaction
creation keep `payer_uuid`.

### Highlights:
- `POST /api/v3/transactions` requires `payor_uuid` instead of `payer_uuid`; the UUID is looked up the same way as before, a vendor person or business first and then a merchant
- Validation errors use the `payor_uuid` field, with messages such as "The payor uuid field is required.", and the not-found, on-hold and bank account errors for the payor now say "payor"
- The transaction response and the `transaction.created` webhook already return a `payor` object; that is unchanged

## 2026.10.1.2

### What's new:
The v3 refund resource now includes the parent `transaction_uuid` at its top level and reports an
ACH return code on the leg it belongs to: the `capture` and `payout` objects each carry their own
`ach_return_code`.

### Why it matters:
A refund has two ACH legs, pulling the funds back and sending them to the customer, and either
can be returned. With the return code on the leg that failed, an integrator can tell which
movement was rejected without comparing timestamps, and with `transaction_uuid` at the root it
can load the original transaction without a search. No existing fields were removed or renamed.

### Highlights:
- `transaction_uuid` is included at the top level of each refund
- `capture.ach_return_code` and `payout.ach_return_code` carry the return code of whichever leg failed most recently; the other leg's value is null, and both are null when neither has failed
- The fields appear in the v3 refund create, list and fetch responses, in the refunds embedded in the v3 transaction response, and in v3 refund webhooks

## 2026.10.1.1

### What's new:
The clawback resource now includes a `payor` object. For clawbacks of type `reverse_payout` and
`refund`, `payor` identifies the party the funds are recovered from, which is the payer on the
original transaction.

### Why it matters:
For these two clawback types the funds being recovered were returned to the payer, so the payer is
the party they are recovered from. An integrator reading a `reverse_payout` or `refund` clawback
should look at `payor` for the party involved; `payee` is populated for `transaction` and
`vendor_fee` clawbacks.

### Highlights:
- The clawback resource includes a `payor` object for clawbacks of type `reverse_payout` and `refund`, and `payee` is null for them
- `transaction` and `vendor_fee` clawbacks keep `payee` and have a null `payor`
- Clawbacks of type `reverse_payout` and `refund` debit the payer's bank account associated with the transaction

## 2026.9.30.1

### What's new:
Refunds and reverse payouts now follow the state of the payment they relate to. A reverse payout or
refund is not created for a transaction or payout that has failed, and one that is still pending
when that failure arrives is cancelled, with a new `reverse_payout.cancelled` webhook event and the
existing refund cancelled event sent. Where funds have already been returned for a payment that
later fails, GrailPay recovers them through a clawback, and the clawback resource now carries the
reverse payout or refund it recovers.

### Why it matters:
Integrators may see a refund or reverse payout cancelled rather than completed when the underlying
payment fails, and should subscribe to `reverse_payout.cancelled` and `refund.cancelled` to track
them. Where funds had already gone out, recovery appears as a clawback with the usual clawback
events, so it shows up in the same records and webhooks as any other clawback.

### Highlights:
- A reverse payout is not created when its transaction has failed; a pending reverse payout is cancelled when the transaction fails, and the amount of a reverse payout is the transaction amount minus any refunds already made
- A refund is not created when its transaction or payout has failed; a refund whose ACH entry has not yet been submitted is cancelled when the transaction or payout fails, with the `refund.cancelled` event sent
- New `reverse_payout.cancelled` webhook event on v3 and `ReversePayoutCancelled` on v1, sent when a reverse payout is cancelled; the v3 payload carries the reverse payout plus `relations.payout` and `relations.transaction`
- Clawbacks of type `reverse_payout` or `refund` are created for funds already returned on a payment that later failed, with the clawback webhook events sent
- The clawback resource's `relations` object now includes `reverse_payout` and `refund` alongside `transaction` and `payout`, and the API reference for the v3 clawback endpoints covers reverse payout and refund clawbacks

## 2026.9.23.1

### What's new:
GrailPay has improved the logic that determines when clawbacks, reverse payouts, refunds and
processor payouts are considered settled. For refunds, this covers both the refund capture and the
refund payout.

### Why it matters:
Settlement is what moves a payment to its completed state and triggers the completed events
integrators act on. Integrators may see these payments reach that state, and receive those events,
earlier. The statuses and events themselves are unchanged, and each payment settles once, so
completed events are not sent twice.

### Highlights:
- Improved settlement logic for clawbacks, reverse payouts, refunds (capture and payout) and processor payouts
- Settled statuses and completed events for these payments may arrive earlier
- No change to the statuses or events themselves; a payment is settled once and its completed events are sent once

## 2026.9.22.2

### What's new:
Vendors and processors can now look up who they are with `GET /api/v3/me`, and a vendor, or the
processor that owns it, can read a vendor's details with `GET /api/v3/vendors/{uuid}`. Vendors
with a pre-funded FBO account receive an hourly `fbo.account_snapshot` webhook with their
balance. Routing numbers are now validated before a bank account is accepted, both when adding an
account and when onboarding a person, merchant or business with one.

### Why it matters:
Until now a key could not discover its own vendor or processor identity through the API, and a
vendor's bank accounts and FBO status required separate calls. The snapshot webhook gives a vendor a
standing view of its available balance and whether it is in good, review or low status, so it can
top up before standalone payouts are affected. Routing number validation reports a bad routing
number as a 422 on the request that carried it.

### Highlights:
- New `GET /api/v3/vendors/{uuid}` returning the vendor's `uuid`, `name`, `bank_accounts` (masked, with funding and payout purpose and default flags), `fbo_account.enabled` and `created_at`; a vendor sees only itself and a processor only the vendors it owns, with unknown or unowned vendors returning 404
- New `GET /api/v3/me` returning `entity.type` (`vendor` or `processor`), `entity.uuid` and `entity.name` for the authenticated key; other token types receive 403
- New hourly `fbo.account_snapshot` webhook for vendors with a pre-funded FBO (and their registered processor), carrying `current_balance`, `pending_payouts`, `available_balance`, `balance_status` of `good`, `review` or `low`, `currency` and `snapshot_at`; sent every hour even when nothing changed, and skipped for vendors without an FBO
- In-flight FedNow standalone payouts count toward `pending_payouts` in the snapshot
- Routing numbers must pass the ABA check digit and be confirmed ACH-enabled when adding a bank account or onboarding a person, merchant or business with one; both failures return the same routing-number-invalid validation message
- On v3 onboarding the failure is reported on `bank_account.routing_number`
- The v3 bank account validate endpoint still checks only that the routing number is 9 digits, since account intelligence validates it there

## 2026.9.21.4

### What's new:
The v3 onboard and update responses for a person, a business and a merchant now return the full
bank account resource for the bank account included in the request.

### Why it matters:
An integrator that onboards an entity with a bank account can use the account's UUID straight
from the onboarding response, for example to make it the default or to create a transaction,
instead of making a second call to look it up.

### Highlights:
- Person, business and merchant onboard and update responses on v3 include a `bank_accounts` list holding the bank account supplied in the request; other accounts on the entity are not fetched into this list

## 2026.9.21.2

### What's new:
GrailPay has improved the logic that determines when a payout is considered settled.

### Why it matters:
Settlement is what moves a payout to its complete state and triggers the completed event integrators
act on. Integrators may see payouts reach that state, and receive that event, earlier, so they learn
sooner that a payee has been paid. The status and event themselves are unchanged, and a payout
settles once, so its completed event is not sent twice.

### Highlights:
- Improved settlement logic for payouts
- The payout complete status and completed event may arrive earlier
- No change to the status or event themselves; a payout is settled once and its completed event is sent once

## 2026.9.21.1

### What's new:
Customers can list their individual billing items and a billing summary on v3, for merchants,
businesses and persons. Each billing item now carries a nested `entity` (name, UUID, type and
client reference ID) and a `source` describing the event that was billed, and both endpoints
filter by entity UUID, billable event name, processor MID and date range. Separately, v3 fetch
endpoints now return person, merchant, business and bank account records even when the person is
not approved or the merchant is deactivated.

### Why it matters:
With the billed entity identified in one consistent shape, including the client reference ID
provided at onboarding, an integrator can map every billing item to its own records without
joining on names. The read change means an integration can inspect an on-hold person or a
deactivated merchant, and their bank accounts, to see why that party cannot transact; creating
transactions and changing bank accounts for them is still refused.

### Highlights:
- `GET /api/v3/billing/items` returns each item with `billed_at`, `amount`, `billable_event_name`, a nested `entity` (`name`, `uuid`, `type`, nullable `client_reference_id`) and a `source` (`type`, `uuid`); the flat merchant name, merchant UUID and client reference fields are replaced by `entity`
- `GET /api/v3/billing/items` and `GET /api/v3/billing/summary` accept `filter[entity_uuid]`, `filter[billable_event_name]`, `filter[processor_mid]`, `filter[start_date]` and `filter[end_date]`; `filter[merchant_uuid]` is no longer accepted
- `GET /api/v3/people/{uuid}`, `GET /api/v3/merchants/{uuid}`, `GET /api/v3/businesses/{uuid}`, and the v3 bank account list, fetch, balance and history endpoints return 200 for an on-hold person or a deactivated merchant, including the nested bank accounts and the `status`, `is_active` and `deactivated_reason` fields
- Creating a transaction with an on-hold party or deactivated merchant is still rejected, bank account changes for a not-approved entity still return 403, and entities scheduled for deletion still return 403 on fetch

## 2026.9.18.1

### What's new:
Vendors now receive the same compliance status webhooks for person KYC that they already receive
for merchant KYB. No new event names were added, and merchant KYB and beneficial owner payloads
are unchanged.

### Why it matters:
Until now a person verified through the standalone KYC endpoint produced no compliance status
events, so an integrator had to poll to learn the outcome. Subscribers to
`compliance_status.processing`, `compliance_status.approved` and `compliance_status.rejected`
now get person KYC results pushed the same way as merchant results, with the payload identifying
the person rather than a merchant.

### Highlights:
- `compliance_status.processing` is sent after a person KYC request has been successfully started; `compliance_status.approved` or `compliance_status.rejected` is sent when the verification provider reports a pass or fail
- The existing onboarding `ComplianceStatusChanged` webhook is also sent for those person KYC status updates
- The payload identifies a person: `entity.type` is `person`, `entity.uuid` is the person's UUID, and `compliance` holds a single `kyc` status rather than `kyb` and a beneficial owner list
- These webhooks are not sent for external KYC, when provider user creation fails, for a duplicate KYC re-registration, or when the person already has an identity token

## 2026.9.16.1

### What's new:
Vendors can now fund their pre-funded FBO account through the API. A new endpoint originates a
same-day ACH debit from one of the vendor's funding bank accounts into the FBO, a second endpoint
cancels a funding transfer while it is still pending, and five new `fbo.funding_*` webhook events
report the transfer's lifecycle. Funding is separate from merchant payments: it creates no
merchant payout, refund or fraud check.

### Why it matters:
Standalone payouts draw on the vendor's pre-funded FBO, and until now topping it up happened
outside the API. With a funding endpoint, a vendor can keep its FBO funded programmatically, for
example in response to the balance it sees in its payouts, and track each transfer from creation
to settlement through webhooks rather than polling. Because funding is isolated from the merchant
transaction flows, nothing about merchant payments, refunds or returns changes.

### Highlights:
- New `POST /api/v3/vendors/{uuid}/fbo/funding` requesting a same-day ACH debit into the vendor's pre-funded FBO; `amount` (integer cents) is required, and `source_account` may be omitted to use the default funding account, carry the `uuid` of an existing funding account, or carry new bank details, which are saved as a funding account
- The request is accepted immediately with 201 and the transfer's `uuid` and `amount`; the ACH entry is originated in the background, and the FBO balance is credited only once it is
- Vendor keys only: processor keys receive 403, and a vendor can fund only its own FBO; a request with the same idempotency key but a different body returns 409; funding returns 422 when the vendor has no pre-funded FBO or no usable funding account, and payout-purpose accounts cannot be the source
- New `DELETE /api/v3/vendors/{uuid}/fbo/funding/{funding_uuid}` cancels a transfer while it is still pending; once the ACH entry is in progress, settled, failed or already cancelled the cancel is refused, and funding transfers cannot be cancelled, paused, resumed or refunded through the merchant transaction endpoints
- When a funding ACH entry settles, the funds stay in the vendor FBO; if it is returned or rejected the funding is marked failed, settled funds are moved back out of the vendor FBO, and return billing is charged to the vendor
- New webhook events for the vendor and its registered processor: `fbo.funding_created` when the request is saved, `fbo.funding_processing` when the ACH entry is originated, `fbo.funding_completed` when it settles, `fbo.funding_failed` when it is returned or rejected, and `fbo.funding_canceled` when it is cancelled, each with a dedicated funding payload

## 2026.9.15.1

### What's new:
GrailPay has improved how payment statuses are kept up to date. The improvement covers ACH status
changes on transactions, payouts, processor payouts, reverse payouts, clawbacks and refunds, and
FedNow status changes on payouts and processor payouts.

### Why it matters:
Status fields and timestamps move closer to real time, so what an integrator reads from the API or
receives in webhooks reflects a payment's current state sooner, for sent, processed, failed,
cancelled and other states. The lifecycle rules are unchanged: a status still moves only through its
valid states.

### Highlights:
- Faster status updates for ACH payments: transactions, payouts, processor payouts, reverse payouts, clawbacks and refunds
- Faster status updates for FedNow payouts and processor payouts, refreshing status and timing fields and leaving other fields unchanged
- Statuses still move only through valid lifecycle states

## 2026.9.14.1

### What's new:
GrailPay has improved the logic that determines when a capture payment is considered settled.

### Why it matters:
Settlement is what moves a capture forward and triggers the events that follow it. Integrators may
see captures reach their settled state, and receive those events, earlier. A capture still settles
once, and a failed or cancelled capture keeps its status.

### Highlights:
- Improved settlement logic for capture payments
- Settled status and the events that follow settlement may arrive earlier
- A capture is settled once and its completed events are sent once; failed and cancelled captures keep their status

## 2026.9.8.1

### What's new:
Refunds and reverse payouts now wait a configurable number of business days before they are
processed. The delay can be set per vendor or per processor payout configuration, and it applies
when a refund is captured, when a refund is paid out, and when a reverse payout is processed.
Delays are counted in business days, taking bank holidays into account.

### Why it matters:
The delay gives the underlying transaction time to settle before funds move back out. A client that
needs a longer or shorter hold than the platform default can have it configured for its vendor, and
a processor can set one for all of its vendors; where neither is configured the platform default
applies. Integrators should expect refund and reverse payout timing to follow business days rather
than calendar days.

### Highlights:
- Delay periods for refund capture, refund payout and reverse payout processing are configurable per vendor and per processor payout configuration
- A vendor-level delay takes precedence, then a processor-level delay, then the platform default
- Delays are calculated in business days, excluding bank holidays
- All v3 list and fetch endpoints (business, merchant, person, clawbacks, payouts, refunds, transactions and reverse payouts) load related records more efficiently, improving response times

## 2026.9.2.2

### What's new:
Reverse payouts can now be listed and fetched individually on v3, so funds returned to payers can
be tracked directly through the API. Fetching a single reverse payout also returns its related
transaction and payout. On the reverse payout resource, the `trace_id` field has been replaced by
`bank_identifiers`, which reports the bank ID and trace number under the same names used
elsewhere in v3.

### Why it matters:
Until now a reverse payout could only be seen through the transaction it belonged to. With a list
endpoint and filters, an integrator can monitor every reverse payout across transactions, narrow
them by status, return code, date or amount, and reconcile each one from its bank identifiers.
Consumers of the reverse payout resource that read `trace_id` need to switch to
`bank_identifiers`.

### Highlights:
- New v3 endpoints to list reverse payouts and fetch one by UUID
- The list filters by status, ACH return code, transaction, date range and amount (with comparison operators), and sorts by date or amount
- Fetching a single reverse payout includes its related transaction and payout in the same response
- `trace_id` on the reverse payout resource is replaced by `bank_identifiers`, carrying the bank ID and trace number

## 2026.9.2.1

### What's new:
Vendors can now add, list, switch and remove funding bank accounts on their vendor profile
through four new v3 endpoints. Funding accounts are kept separate from payout accounts, so a
vendor can have one default account for funding its FBO and a different default account for
receiving payouts. Vendor fee payouts and the clawbacks of those fees now use the vendor's
designated payout account.

### Why it matters:
A vendor that pre-funds an FBO needs a bank account to fund it from, and that account is often
not the one it wants fees paid into. Keeping the two purposes apart, each with its own default,
lets a vendor manage both through the API without one setting overriding the other, and keeps fee
payments flowing to the payout account even after a funding account is added. Processor and
merchant payout behavior is unchanged.

### Highlights:
- New `POST /api/v3/vendors/{uuid}/bank-accounts` to attach a funding bank account, taking `account_number`, `routing_number`, `account_type`, `account_name`, optional `client_reference_id` and `purposes.funding.enabled`; the first funding account becomes the default automatically, resubmitting the same account reuses it with a 200 instead of a duplicate, and payout accounts cannot be added here
- New `GET /api/v3/vendors/{uuid}/bank-accounts` listing the vendor's accounts with masked account numbers and `purposes.funding` and `purposes.payout` flags showing which account is the default for each purpose; an empty list is returned when there are none
- New `PUT /api/v3/vendors/{uuid}/bank-accounts/{bank_account_uuid}/default` to make an existing funding account the default funding source
- New `DELETE /api/v3/vendors/{uuid}/bank-accounts/{bank_account_uuid}` to remove a funding account; removal returns 422 if the account was used within the recent-activity window (30 days by default), and if the removed account was the default another funding account is promoted
- All four endpoints accept vendor keys only: processor keys receive 403, and an unknown or unowned vendor UUID returns 404
- Vendor fee payouts and clawbacks of vendor fees use the vendor's designated payout account; processor and merchant payout behavior is unchanged

## 2026.9.1.1

### What's new:
The v3 payout endpoints now serve processor payouts as well as regular payouts, v3 transactions
can be filtered by the payout they belong to, and v3 billing items return the merchant's client
reference ID.

### Why it matters:
A processor can now manage its own payouts through the same v3 interface as everything else, and
any integrator can go from a payout, processor or regular, to the transactions it covers with one
filtered request. The client reference ID on billing items lets billing records be mapped to the
integrator's own records using the reference it supplied at onboarding. Note that the v3 payout
detail response now returns the related transaction's UUID instead of the whole transaction
object.

### Highlights:
- `GET /api/v3/payouts` accepts `filter[payout_type]=processor` to list processor payouts, and the fetch endpoint returns a processor payout by its UUID; processor payouts are available to processor users only
- The v3 payout detail response returns the related transaction's UUID instead of the complete transaction object, for both regular and processor payouts
- `GET /api/v3/transactions` accepts `filter[payout_uuid]`, returning the transactions associated with a regular or processor payout
- `GET /api/v3/billing/items` returns `client_reference_id`, the merchant's reference supplied at onboarding, or `null` when none is configured; existing fields are unchanged

## 2026.8.31.1

### What's new:
The SEC code of each ACH entry is now returned across the v3 API. A `sec_code` field (`ccd`,
`web` or `ppd`) appears on transactions, payouts, processor payouts, clawbacks and reverse
payouts, and on both the capture and payout sides of a refund, wherever those resources are
returned by v3 endpoints or webhook events. The v3 refund resource has also been simplified:
batch membership now lives only in the nested `batch` object.

### Why it matters:
An integrator that reconciles or reports on ACH activity can now read the SEC code directly from
each resource and event instead of inferring it, and the same field appears in the same place
across every payment type. The refund change removes two redundant fields, so refund consumers
should read batch membership from `batch` alone.

### Highlights:
- `sec_code` added to the v3 transaction, payout, processor payout, clawback and reverse payout resources, and to the `capture` and `payout` sections of the v3 refund resource, with values `ccd`, `web` or `ppd` (or `null`)
- The field is carried wherever those resources appear, including every v3 webhook event that embeds them
- The v3 refund resource no longer includes top-level `is_batch` or `batch_uuid`; a non-batched refund returns `"batch": null`, and a batched refund's `batch` object holds `uuid`, `refund_count` and `total_amount`, placed after `timestamps`
- `filter[is_batch]` and `filter[batch_uuid]` on the v3 refund list are unchanged
- The `batch_refund` webhook's `data.batch_refund.uuid` is the shared batch UUID
- The API reference documents the refund `amount` as an integer in cents

## 2026.8.26.1

### What's new:
GrailPay has improved how reverse payouts are originated after a payout is returned, so a reverse
payout can begin sooner. Separately, merchant onboarding on v2 and v3 now creates the merchant and
its beneficial owners even when business verification cannot be reached at the time of the request.

### Why it matters:
Funds can start their way back to the payer sooner after a return, with no change to the amount, the
payer-facing behavior or notification timing. On onboarding, the availability of business
verification does not block the integrator's onboarding call.

### Highlights:
- Reverse payouts are originated sooner after a payout return
- Reverse payout amounts, payer-facing behavior and notification timing are unchanged
- v2 and v3 merchant onboarding create the merchant and its beneficial owners even if business verification is unavailable at the time

## 2026.8.21.1

### What's new:
Refunds can now be created on v3 with `POST /api/v3/refunds`. Refund creation on both v1 and v3
is now asynchronous: a new refund is accepted with a `QUEUED` status and processed in the
background, and a refund that would exceed the origination limit waits for capacity instead of
being rejected. The v3 refund list and fetch responses also expose batch membership.

### Why it matters:
Until now a refund request that reached the origination limit came back as an error the
integrator had to retry itself. With queued processing, the request is accepted immediately and
GrailPay retries it when capacity is available, so creating a refund is a single call regardless
of volume. `QUEUED` is the first state a refund passes through, so integrators that drive
workflows from refund status should expect it before `REFUND_PENDING`. On v3, the batch fields and
filters make it possible to find every refund that was captured together.

### Highlights:
- New `POST /api/v3/refunds` taking `transaction_uuid`, `amount` (integer) and an optional `client_reference_id`; returns 201 with the full refund resource in `QUEUED` status and supports the standard idempotency header
- Eligibility checks (ownership, refundable transaction, remaining refundable amount) return 422 with field-level errors
- On both v1 and v3, refunds are created `QUEUED` and processed asynchronously; v1 now returns 201 with status `QUEUED` instead of 429 when the origination limit is reached
- A refund that exceeds the origination limit stays `QUEUED` and is retried until capacity is available, then moves to `REFUND_PENDING`
- Queued refunds count toward a transaction's remaining refundable amount
- v3 refund list and fetch responses include `is_batch` and an embedded `batch` summary; the list accepts `filter[batch_uuid]` and `filter[is_batch]`
- The API reference documents the v3 refund endpoints, the batch fields and filters, and the `QUEUED` status

## 2026.8.20.2

### What's new:
Transactions can now be created on v3 with `POST /api/v3/transactions`, identifying the payer and
payee by UUID. The request accepts an optional `modality` object that sets the payment rail and
speed for the debit and for the payout separately, across ACH standard, ACH same day and, where
it is enabled for the vendor, FedNow. Transaction responses and transaction and payout webhook
payloads now include a `modality` object alongside the existing `speed` field.

### Why it matters:
With creation on v3, the whole transaction lifecycle lives on one API version, and the modality
object gives explicit control over how each leg moves, so a debit and its payout can run on
different rails or speeds. Existing consumers are unaffected: `speed` is still populated, now
derived from the chosen modality.

### Highlights:
- New `POST /api/v3/transactions` with `payer_uuid`, `payee_uuid` and `amount` required, plus optional `transaction_fee`, `client_reference_id`, `company_name`, `description`, `addenda`, `source_bank_account_uuid` and `destination_bank_account_uuid`; the transaction is queued and returned with 201
- Optional `modality` object with `transaction` and `payout` legs, each taking a `payment_rail` and `speed`; FedNow is accepted only for vendors allowed to use it
- `modality.payout` is rejected for vendors whose payouts go out through processor batch payouts
- Transaction responses (list, fetch and create) include a `modality` object with `transaction` and `payout` legs; the existing `speed` field remains
- Transaction and payout webhook events include a `modality` object with `payment_rail` and `speed`; `speed` is still present and derived from the modality
- The API reference documents the new endpoint, including the `modality` object and all response codes

## 2026.8.3.1

### What's new:
The global API rate limit has been raised to 2,000 requests per minute. It was previously 400.

### Why it matters:
High-volume clients, such as those submitting recurring autopay batches, now have more room during
peak minutes. The limit still protects the platform: requests beyond it are rejected with a 429 and
the message "Too many attempts".

### Highlights:
- Global API throttle raised from 400 to 2,000 requests per minute across environments
- The limit applies per user ID or IP address; requests over it receive a 429 "Too many attempts" response

## 2026.7.28.1

### What's new:
Clawbacks are now created for payouts sent through FedNow, both processor payouts and
individual payouts, in the same way as for ACH payouts.

### Why it matters:
A client paying out through FedNow now gets the same recovery workflow as on ACH: when a payout
needs to be recovered, a clawback is generated and shows up in the same clawback records,
responses and webhook events, so reconciliation does not depend on which rail the payout used.

### Highlights:
- Clawback creation covers FedNow payouts, for both processor and individual payouts

## 2026.7.24.1

### What's new:
Every v3 payment resource and every v3 webhook payload now carries a standardized
`bank_identifiers` object holding the bank ID and trace ID for the money movement it represents.
The same object has been added to the remaining v1 webhook events, completing its rollout across
the v1 webhook suite.

### Why it matters:
Bank identifiers are what tie a GrailPay record to the entry on a bank statement. With one object
in one shape on every payment resource and every event, an integrator can reconcile transactions,
payouts, refunds and clawbacks with a single piece of parsing code, whether the data arrives from
an API call or a webhook.

### Highlights:
- `bank_identifiers` added to the v3 List and Fetch endpoints for transactions, payouts, refunds and clawbacks
- `bank_identifiers` added to all v3 transaction, payout, processor payout, refund, batch refund, reverse payout and clawback webhook events
- `bank_identifiers` added to the v1 Payout, Reverse Payout, Refund, Batch Refund and Batch Payout webhook events, so every v1 payment webhook now carries it
- The object holds both the bank ID and the trace ID, and the API reference and resource documentation describe its fields

## 2026.7.22.1

### What's new:
The standardized `bank_identifiers` object now appears in the v1 processor payout webhook events,
in the v1 and v2 Batch Payout API responses, and in clawback webhook events.

### Why it matters:
Processors and batch payout consumers previously had to read bank identifiers from
version-specific fields or look them up separately. With the same `bank_identifiers` object in
these payloads, the identifiers needed to match a payout or clawback to bank activity arrive in
one consistent shape, and existing payload fields are untouched.

### Highlights:
- v1 processor payout webhook events (`BatchPayout`, `ProcessorPayoutCreated`, `ProcessorPayoutCompleted`, `ProcessorPayoutFailed`) include `bank_identifiers` with `credit_bank_id` and `credit_trace_id`
- v1 and v2 Batch Payout endpoints return a `bank_identifiers` object on each payout; identifiers that are not yet available are returned as `null` rather than omitted
- Clawback webhook events include a `bank_identifiers` object with both internal and external identifiers; existing payload fields are preserved

## 2026.7.21.1

### What's new:
The v3 payout endpoints are now publicly available and documented in the API reference. Vendors
can retrieve payouts with their existing tokens, provided the token carries the transactions
fetch ability.

### Why it matters:
With `GET /api/v3/payouts` and `GET /api/v3/payouts/{uuid}` open, an integrator can list and inspect
payouts directly, including standalone payouts, using the filters, sorting, pagination and includes
described in the reference, without needing a new token.

### Highlights:
- `GET /api/v3/payouts` and `GET /api/v3/payouts/{uuid}` are publicly available
- The API reference documents both endpoints, including filters, sorting, pagination and include parameters, with standalone payouts in the examples
- A vendor token with the transactions fetch ability can call them; no new ability is required

## 2026.7.17.1

### What's new:
The v2 List Transactions and Fetch Transaction responses now include a `bank_identifiers` object
that gathers the bank and trace identifiers for a transaction and every payment activity related
to it. All v1 transaction webhook events carry a `bank_identifiers` object as well. On the v3
Returns endpoint, the generic `bank_id` and `trace_id` fields have been replaced by direction-specific
names.

### Why it matters:
Reconciling a transaction against bank activity has meant collecting identifiers from several
places, since the debit, the payout, any clawback, reverse payout or refund each has its own.
With them grouped under `bank_identifiers`, an integrator reads them from one object in one
response or one webhook. On Returns, the directional names make clear whether an identifier
belongs to the debit or the credit side, so a return can be matched without guessing.

### Highlights:
- v2 List Transactions and Fetch Transaction include `bank_identifiers` with `transaction` (`debit_bank_id`, `debit_trace_id`), `payout` (`credit_bank_id`, `credit_trace_id`), `clawback`, `reverse_payout`, and `refunds` with separate `capture` and `payout` sections
- All v1 transaction webhook events (`TransactionStarted`, `TransactionCaptureStarted`, `TransactionCompleted`, `TransactionFailed`, `TransactionCanceled`, `TransactionPaused`, `TransactionResumed`, `TransactionDeclined`, `TransactionAwaitingCancellation`) include `bank_identifiers` with `debit_bank_id` and `debit_trace_id`
- On `GET /api/v3/returns`, `bank_id` and `trace_id` are replaced by `debit_bank_id`, `credit_bank_id`, `debit_trace_id` and `credit_trace_id`, depending on the leg the return occurred on
- When a paused transaction is resumed and a replacement ACH entry is created, the transaction's bank identifier is updated to reference the new entry

## 2026.7.14.1

### What's new:
The v3 Clawback List and Show endpoints are now documented in the API reference, and their
`relations.payout` object includes the payout's `uuid`, `trace_id` and `status`. Passing
`?include=payout` still returns the full payout resource.

### Why it matters:
Most clawback consumers need the related payout's identity and state, not its whole record.
Having `uuid`, `trace_id` and `status` inline avoids a second request for the common case, while
`include=payout` remains for callers that want everything. Only new fields were added, so existing
consumers are unaffected.

### Highlights:
- v3 Clawback List and Show are documented in the API reference, including filters, sorting, includes and the response structure
- `relations.payout` on a clawback now includes `uuid`, `trace_id` and `status`
- `?include=payout` continues to return the full payout resource

## 2026.7.13.2

### What's new:
A new `GET /api/v3/returns` endpoint lists every ACH return visible to the authenticated entity
in one place, regardless of which leg of a transaction the return occurred on.

### Why it matters:
Until now an ACH return had to be found through the transaction or payout it belonged to, which
meant checking several places to see everything that had come back. The Returns endpoint merges
returns from both the debit and the payout side into a single paginated list, so an integrator
can monitor returns with one query and filter down to a specific transaction, payout, clawback,
reverse payout, entity or bank reference when needed.

### Highlights:
- `GET /api/v3/returns` returns a paginated list of ACH returns across transactions and payouts for the authenticated entity
- Filters cover the leg of the transaction the return occurred on, ACH return codes, amount with comparison operators, the related transaction, payout, clawback or reverse payout UUID, the entity UUID, the vendor, and the bank or trace identifier
- The endpoint is documented in the API reference

## 2026.7.10.2

### What's new:
The standalone Person KYC endpoint is now documented in the API reference.

### Why it matters:
Integrators verifying individuals outside of merchant onboarding can now work from the published
request and response definitions for the endpoint instead of relying on guidance supplied
directly.

### Highlights:
- The Person KYC endpoint's request, response and error definitions are published in the API reference

## 2026.7.9.3

### What's new:
When a transaction fails, any reverse payout for it that is still pending is cancelled
automatically. If the reverse payout had already initiated its ACH entry, that entry is cancelled
as well.

### Why it matters:
A reverse payout exists to send funds back for a transaction, so once that transaction has
failed there is nothing left to reverse. Cancelling it automatically means an integrator does not
have to watch for the failure and cancel the reverse payout itself, and the reverse payout's
records and status stay consistent with the transaction's outcome.

### Highlights:
- A pending reverse payout is cancelled when its transaction fails, including when the failure arrives through a return
- If the reverse payout had already initiated an ACH entry, the entry is cancelled too; the cancellation is recorded with a reason
- Cancellation applies only to eligible reverse payouts, and the reverse payout is left unchanged if its ACH entry cannot be cancelled

## 2026.7.3.1

### What's new:
The `failure_simulation` parameter has been removed from the v1 Create Transaction endpoint and
from its documentation. The API reference for the v1 Add Bank Account endpoint now also documents
the `200 OK` response returned when the account already exists.

### Why it matters:
Integrators that still send `failure_simulation` on v1 Create Transaction can remove it from their
requests. The documented `200 OK` lets an integrator handle the already-exists case on Add Bank
Account deliberately rather than treating anything but `201` as an error.

### Highlights:
- `failure_simulation` is no longer accepted or documented on the v1 Create Transaction endpoint
- `POST /3p/api/v1/bank-account/{user_uuid}` documents a `200 OK` response for an account that already exists, alongside the existing `201 Created`

## 2026.7.1.1

### What's new:
The v3 bank account API is now complete. Alongside the existing list, fetch and balance
endpoints, v3 gains endpoints to add a bank account, switch an entity's default account, delete
an account and read an account's transaction history. The balance endpoint now also serves
accounts linked through the previous aggregator, and the API reference carries full
specifications for every v3 bank account endpoint.

### Why it matters:
Until now, managing bank accounts meant mixing v3 reads with v1 or v2 writes. With add, switch
default and delete on v3, an integrator can handle the whole bank account lifecycle on one API
version, with the same entity model, masking rules and response envelope throughout, and read
balances and transaction history for the accounts it manages there.

### Highlights:
- New `POST /api/v3/bank-accounts` to add a manually entered or aggregator-linked bank account to a person, business or merchant; adding an account that already exists returns the existing account instead of a duplicate
- New `PUT /api/v3/bank-accounts/{uuid}/default` to make an account the entity's default, with a distinct response when it already is
- New `DELETE /api/v3/bank-accounts/{uuid}`, which cleans up the provider link, reassigns the default account if needed and emits the bank account removed webhook event
- New `GET /api/v3/bank-accounts/{uuid}/history` returning the account's transactions with pagination, a `next_cursor` where applicable, and optional `start_date` and `end_date` filters
- `GET /api/v3/bank-accounts/{uuid}/balance` returns available balance and currency for accounts linked through the previous aggregator as well as the current one
- Accounts whose linking has not completed are excluded from list responses
- The API reference now documents every v3 bank account endpoint under a "V3 Bank Accounts" tag, with standardized success and error envelopes

## 2026.6.30.2

### What's new:
Vendors can now process person-to-person (P2P) transactions, where both the payer and the payee
are persons. P2P is enabled per vendor by GrailPay, and a P2P transaction is accepted only when
the payee has an approved KYC status.

### Why it matters:
Until now a transaction had to involve a merchant or business on at least one side. With P2P
enabled, an integrator can move funds between two onboarded persons through the same v1 Create
Transaction request it already uses, and the KYC requirement on the payee keeps those transfers
within the platform's compliance rules. Merchant and business transaction flows are unchanged.

### Highlights:
- A transaction whose payer and payee are both persons is treated as a P2P transaction on the v1 Create Transaction endpoint
- P2P transactions require the vendor's P2P capability to be enabled by GrailPay; it is off by default
- The payee must have an approved KYC status, and the payer and payee cannot be the same person
- Each of these conditions returns its own validation error when not met

## 2026.6.29.2

### What's new:
Webhook subscribers are now notified when a Notification of Change (NOC) is received, not only
when it has been processed. A new `noc.received` event (v3) and `NocReceived` event (v1) fire as
soon as a NOC request is created, and `noc.processed` (v3) and `NocProcessed` (v1) fire once the
NOC has been processed, whether that happened automatically or through GrailPay's operators.

### Why it matters:
A NOC means the bank has told GrailPay that an account's details are changing. With a received
event, an integrator learns about the change as soon as it arrives and can start tracking it,
instead of only hearing about it after the change has been applied. The processed event then
confirms that the updated banking details are in place, so downstream records can be
synchronized at the right moment.

### Highlights:
- New `noc.received` webhook event for v3 subscribers and `NocReceived` for v1 subscribers, sent when a NOC request is received
- `noc.processed` (v3) and `NocProcessed` (v1) are sent when a NOC request has been processed successfully, whether automatically or by GrailPay
- Processed events are sent only after processing succeeds; nothing is sent if processing fails or is rolled back

## 2026.6.29.1

### What's new:
The `BatchPayout` and `BatchRefund` webhook events now include a `trace_id` in their payloads.

### Why it matters:
The trace identifier is what lets an integrator match the webhook event to the entry on its bank
statement and to its own records. Having it in the payload removes a lookup step from
reconciliation.

### Highlights:
- `trace_id` added to the `BatchPayout` webhook event payload
- `trace_id` added to the `BatchRefund` webhook event payload

## 2026.6.25.2

### What's new:
The v3 Fetch Transaction response now includes a `clawback` object at its root, alongside the
existing `payout` and `refunds` objects, holding the transaction's clawback when one exists and
`null` otherwise. In clawback webhook events, the `clawback_bank_identifier` field has been
renamed to `clawback_trace_id`, matching the trace ID naming used elsewhere in the API.

### Why it matters:
An integrator reading a transaction can now see its clawback in the same response instead of
looking it up separately. The rename is a breaking change for webhook consumers: the
`clawback_bank_identifier` key is no longer sent, so any code reading it from
`ClawbackCaptureStarted`, `ClawbackFailed` or `ClawbackCompleted` events must switch to
`clawback_trace_id`.

### Highlights:
- v3 Fetch Transaction returns a `clawback` object at the root of the response, in the standard clawback response format, or `null` when the transaction has no clawback
- Clawback webhook events (`ClawbackCaptureStarted`, `ClawbackFailed`, `ClawbackCompleted`) now send `clawback_trace_id` in place of `clawback_bank_identifier`; the old key is no longer included

## 2026.6.25.1

### What's new:
The v2 Fetch Transaction and List Transactions endpoints now return a `clawback_trace_id` inside
each transaction's `trace_ids` object when the transaction has a clawback.

### Why it matters:
With `clawback_trace_id` in `trace_ids`, an integrator can match a transaction's clawback to the
corresponding bank entry from the transaction record alone.

### Highlights:
- `trace_ids.clawback_trace_id` added to the v2 Fetch Transaction and List Transactions responses, present when a related clawback exists

## 2026.6.23.1

### What's new:
The financing product has been retired and its API surface removed. The financing API, the v1
invoice endpoints under `/users/{user_uuid}/invoices`, the `financing_credit_balance` field on
business responses, and the financing token types and abilities are gone.

### Why it matters:
No live integrations were calling the financing or invoice endpoints, so the removal should not
affect current clients. Any code still reading `financing_credit_balance` from a business
response should stop expecting it. Transactions that were created under the financing product
are no longer subject to its cancellation restriction.

### Highlights:
- The financing API routes and the v1 third-party invoice endpoints (`/users/{user_uuid}/invoices` and related) have been removed
- `financing_credit_balance` is no longer returned on v2 and v1 business responses
- Financing token types and authorization abilities have been removed
- The cancellation restriction that applied to financing transactions has been removed; the financing transaction type and status values are kept for historical records

## 2026.6.19.1

### What's new:
A vendor can now have a preferred batch payout modality configured, either ACH same day or ACH
standard. When it is set, every eligible transaction for a payee is consolidated into a single
payout at that speed, instead of one payout per speed.

### Why it matters:
Until now batch payouts were grouped by transaction speed, so a payee with both standard and
same-day transactions received two payouts. With a modality configured, that payee receives one
payout at the vendor's chosen speed, which simplifies reconciliation for the payee and makes
payout timing predictable for the vendor. Vendors without a configured modality keep the current
behavior.

### Highlights:
- Vendor-level batch payout modality setting, configured by GrailPay, with `ach.sameday` and `ach.standard` as the supported values
- When set, all eligible transactions for a payee are aggregated into a single payout at the configured speed; no separate payout is created for the other speed
- Applies to merchant, business and person batch payouts, independently per vendor
- Vendors without a configured modality keep the existing behavior, one payout per speed

## 2026.6.17.2

### What's new:
Clawback webhook events now carry a `clawback_bank_identifier`, the bank-side identifier of the
ACH entry created for the clawback.

### Why it matters:
Until now clawback events gave no way to tie the event to the ACH record behind it, so
reconciling a clawback against bank activity meant extra lookups. With the identifier in the
payload, an integrator can correlate each clawback event with the corresponding ACH entry
directly. All existing payload fields are unchanged.

### Highlights:
- `clawback_bank_identifier` added to every clawback webhook event
- It is `null` on `ClawbackStarted`, before the ACH entry exists, and carries the ACH identifier on `ClawbackCaptureStarted`, `ClawbackCompleted` and `ClawbackFailed`
- Existing clawback payload fields are unchanged

## 2026.6.17.1

### What's new:
The v1 and v2 bank account endpoints now support accounts linked through the new Bank Link
aggregator. Account balance (v1 and v2), cashflow prediction (v1) and transaction history (v2) work
for these accounts.

### Why it matters:
Integrators on v1 and v2 do not need to move to v3 to work with accounts linked through the current
Bank Link SDK. The endpoints they already call read balances, cashflow predictions and transaction
history for those accounts, and keep working for accounts added any other way.

### Highlights:
- Get account balance (v1 and v2) returns balances for accounts linked through the new aggregator, provided the account is connected
- Cashflow prediction (v1) and transaction history (v2) support accounts linked through the new aggregator
- Existing response structure and pagination behavior are preserved

## 2026.6.12.1

### What's new:
Processors can now activate and deactivate merchants that belong to their vendors, using the
existing v3 merchant activation and deactivation endpoints with a processor token that has been
granted the corresponding ability.

### Why it matters:
A processor that deactivates a merchant on its own side can now mirror that change in GrailPay
through the API, keeping merchant status consistent across both systems without asking the vendor
to do it. Ownership checks ensure a processor can only act on merchants under its own vendors.

### Highlights:
- Processor tokens can call the v3 activate and deactivate merchant endpoints for merchants of their associated vendors
- A new token ability covers these actions and must be granted to the processor token
- Ownership and business-type checks apply, so a processor cannot act on another processor's vendors or merchants

## 2026.6.10.1

### What's new:
Vendors can now send standalone payouts, which are payouts with no associated transaction, funded
from the vendor's own pre-funded FBO account. A new v3 endpoint creates them, and another returns
the vendor's FBO account details and current balance so the vendor can tell when the account
needs a top-up. Standalone payouts flow through the same processing, status tracking, reporting
and payout webhooks as transaction-backed payouts.

### Why it matters:
Until now every payout was tied to a transaction, so a vendor had no way to pay a person,
business or merchant through GrailPay for anything that was not a payment it had collected.
Standalone payouts open that up, and because they draw on the vendor's pre-funded account, the
FBO endpoint matters: an integrator can watch the balance and keep it funded, and a payout that
would exceed it is rejected rather than attempted. Failed standalone payouts are handled for the
vendor automatically.

### Highlights:
- New `POST /api/v3/payouts/standalone` creating a payout to an entity's default bank account; `entity_uuid`, `amount` and `speed` are required, and `speed` accepts `standard`, `fast` or `fednow`
- Standalone payouts must be enabled for the vendor by GrailPay, the vendor must have a pre-funded FBO account, and the token needs the standalone payout ability; otherwise the request returns 403
- Requests are idempotent through the `x-gp-request-id` header, so a replay returns the original response instead of creating a second payout
- A payout larger than the vendor's available pre-funded balance is rejected; the minimum `amount` is 10 (amounts are integers in cents)
- `fednow` is accepted only for vendors with FedNow enabled; otherwise the request is rejected with a message that FedNow is not available on the account
- New `GET /api/v3/vendors/{uuid}/fbo` returning the vendor's FBO account: bank name, name on account, full routing and account numbers, balance in cents, currency and the time the balance was last refreshed; vendor tokens only
- Standalone payouts appear in the v3 list and fetch payout endpoints with `transactions: []`, and can be filtered with `?payout_type=standalone`
- Standalone payout responses include the recipient's bank account details
- Existing payout webhook events cover standalone payouts, attributed to the owning vendor
- A failed ACH standalone payout returns the funds to the vendor's pre-funded account; a failed FedNow standalone payout is automatically re-sent as an ACH standalone payout to the same recipient for the same amount

## 2026.6.9.2

### What's new:
The company name that appears on batch payouts can now be set per vendor. Vendors without a
configured name keep the default, GrailPay.

### Why it matters:
A vendor that wants its own name rather than GrailPay's on its batch payouts can have it configured,
while every other vendor's payouts are unchanged.

### Highlights:
- Vendor-specific company name for batch payouts, configured by GrailPay; the default remains GrailPay when none is set
- Originator names on payouts are sanitized and formatted automatically

## 2026.6.1

### What's new:
API responses that list an entity's bank accounts now include only accounts that are fully
connected and active. An account whose bank linking has not yet completed is not returned until
it is.

### Why it matters:
A partially linked account cannot be used for a payment, so showing it alongside usable accounts
invites a bad selection. With pending accounts hidden until linking completes, an integrator can
treat every account in a response as ready to use.

### Highlights:
- Bank account lists across the bank account endpoints return only connected, active accounts; pending accounts appear once the bank linking process has completed
- Existing filtering and pagination behavior is unchanged

## 2026.5.25.1

### What's new:
v3 webhook payloads for clawback, payout, processor payout, refund and reverse payout events now
carry the related transaction and payout as embedded objects under a `relations` key. The
clawback and reverse payout objects themselves no longer nest those relationships at the top
level.

### Why it matters:
Until now these payloads exposed mostly identifiers for related records, so acting on an event
meant a follow-up API call to fetch the transaction or payout it belonged to. With the related
objects embedded, an integrator can process the event from the webhook alone. Consumers that
read related records from the old top-level fields need to move to the `relations` object.

### Highlights:
- Clawback, payout, processor payout, refund and reverse payout webhook events include a `relations` object holding the related transaction and payout
- Clawback and reverse payout objects no longer include nested relationship fields at the top level; read them from `relations` instead

## 2026.5.22.2

### What's new:
The v3 Get All Transactions and Get Transaction endpoints are now public routes, available to any
authenticated client.

### Why it matters:
Authorized clients can now read transaction data directly from v3, under the same authentication and
authorization rules as the rest of the API.

### Highlights:
- `GET /api/v3/transactions` and `GET /api/v3/transactions/{uuid}` are publicly accessible, with the existing authentication and authorization rules
- The API reference for the v3 transaction endpoints now documents the ACH timestamps schema

## 2026.5.22.1

### What's new:
The v2 Delete Bank Account endpoint now supports bank accounts linked through the new Bank Link
aggregator. These accounts can be removed through the same API flow used for every other bank
account provider.

### Why it matters:
Deletion now behaves the same way across providers, and the existing validation rules and ownership
checks apply unchanged.

### Highlights:
- The v2 Delete Bank Account endpoint identifies and processes accounts linked through the new Bank Link aggregator
- Deletion behavior is aligned across supported bank linking providers; existing validation rules and ownership checks still apply

## 2026.5.21.1

### What's new:
Bank accounts linked through the new Bank Link aggregator can now be used for payments. They are
accepted as the source or destination of a v1 transaction and in v1 refunds, and they appear in
the payer and payee details of transaction, payout, refund, clawback, merchant, business and
person responses across v1, v2 and v3, as well as in webhook payloads.

### Why it matters:
With these accounts accepted everywhere the existing account types are, an integrator can link an
entity's bank account through the current SDK and create transactions, payouts and refunds against
it without any provider-specific handling. Responses keep the same structure for every provider, so
nothing changes for accounts linked another way.

### Highlights:
- Accounts linked through the new aggregator are accepted as the source and destination of a v1 Create Transaction request, alongside manually entered and previously linked accounts
- Refunds can be created for transactions and payouts that involve these accounts
- Transaction, payout, refund, clawback, merchant, business and person responses include these accounts in their payer and payee bank account details, with a consistent structure across providers
- Webhook payloads include the bank account details for these accounts
- Account and routing numbers for these accounts are masked in responses outside the bank account endpoints and in webhook payloads
- The payer and payee UUIDs on a transaction may reference either a person or a merchant

## 2026.5.19.1

### What's new:
GrailPay has upgraded the v3 webhook system. A much wider set of events is delivered in real time
across transactions, payouts, refunds, clawbacks, reverse payouts, bank accounts, persons,
merchants, businesses and compliance status. Delivery is queued with automatic retries and backoff,
and every attempt is logged.

### Why it matters:
With event coverage for the whole payment lifecycle, an integrator can drive its own workflows from
events instead of polling, and because failed deliveries are retried, a temporarily unavailable
endpoint does not miss notifications. A webhook whose deliveries keep failing is deactivated
automatically, so endpoint health is worth monitoring.

### Highlights:
- Payloads are versioned (`event_version` 3) and carry an event UUID and timestamp
- Failed deliveries are retried automatically on a backoff schedule; a webhook that keeps failing is deactivated
- Transaction events: `transaction.created`, `transaction.processing`, `transaction.completed`, `transaction.failed`, `transaction.paused`, `transaction.resumed`, `transaction.awaiting_cancellation`, `transaction.cancelled`, `transaction.declined`
- Payout events: `payout.created`, `payout.processing`, `payout.completed`, `payout.failed`, and the same four stages for `processor_payout`, `clawback` and `reverse_payout`
- Refund events: `refund.created`, `refund.cancelled`, `batch_refund`, `refund.capture_processing`, `refund.capture_completed`, `refund.capture_failed`, `refund.payout_processing`, `refund.payout_completed`, `refund.payout_failed`
- Entity events: `person.created`, `person.updated`, `person.status_changed`, `merchant.created`, `merchant.updated`, `business.created`, `business.updated`
- Compliance events: `compliance_status.processing`, `compliance_status.in_review`, `compliance_status.approved`, `compliance_status.rejected`
- Bank account events: `bank_account.link_success`, `bank_account.link_failed` (with a `failed_reason`), `bank_account.removed`, and `noc.processed` carrying the previous and current account details
- Payout responses include a `payout_failure_reason` when an ACH return code is present
- Refund responses include batch identifiers and bank transaction tracking references
- Every delivery attempt, retry and failure is logged for troubleshooting

## 2026.5.8.1

### What's new:
The v3 Get All Refunds and Get Refund endpoints are now public. The list endpoint supports filtering
by status, amount (with comparison operators), dates and ACH identifiers, plus sorting and
pagination, and a single refund's response includes its parent transaction.

### Why it matters:
Until now the v3 refund endpoints were not public. With the list endpoint open, an integrator can
query refunds across transactions with filters and pagination, and read each refund together with
its parent transaction and batch identifier in one call.

### Highlights:
- `GET /api/v3/refunds` is publicly available, with filtering by status, amount with operators, dates and ACH identifiers, plus sorting and pagination
- `GET /api/v3/refunds/{uuid}` is publicly available and includes the parent transaction
- Refund responses document a nullable `batch_uuid` and expanded inline `bank_account` fields
- The API reference for the v3 bank account list and fetch endpoints now documents `client_reference_id` and `person_uuid` in the entity object

## 2026.5.6.1

### What's new:
Refunds can now be created for transactions whose processor payout was completed through FedNow.

### Why it matters:
A client that pays out through FedNow can refund those payments through the same refund
endpoints it already uses, with no separate handling for the payout rail.

### Highlights:
- Refund requests are accepted for settled transactions whose processor payout completed through FedNow

## 2026.5.1.1

### What's new:
The v3 API gains a bank account balance endpoint, which returns the available and current
balance of a linked bank account on demand. Bank accounts also accept an optional
`client_reference_id` when they are linked, and the value is returned in bank account and entity
responses.

### Why it matters:
A client can now check available funds before initiating a transaction against a linked
account. And with `client_reference_id` stored on the bank account as well as the entity, an
integrator can reconcile GrailPay records against its own identifiers without keeping a separate
mapping.

### Highlights:
- New `GET /api/v3/bank-accounts/{uuid}/balance` returning `uuid`, `provider`, the available and current balances, `limit`, `currency` and `as_of`
- The balance endpoint is available for accounts linked through the new Bank Link aggregator; it returns 403 when the token lacks the required ability, 422 for a provider that does not support balance checks, and 404 for an account whose connection is not yet complete
- Bank accounts accept an optional `client_reference_id` (up to 255 characters) at linking time, returned in bank account, entity and session responses

## 2026.4.28.1

### What's new:
Bank Link can now run on a vendor's own bank aggregator configuration. A client with its own
aggregator credentials and environment can have them configured for its vendor, so the bank
linking experience carries the client's branding and runs in its own environment. Existing
integrations continue on GrailPay's default configuration with no changes required.

### Why it matters:
A client that wants its own branding in the bank linking flow, or needs its aggregator environment
kept separate from other vendors, can now have that without changing how it calls the API. Webhooks
from the aggregator are validated with the vendor's own secret when one is configured, so each
vendor's integration stays isolated from the others.

### Highlights:
- Vendor-specific bank aggregator configuration, so a client can use its own credentials, environment and branding for bank linking
- Configured by GrailPay per vendor; vendors without their own configuration fall back to GrailPay's default, so existing integrations keep working unchanged
- Aggregator webhooks are validated with the vendor's own secret when one is configured, with the same fallback, improving isolation between vendor integrations
- Credentials and webhook secrets are stored encrypted

## 2026.4.23.1

### What's new:
The v3 bank account endpoints now return the full routing number and account number for each
bank account. Previously these fields carried only the last four digits.

### Why it matters:
An integrator that reads a linked bank account through the v3 API now gets the complete account
and routing numbers in the same response, so production integrations that depend on the full
values can rely on the v3 endpoints.

### Highlights:
- The v3 list and fetch bank account endpoints return the full `account_number` and `routing_number` values

## 2026.4.17.1

### What's new:
The Bank Link SDK now runs on a new bank aggregation integration that supports multiple
aggregators through one interface, with feature parity and backward compatibility for every
existing callback and configuration option. Alongside it, the v3 API gains endpoints for listing
bank accounts, fetching a single bank account, and retrieving the verified owners of a linked
account.

### Why it matters:
Until now there was no v3 endpoint for reading linked bank accounts back out of the API. An
integrator can now list an entity's accounts, fetch one by its UUID, read its owners, and see from
its status whether the account and routing numbers have been retrieved yet. Because the aggregator
migration keeps every existing callback and configuration option working, current Bank Link
integrations need no changes to benefit from the improved institution coverage.

### Highlights:
- The Bank Link SDK has migrated to a new bank aggregator integration, with feature parity and backward compatibility for all existing callbacks and configuration options
- New v3 endpoint to list bank accounts, with filtering by entity, account type, default status, provider and name, sorting, and pagination
- New v3 endpoint to fetch a single bank account by UUID, returning masked account and routing numbers, the owning entity, and timestamps
- New v3 endpoint to retrieve the owners of a linked bank account, with each owner's name returned as a structured `names` object
- Bank account responses include a `status` of `pending`, `connected` or `failed`, reflecting whether account and routing numbers have been retrieved; failed retrievals are retried automatically
- Account verification is supported through the new integration, and the bank name is now stored for each linked account
- Processors can access bank accounts belonging to their associated vendors
- Improved performance and consistency in bank account retrieval

## 2026.4.3.1

### What's new:
GrailPay now enforces transaction rules when a transaction is created and while it is processed.
A rule can add a settlement delay or decline the transaction outright, and rules apply either
globally or to a specific vendor. Declined transactions carry a new `declined` status, with
`declined_reason` and `declined_at` in transaction responses, and a new `TransactionDeclined`
webhook event is sent whenever a decline occurs.

### Why it matters:
A transaction can now be declined before it ever reaches the processing queue, so an integrator may
see a `declined` status immediately after creation rather than a failure later in the lifecycle.
Declined transactions cannot be cancelled, paused, resumed or refunded, and no payout, clawback or
reverse payout is created for them, so `declined` should be treated as a terminal state and
`TransactionDeclined` is the event to subscribe to for it. Delay rules also mean that a transaction
may settle later than it otherwise would.

### Highlights:
- New `declined` transaction status, with `declined_reason` and `declined_at` included in transaction responses and webhook payloads
- New `TransactionDeclined` webhook event, sent when a rule declines a transaction
- Declines happen before the transaction is added to the processing queue; the API response and webhook carry a standard decline message, and the detailed reason is kept internally
- Declined transactions cannot be cancelled, paused, resumed or refunded; those requests return HTTP 403 with a decline-specific error message
- No payout, clawback or reverse payout is created for a declined transaction
- Fraud-related returns place the affected payer or payee on hold and send a `PersonStatusChanged` webhook event
- GrailPay can configure additional rules for an individual vendor that add delays or decline transactions
- Rules run either at transaction creation or asynchronously after the transaction is queued

## 2026.3.19.1

### What's new:
GrailPay now supports standalone KYC verification for persons, independent of any merchant or
business onboarding flow. A new API allows clients to verify individuals directly, with support
for both GrailPay-managed and externally provided verification.

### Why it matters:
Previously, KYC verification was only available as part of the merchant onboarding process. With
standalone Person KYC, clients who need to verify individuals outside of a business context—or
ahead of onboarding—can now do so through a dedicated API. This provides greater flexibility in
how and when identity verification is performed while maintaining consistent compliance tracking.

### Highlights:
- New API endpoint for verifying persons independently, without requiring a merchant or business association
- Supports two verification methods: GrailPay-managed verification (via OneFootprint) or externally verified data provided by clients or partners
- Intelligent duplicate detection using identity details such as TIN and personal information
- KYC results are automatically shared with the Identity service for connected users
- Compliance status updates are processed consistently, ensuring accurate tracking and reliable notifications with no disruption to existing integrations

## 2026.3.18.1

### What's new:
GrailPay has made significant improvements to how payments are created and processed. The system
now responds faster, handles errors more gracefully, and provides greater visibility into payment
status—all without impacting the experience for end users or merchants.

### Why it matters:
Payment processing reliability is the foundation of any payments platform. These improvements
ensure that payments move through the system more predictably, recover automatically from
temporary failures, and provide clear audit trails for operations and support teams. For
integration partners, faster API responses and better error messaging mean a smoother
development experience.

### Highlights:
- Payment creation now returns an immediate response—processing is handled asynchronously in the background for a noticeably faster experience
- Payments follow a clearer lifecycle: created → queued → processed, making it easier to track status at any point
- Failed processing attempts are automatically retried in the next available window, with each attempt logged with a reason and timestamp
- Processing limits are checked before submission—payments wait for the next window rather than failing outright
- Stronger upfront validation ensures payer and payee are valid, active, compliant, and have the correct bank accounts before a payment is created
- Cancelled or paused payments are handled correctly in the queue—cancelled payments will not proceed, and resumed payments pick up where they left off without duplicates
- Updated API documentation with a full list of possible error messages and their meanings
- Improved system logging and monitoring to reduce edge-case issues in production

## 2026.3.17.1

### What's new:
This release resolves an issue that prevented clients from subscribing to the `NocProcessed`
webhook event.

### Why it matters:
The `NocProcessed` event is essential for receiving real-time notifications when a Notification
of Change (NOC) has been processed. This fix ensures that the event can be successfully registered
during webhook setup.

### Highlights:
- Fixed an issue where the `NocProcessed` webhook event was rejected as invalid during registration despite being a
supported event type

## 2026.2.20.1

### What's new:
GrailPay now supports onboarding Beneficial Owners using an Individual Tax Identification Number
(ITIN) in place of a traditional Social Security Number (SSN).

### Why it matters:
Not all beneficial owners have a Social Security Number. By accepting ITINs, GrailPay enables a
broader range of legitimate business owners to complete onboarding and pass KYC verification—
expanding access to the platform while maintaining compliance standards.

### Highlights:
- Beneficial Owners can now be onboarded using an ITIN (tax IDs in the 900–999 range)
- ITIN values are validated against IRS formatting rules, with clear error messaging for invalid entries
- Updated SSN validation messaging to accurately reflect accepted formats

## 2026.2.11.1

### What's new:
Phase 2 of the KYB Compliance Refactor and Beneficial Owner Migration is now complete. Merchant
compliance is no longer stored as a static flag—it is now dynamically computed based on the latest
KYB result from verification providers and the KYC results of all associated Beneficial Owners.
A new `compliance_status` object and `ComplianceStatusChanged` webhook event have been introduced
to give you full visibility into a Merchant's compliance posture.

### Why it matters:
With compliance status now computed in real time, approval decisions always reflect the most current
verification data. This eliminates the risk of stale or outdated compliance states and ensures that
only Merchants with approved KYB and fully verified Beneficial Owners can transact. The new
`compliance_status` object consolidates KYB and KYC information into a single view, and the
`ComplianceStatusChanged` webhook keeps you informed the moment anything changes.

### Highlights:
- Merchant compliance is now dynamically computed—a Merchant is approved only when KYB status is `approved` and all Beneficial Owners have approved KYC statuses
- Merchants processed by third parties are recorded with a status of `approved_externally`
- New `compliance_status` object added to V3 API Merchant responses and webhook payloads, showing the latest KYB status and KYC status of each Beneficial Owner
- New `ComplianceStatusChanged` webhook event fires whenever KYB or KYC status changes — **all clients must subscribe to this event**
- Updates to Merchant or Beneficial Owner data automatically retrigger compliance checks
- All legacy compliance logic and deprecated approval handling have been removed

## 2026.1.30.3

### What's new:
GrailPay now provides full merchant status management and compliance enforcement, giving you
direct control over merchant activation and ensuring only active, compliant merchants can
process transactions.

### Why it matters:
Managing merchant eligibility is essential for reducing risk and maintaining regulatory compliance.
With dedicated activation and deactivation endpoints—combined with automatic compliance
validation—you can confidently control which merchants are allowed to transact, with full
transparency into status changes and block reasons.

### Highlights:
- New Activate and Deactivate Merchant API endpoints with optional deactivation reason support
- Merchants have a clear `active` / `inactive` status, with deactivation reasons and timestamps recorded
- Compliance enforcement ensures only merchants with an approved compliance status can process transactions
- Transactions are blocked with clear error responses when a merchant is inactive or non-compliant
- Both conditions—active status and approved compliance—must be met before a transaction is allowed

## 2026.1.28.2

### What's new:
This release improves error messaging when attempting to delete a bank account that is not yet
eligible for deletion.

### Why it matters:
Clear and actionable error messages help you understand why a request was rejected and what
conditions must be met before proceeding—reducing confusion and support overhead.

### Highlights:
- Improved error messaging for bank account deletion requests when the account is not yet eligible for removal

## 20261.16.2

### What's new:
Clawback APIs are now available in GrailPay V3, providing programmatic access to view and track
clawbacks alongside your other financial resources.

### Why it matters:
Clawbacks are a critical part of payment operations, and until now lacked dedicated API support in V3.
With these new endpoints, you can retrieve and monitor clawbacks with the same consistency and
reliability you expect from the rest of the GrailPay API—streamlining reconciliation and reporting.

### Highlights:
- New V3 Clawback API endpoints for viewing and tracking clawbacks
- Consistent resource structure aligned with other V3 financial APIs
- Enables programmatic access for improved reconciliation and reporting workflows

## 20261.13.3

### What's new:
The V3 Account Validation API now supports multiple versions of Account Intelligence, giving you
the flexibility to choose between V1, V2, or V3 intelligence models when validating bank accounts
and routing numbers.

### Why it matters:
Each version of Account Intelligence offers different levels of insight and decisioning capability.
With version selection, you can adopt newer models at your own pace—leveraging enhanced risk signals
and validation accuracy when you're ready, while maintaining compatibility with existing integrations.

### Highlights:
- V3 Account Validation endpoint now accepts a version parameter for Account Intelligence
- Choose between V1, V2, or V3 intelligence models per request
- Newer model versions provide enhanced insights and improved validation accuracy
- Full backward compatibility with existing validation workflows

## 20261.2.1

### What's new:
GrailPay now automatically falls back from FedNow to Fast ACH (same-day) when a FedNow payout fails,
ensuring funds are still delivered without delay.

### Why it matters:
FedNow payouts can occasionally fail due to network issues or recipient bank limitations. Rather than
requiring manual intervention or leaving a payout in a failed state, the platform now automatically
retries via Fast ACH—keeping your payment operations running smoothly and your vendors paid on time.

### Highlights:
- Automatic failover from FedNow to Fast ACH (same-day) for failed individual payouts
- Ensures uninterrupted fund delivery without manual intervention
- Failover is seamless and requires no action on your end

## 2025.12.31.2

### What's new:
The Bank Link flow has been enhanced to ensure reliable OAuth redirection for mobile applications.

### Why it matters:
During bank linking, users are redirected to their bank's OAuth flow to authorize account access.
Previously, mobile applications could experience session loss after completing OAuth, interrupting
the linking process. This fix ensures a seamless return to the Bank Link flow after authorization.

### Highlights:
- Improved OAuth redirect handling for mobile Bank Link sessions
- Prevents session loss after OAuth completion, allowing the bank linking process to continue without interruption

## 2025.12.22.1

### What's new:
Processor payouts exceeding $1,000,000 are now automatically split into multiple smaller payouts to
ensure successful processing without hitting banking or partner-imposed limits.

### Why it matters:
Large processor payouts can fail or be rejected when they exceed thresholds set by banking partners.
Automatic splitting removes this risk, ensuring high-value payouts process reliably without requiring
manual intervention.

### Highlights:
- Processor payouts exceeding $1M are automatically divided into multiple payouts, each below the threshold
- Applies to both ACH and FedNow processor payouts
- Processing is seamless with no action required on your end

## 2025.12.19.2

### What's new:
This release includes an update to the Swagger API documentation security schema.

### Why it matters:
Keeping our OpenAPI specification compliant with validation standards ensures a consistent and
warning-free experience when testing authenticated endpoints through the Swagger UI.

### Highlights:
- Updated the Swagger security schema naming to comply with OpenAPI validation rules, eliminating documentation warnings

## 2025.12.19.1

### What's new:
GrailPay now supports FedNow for processor payouts, along with new webhook events and a standardized
modality response object to give you full visibility into how processor-level payouts are processed.

### Why it matters:
Processor payouts can involve high volumes of batched transactions, making transparency into their
status and payment rail critical. These additions enable real-time tracking of processor payout
lifecycles and provide clear insight into whether funds were sent via ACH or FedNow—improving
reconciliation and confidence in your payout operations.

### Highlights:
- FedNow is now supported as a payment rail for processor payouts
- New webhook events for processor payout lifecycle tracking:
- `ProcessorPayoutCreated`
- `ProcessorPayoutCompleted`
- `ProcessorPayoutFailed`
- A `modality` object is now included in batch payout responses, indicating the payment rail (ACH or FedNow) and processing speed
- Historical payout records have been backfilled with modality data for full consistency

## 2025.12.10.2

### What's new:
This release resolves issues with our Swagger API documentation that were causing validation failures.

### Why it matters:
Accurate and reliable API documentation is essential for a smooth integration experience. These fixes
ensure the Swagger UI remains a dependable reference for building against the GrailPay API.

### Highlights:
- Resolved OpenAPI specification issues that were causing Swagger validation failures in production
- API documentation now passes all validation checks, ensuring accuracy for developers and integrators using the Swagger UI

## 2025.12.2.1

### What's new:
This release includes fixes to improve the developer experience when working with the GrailPay API.

### Why it matters:
These updates reduce friction when testing API endpoints and submitting data, helping you integrate
more quickly and avoid common validation errors.

### Highlights:
- Fixed an issue where Swagger UI was not correctly passing the `Authorization: Bearer` header on authenticated requests — tokens entered in the Authorize section now work as expected
- Improved phone number validation messaging to clearly indicate that values must contain exactly 10 digits without the `+1` prefix or special characters

## 2025.11.19.1

### What's new:
GrailPay now supports FedNow payouts, enabling instant, around-the-clock payout processing for eligible
transactions. Clients approved for FedNow will automatically receive payouts via the FedNow network once their
associated transaction debits have settled.

### Why it matters:
Traditional ACH payouts are limited to banking hours and standard processing windows. With FedNow support,
your vendors can receive funds in real time—24 hours a day, 7 days a week—reducing settlement delays and
improving cash flow for your payment operations.

### Highlights:
- Instant payouts via the FedNow network for enabled vendors
- True 24/7 payout processing with no dependency on banking hours
- Automatic routing ensures FedNow-eligible transactions are processed separately from standard ACH payouts

## 2025.11.17.1

### What’s new:
We’ve introduced three new `Person` statuses and a new webhook event to improve visibility into why a person may
be placed on hold.

### Why it matters:
These additions provide clearer insight into hold reasons—whether related to sanctions or suspected fraud—so you can
take appropriate action and maintain compliance. The new webhook event ensures real-time notification when a person’s
status changes.

### Highlights:
- New person statuses:
- `ON_HOLD_SANCTIONS`
- `ON_HOLD_FRAUD_PAYER`
- `ON_HOLD_FRAUD_PAYEE`
- New `PersonStatusChanged` webhook event triggers whenever a person enters or exits one of these statuses
- Enhances transparency and traceability for risk-related holds

## 2025.11.14.1

### What’s new:
We’ve added full transaction lifecycle management to the GrailPay API with three new V3 endpoints: **Pause**,
**Resume**, and **Cancel**.

### Why it matters:
These new controls give vendors and processors more flexibility and control over transaction processing. Whether
halting a transaction for compliance review or canceling a transfer in progress, this release adds powerful
capabilities with complete auditability and real-time notifications.

Please view our updated [Manage Transactions](/docs/technical/transactions/manage-transactions) guide for full details on using
these new endpoints and understanding their behavior.

### Highlights:
- **New V3 endpoints** for pausing, resuming, and canceling transactions
- **New transaction statuses**: `PAUSED` and `AWAITING_CANCELLATION`, with full timestamp tracking
    - **Pause** halts the ACH processing for a transaction in progress
    - **Resume** re-initiates ACH or syncs with bank state depending on prior progress
    - **Cancel** either halts the transaction immediately or initiates a reverse payout if debit has been settled
- **Three new webhook events**: `TransactionPaused`, `TransactionResumed`, and `TransactionAwaitingCancellation`

## 2025.11.10.1

### What’s new:
We’ve fixed an issue where the `MerchantUpdated` webhook event was not being triggered when a merchant transitioned
to the `IN_REVIEW` state.

### Why it matters:
Merchants moving into review—either due to failed KYC or updates from Middesk—will now properly emit webhook
notifications. This ensures platforms receive real-time updates and can accurately reflect onboarding status in
their workflows.

### Highlights:
- Fixed bug preventing `MerchantUpdated` webhook from triggering on `IN_REVIEW` transitions
- Webhooks now trigger on KYC failure when KYB status moves to `IN_REVIEW`
- Middesk-originated `IN_REVIEW` changes also emit update notifications

## 2025.10.30

### What’s new
No new features were released in this update.

### Why it matters
We’ve made backend improvements to ensure data integrity and consistency across V3 listing endpoints, especially
when handling relational data like linked bank accounts.

### Highlights
- Fixed binding issues between collection objects and resource transformers
- Ensured relational data (e.g., bank accounts) is preserved during transformation
- Added safeguards to prevent data loss during response transformation

## 2025.10.28

### What’s new
We’ve made several enhancements to the V3 API, including unified bank account data across key endpoints and a new
onboarding flow for adding bank accounts to persons.

### Why it matters
These updates give you greater visibility into linked bank accounts, improve onboarding flexibility, and enable
support for additional payment rails like FedNow. You can now onboard and validate accounts via Plaid or manually—all
with consistent structure and improved intelligence.

### Highlights
- **Unified Bank Account Objects:** Bank account details are now included in all V3 listing and detail API responses for
People, Merchants, and Businesses.
- **New V3 Bank Account Onboarding Endpoint:** New v3 API endpoint for adding bank accounts with account intelligence of various versions.  This includes:
    - Support for both Plaid-based and manual bank account onboarding
    - Comprehensive account validation including account holder name verification
    - Duplicate detection for manual accounts
- **Cleaner Timestamp Responses:** Removed unused updated_at fields for a more streamlined response format.

## 2025.10.22

### What’s new:
We’ve added a new status field to all Person-related V3 API responses, including List, Fetch, Onboard, and Update,
as well as the PersonCreated and PersonUpdated webhook event payloads.

### Why it matters:
You can now immediately see the current status of any user in your system. This makes it easier to confirm that a
person is in a valid state to transact before initiating a transfer, helping reduce failed attempts and streamline your integration logic.

### Highlights:
- New status parameter added to V3 API responses for People (List, Fetch, Onboard, Update)
- Included in webhook payloads for both person creation and updates
- Improves visibility into user state and transactional readiness across the platform

## 2025.10.15

### What’s new:
We’ve added a new `kyb_rejected_reason` field to both the Merchant Create and Merchant Update API responses, as
well as the corresponding MerchantCreated and MerchantUpdated webhook event payloads.

### Why it matters:
You can now see the specific reason a merchant’s KYB (Know Your Business) verification failed. This provides greater
transparency and helps streamline your onboarding and support workflows.

#### Highlights:
- New `kyb_rejected_reason` parameter added to API responses ( Onboard, Update, List, Fetch )
- Included in webhook payloads for both merchant creation and updates
- Ensures consistent, actionable KYB feedback across the API and webhooks

## 2025.10.10

### Maintenance Items
- **OpenAPI Documentation Updates:** Fixed an issue with the Webhook Registration OpenAPI documentation to specify
that the `webhook_url` field should be passed as an array to allow for multiple webhook URLs.

## 2025.10.7

### Release Features
- **Optimized Business & Merchant Response Payloads:**
    - Responses: Removed full Person objects from create and update responses
    - Relations Object: Responses now include a clean relations object containing only the Person UUID
- **OpenAPI Documentation Updates:** Updated OpenAPI documentation for Business and Merchant onboarding and update endpoints
to reflect the new relational data structure.

### Maintenance Items
- **Vendor Object in Relations:** Resolved an issue where the vendor object was incorrectly appearing in List
Person and List Merchant API responses. The relations attribute now correctly returns only allowed UUID references,
ensuring consistency across all V3 endpoints.

## 2025.10.6

### Release Features
- **V3 API Response Standardization:** All V3 APIs of List and Showing (Person, Business, and Merchant) now follow a
unified response contract with consistent structure. Error responses are now standardized across all endpoints,
providing clearer, more consumer-friendly messages with proper attribute naming in validation errors.
- **Enhanced Relational Data:** We've introduced a new relations object across all V3 endpoints, making it easier to
understand entity relationships:
    - Person responses now include related Business or Merchant UUIDs.
    - Business responses include the associated Person UUID.
    - Merchant responses include the associated Person UUID.
- **Webhook Enhancements:** Updated Person and Merchant webhook responses to include the new relations object structure,
providing cleaner, more relevant information for integrations.

### Maintenance Items
- **Billing Improvements:** Fixed filter inconsistencies in Billing Item and Summary endpoints, ensuring accurate and
reliable query results across both endpoints with consistent behavior.