Wire Transfers
This page covers wires you receive into an account. For the manual wire transfer review flow, see Wire Transfers (Manual Funding).
Overview
A wire transfer moves funds from an external bank account into a Highnote FinancialAccount. Highnote calls a wire that arrives from outside the platform non-originated.
You make no call. A wire addressed to one of your account numbers lands on that account when Highnote receives it from the bank. You find it through the NON_ORIGINATED_WIRE_TRANSFER_* notifications, financial events, or search, and you can read it by ID.
| Non-originated | |
|---|---|
__typename | NonOriginatedWireTransfer |
| ID prefix | wttxn_v26nt |
| Event type / prefix | NonOriginatedWireTransferEvent / wt_v26nt |
type | PUSH |
sign | POSITIVE (funds enter the account) |
Your FinancialAccount is on | destination |
NonOriginatedWireTransfer implements the WireFundsTransfer interface, which holds the fields common to wires.
Receive a wire
The first notification you get for a received wire is NON_ORIGINATED_WIRE_TRANSFER_RECEIVED_EVENT.
If a wire's account number does not match an active Highnote account, the wire is not credited. Highnote records it as FAILED and sends you no notification.
In the Test environment, use simulateNonOriginatedWireTransfer to receive a wire:
{
"input": {
"idempotencyKey": "<UUID_v4>",
"amount": { "value": 100000, "currencyCode": "USD" },
"creditor": { "financialAccountId": "<FINANCIAL_ACCOUNT_ID>" },
"debtor": {
"name": "<SENDER_NAME>",
"accountNumber": "<ACCOUNT_NUMBER>",
"routingNumber": "<ROUTING_NUMBER>"
},
"wireInstruction": {
"beneficiaryReference": "INV-0123456789",
"originatorToBeneficiaryInformation": {
"lines": ["Invoice 0123456789", "For further credit to account 4521"]
}
}
}
}
wireInstruction is optional. It carries what the sender put on the wire:
beneficiaryReferenceholds up to 16 characters in the simulator.originatorToBeneficiaryInformationis the message for the beneficiary. Send exactly one oftextorlines.textholds up to 140 characters. Line breaks and repeated spaces become one space. Highnote wraps it at spaces into up to 4 lines of 35 characters.linesholds up to 4 lines of up to 35 characters each. A line cannot contain a line break.
- A request that breaks one of these limits is rejected, not cut. The request fails if
textis blank, needs more than 4 lines, or has a word longer than 35 characters.
A simulated wire reads back with paymentRelatedInformation set to TEST. The simulator puts originatorToBeneficiaryInformation in capital letters, so it reads back as, for example, INVOICE 0123456789. The call fails with CREDITOR_DDA_NOT_FOUND if the financial account has no account number.
Lifecycle, notifications, and ledger
Each row is a status of the wire. The notification column shows the event you receive. The ledger column shows the entries posted to your FinancialAccount at that status.
| Status | Notification | Ledger entries |
|---|---|---|
RECEIVED | NON_ORIGINATED_WIRE_TRANSFER_RECEIVED_EVENT | none |
COMPLETED | NON_ORIGINATED_WIRE_TRANSFER_COMPLETED_EVENT | DEBIT CASH / CREDIT FUND_IN_HOLD / DEBIT FUND_IN_HOLD / CREDIT AVAILABLE_CASH, in one journal entry. Cash and available balance both increase. |
FAILED | NON_ORIGINATED_WIRE_TRANSFER_FAILED_EVENT | none |
A received wire has one ledger step because wire funds are final when received. Nothing is held while the wire is in progress.
Every notification for a wire uses the same payload. The event node contains the wire:
{
"data": {
"node": {
"__typename": "NotificationEvent",
"id": "<NOTIFICATION_EVENT_ID>",
"name": "NON_ORIGINATED_WIRE_TRANSFER_COMPLETED_EVENT",
"createdAt": "2026-10-08T15:47:03.583Z",
"node": {
"__typename": "NonOriginatedWireTransferEvent",
"id": "wt_v26nt<ID>",
"createdAt": "2026-10-08T15:47:03.047Z",
"status": "COMPLETED",
"failureReason": null,
"wireTransfer": {
"__typename": "NonOriginatedWireTransfer",
"id": "wttxn_v26nt<ID>",
"createdAt": "2026-10-08T15:46:55.779Z",
"updatedAt": "2026-10-08T15:47:03.047Z",
"type": "PUSH",
"sign": "POSITIVE",
"status": "COMPLETED",
"failureReason": null,
"amount": {
"__typename": "Amount",
"value": 1095,
"currencyCode": "USD",
"decimalPlaces": 2
},
"financialAccount": { "id": "ac_<ID>" },
"source": {
"node": {
"__typename": "USBankAccount",
"last4": "6789",
"routingNumber": null,
"accountType": null
},
"amount": {
"__typename": "Amount",
"value": 1095,
"currencyCode": "USD",
"decimalPlaces": 2
}
},
"destination": {
"node": { "__typename": "FinancialAccount", "id": "ac_<ID>" },
"amount": {
"__typename": "Amount",
"value": 1095,
"currencyCode": "USD",
"decimalPlaces": 2
}
},
"bankTransferDetails": {
"__typename": "WireTransferBankTransferDetails",
"paymentRelatedInformation": null,
"originatorToBeneficiaryInformation": {
"__typename": "WireOriginatorToBeneficiaryInformation",
"text": "INVOICE 0123456789 PAYROLL OCTOBER",
"lines": ["INVOICE 0123456789 PAYROLL OCTOBER"]
},
"references": {
"__typename": "WireTransferReferences",
"beneficiaryReference": "INV-0123456789",
"senderReference": "<SENDER_REFERENCE>",
"inputMessageAccountabilityData": "<IMAD>",
"outputMessageAccountabilityData": "<OMAD>"
}
}
}
},
"expiresAt": "2026-11-07T15:47:03.583Z"
}
},
"extensions": {
"signatureTimestamp": 1791474423583
}
}
Read a wire by ID
node(id:) gets the wire type from the ID prefix (see Overview). An event ID returns the event, and the wire is on its wireTransfer field.
query Wire($id: ID!) {
node(id: $id) {
... on WireFundsTransfer {
__typename
id
failureReason
amount {
value
currencyCode
}
financialAccount {
id
}
bankTransferDetails {
paymentRelatedInformation
originatorToBeneficiaryInformation {
lines
text
}
references {
beneficiaryReference
senderReference
inputMessageAccountabilityData
outputMessageAccountabilityData
}
}
}
... on NonOriginatedWireTransfer {
status
events {
id
createdAt
status
failureReason
}
}
... on NonOriginatedWireTransferEvent {
id
createdAt
status
failureReason
wireTransfer {
__typename
id
status
amount {
value
currencyCode
}
financialAccount {
id
}
}
}
}
}
statusisRECEIVED,COMPLETED, orFAILED, on both the wire and its events.eventsis a plain list. An empty list means no events have occurred, not an error.failureReasonis aWireTransferFailureReason. A received wire fails with one of seven values:INSUFFICIENT_FUNDS,ACCOUNT_NOT_FOUND,ACCOUNT_CLOSED,ACCOUNT_NOT_ACTIVE,CURRENCY_MISMATCH,TRANSFER_NOT_PERMITTED, orUNSPECIFIED.UNSPECIFIEDis returned when Highnote can't classify the failure. See Wire failure reasons for what each means.bankTransferDetailsshows what went on the wire, as the bank recorded it. For a wire you received, it is the sender's instruction.
| Field | What it holds |
|---|---|
paymentRelatedInformation | The payment purpose, kept at the source bank. Usually null on a wire you received. |
originatorToBeneficiaryInformation.lines | The sender's message as up to 4 lines, in their positions. An empty line between two others is kept as "". The bank can merge the sender's lines into one. |
originatorToBeneficiaryInformation.text | The same message as one line. Line breaks and repeated spaces become one space. originatorToBeneficiaryInformation is null when the wire carried no message. |
references.beneficiaryReference | The reference for you to match the payment, such as an invoice number. null when the wire carried no reference. |
references.senderReference | The reference the source bank assigned. |
references.inputMessageAccountabilityData | IMAD, the ID the wire network assigned when the wire was sent. |
references.outputMessageAccountabilityData | OMAD, the ID the wire network assigned when the wire was delivered. |
references is normally present, because every wire has wire network identifiers.
An example bankTransferDetails response:
{
"bankTransferDetails": {
"paymentRelatedInformation": null,
"originatorToBeneficiaryInformation": {
"lines": ["INVOICE 0123456789 PAYROLL OCTOBER"],
"text": "INVOICE 0123456789 PAYROLL OCTOBER"
},
"references": {
"beneficiaryReference": "INV-0123456789",
"senderReference": "<SENDER_REFERENCE>",
"inputMessageAccountabilityData": "<IMAD>",
"outputMessageAccountabilityData": "<OMAD>"
}
}
}
Search
Search wires with searchTransactions on Organization. Set type=wireTransfer in the query.
Results include both wires and wire events. Add transactionSearchType=transaction to return wires only, or transactionSearchType=event to return events only.
The type=wireTransfer results can also include WireTransfer items from the manual funding flow — see Wire Transfers (Manual Funding). Use __typename to tell them apart. The status on WireTransfer is a different enum, so give it an alias if you select it too.
query SearchWires($id: ID!, $filterBy: TransactionSearchFilterInput!) {
node(id: $id) {
... on Organization {
searchTransactions(first: 20, filterBy: $filterBy) {
... on TransactionSearchResultConnection {
edges {
node {
status
transactionSearchType
transactionSearchObjectType
amount {
value
currencyCode
}
source {
__typename
... on NonOriginatedWireTransfer {
id
status
}
... on NonOriginatedWireTransferEvent {
id
status
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
... on UserError {
errors {
code
description
}
}
... on AccessDeniedError {
message
}
}
}
}
}
{
"id": "<ORGANIZATION_ID>",
"filterBy": {
"searchQueryLanguage": {
"query": "type=wireTransfer AND transactionSearchType=transaction AND accountId=<FINANCIAL_ACCOUNT_ID>",
"version": "VERSION_1"
}
}
}
Each result has transactionSearchObjectType: WIRE_TRANSFER. The search status of a wire is:
PENDINGwhile the wire isRECEIVED.COMPLETEDwhen the wire isCOMPLETED.FAILEDwhen the wire isFAILED.
The status on the wire itself is more detailed. A new status can take a short time to appear in search.
Searching for a wire ID returns one TRANSACTION result. Each revision of a wire event is its own search row with its own status, not the wire's current status. The booking row is written COMPLETED, so a wire that later fails shows a COMPLETED result next to the FAILED one. Searching for a wire event ID can therefore return more than one result.
Ledger entries
Ledger entries for a wire link back to the wire event through financialEvent, which returns a NonOriginatedWireTransferEvent. To read them, use ledgers on the wire itself or on the FinancialAccount:
query WireLedgers($id: ID!) {
node(id: $id) {
... on WireFundsTransfer {
ledgers(ledgerNames: [AVAILABLE_CASH, CASH]) {
name
ledgerEntries {
edges {
node {
__typename
amount {
value
currencyCode
}
createdAt
financialEvent {
__typename
... on NonOriginatedWireTransferEvent {
id
status
}
}
}
}
}
}
}
}
}
Related guides
- Wire Transfers (Manual Funding) for the manual wire transfer review flow.
- Transfer Failure Reasons for what each wire failure reason means.