Skip to content

Tracking a Payment

"What is the status of this payment?" and "Can I get proof of payment?" are the two questions every payments program fields most often from end users. This guide answers both from the API, for every rail: checking a Transaction's state, finding a Transaction by its network trace identifier, and retrieving the audit history and underlying files that serve as proof of payment.

The Transaction state machine itself (states, meanings, allowed transitions) is defined once, for every rail, in Transactions → Lifecycle. This guide does not restate it; keep that page open alongside this one.

Prerequisites

The code snippets provided in this guide require the following variables:

  • BASE_API_URL - The target GIB API domain, which can be found in the API-Reference.
  • API_KEY - The API key setup by the client for using the API. Can be generated using the Dashboard.
  • TRANSACTION_ID - The ID of the Transaction you want to track, returned when the Transaction was created.
import requests

headers = {
    "Content-type": "application/json",
    "Authorization": f"{API_KEY}"
}

For one-off manual checks, the dashboard exposes the same Transaction data; this guide focuses on the API.

Step 1 - Check the Status

If you have Webhooks configured, status comes to you: every state transition is delivered as a {direction}_{type}_transaction_{state} event (for example outbound_ach_transaction_posted). Webhooks are the primary mechanism for keeping your platform in sync with GIB's view of the world; polling is the fallback for spot checks and backfills.

To poll, call getTransactions and read the state field:

url = f"{BASE_API_URL}/transaction"

params = {"id": TRANSACTION_ID}

response = requests.request("GET", url, params=params, headers=headers)

response.raise_for_status()

transaction = response.json()["items"][0]

print(transaction["state"])

getTransactions also filters by state, type, date and amount ranges, reference, batch_external_key, the trace references covered in the next section, and more; see the operation's parameter list for the full set.

Three rail-specific points resolve most "the state says X but the user says Y" questions:

  • posted on an international wire confirms GIB's outbound, not the beneficiary credit. The SWIFT path to the destination bank can take additional time. See International Wire → Lifecycle.
  • A posted ACH entry can still come back. Returns arrive as separate inbound Transactions. If the original Transaction was returned, its return_transaction_id field is set. See Returns and ACH → Returns.
  • under_review means manual review by GIB's operations team. You receive a webhook when a Transaction enters review and another when the review resolves. See Transactions → About under_review for typical triggers and how to present the state to end users.

Step 2 - Find a Payment by Its Trace Identifier

Trace identifiers are the rail-level references other parties quote: an end user's receiving bank quotes an ACH trace number; a beneficiary or correspondent bank quotes an IMAD or UETR. Every Transaction carries up to three trace fields, each a unique identifier within the rail (see Transactions → Fields):

  • trace_reference: the entry's identifier on the rail
  • trace_reference_final: the reference from the processed/confirmation file (for example, the confirmation IMAD for wires)
  • trace_reference_original: on returns, the trace of the original Transaction; it matches the original's trace_reference or trace_reference_final

What trace_reference contains depends on the rail:

Rail (type) trace_reference contents
ach The ACH trace number (NACHA traceNumber)
wire (legacy / Fedwire) The IMAD (inputMessageAccountabilityData), or IMAD;UETR (after July 2025)
wire20022 The IMAD and the UETR combined as {imad};{uetr}
icl The check's eceInstitutionItemSequenceNumber
book Not applicable. BOOK transfers settle on GIB's internal ledger and never touch an external network; identify them by Transaction id, reference, or batch_external_key

ACH trace numbers

For Transactions created through createTransaction, the generated trace references are also returned immediately in the X-Generated-Transaction-Trace-References response header as comma-separated {transfer_key}={traceNumber} pairs. For an ACH return, trace_reference_original holds the original entry's trace (originalTrace), which is how you match a return back to the payment it reverses.

Wire IMAD and UETR

The IMAD appears in trace_reference once the Fed confirms the wire (see Domestic Wire → Notifications). For ISO 20022 wires, trace_reference carries both the IMAD (FIToFICstmrCdtTrf.GrpHdr.MsgId) and the UETR (PmtId.UETR), separated by a semicolon.

The UETR (Unique End-to-End Transaction Reference) survives every SWIFT routing hop. If an international wire is delayed or appears stuck, take the UETR from trace_reference (the part after the semicolon) and send it to info@gibank.com; GIB can trace the wire's path through the network. There is no public trace endpoint. See International Wire → Tracing.

Searching by trace reference

All three trace fields are query parameters on getTransactions, so a reference quoted by a counterparty resolves directly to the Transaction it belongs to:

url = f"{BASE_API_URL}/transaction"

params = {"trace_reference": "124782618117"}

response = requests.request("GET", url, params=params, headers=headers)

response.raise_for_status()

To find the return for a known original entry, query trace_reference_original with the original's trace reference.

Step 3 - Retrieve the Audit History

getTransactionHistory returns the actions that were logged for a Transaction: what happened, when, and by whom. It is the first artifact to pull when someone asks "what happened to this payment".

url = f"{BASE_API_URL}/transaction/{TRANSACTION_ID}/history"

response = requests.request("GET", url, headers=headers)

response.raise_for_status()

The response is paginated with limit and offset (see Pagination). Each entry looks like:

{
  "action": "create",
  "create_user_id": 1,
  "create_user_full_name": "Max Mustermann",
  "create_date_time": "2024-02-04T23:00:00.000Z",
  "level": "info",
  "data": "User source: accounts"
}
  • action: create or update
  • create_date_time: when it happened (UTC)
  • create_user_id / create_user_full_name: who acted
  • level: debug or info
  • data: additional details for the entry

Step 4 - Retrieve the Underlying Files

getTransactionFiles returns download URLs for the raw file and the parsed data used to create the Transaction, plus the processed file content where available. Combined with the Transaction record itself (state, posted_date, trace references), this is the proof-of-payment package the API produces.

url = f"{BASE_API_URL}/transaction/{TRANSACTION_ID}/files"

response = requests.request("GET", url, headers=headers)

response.raise_for_status()

files = response.json()

The response can contain up to six entries; each is nullable and carries a url plus a url_malware_protection_status:

Key Content
raw The raw file used to create the Transaction
parsed The parsed data used to create the Transaction
raw_virtual, parsed_virtual The raw and parsed content in the virtual account variant
processed_raw, processed_parsed The processed file content; for wires this is the confirmation file whose IMAD lands in trace_reference_final

Check url_malware_protection_status (for example no_threats_found or threats_found) before passing a downloaded file onward.

Step 5 - Export in Bulk

For evidence covering many Transactions at once (a statement period, a batch, a list of IDs), use exportTransactions. It accepts the same filters as getTransactions plus an export_type, and returns a URL to the generated file (a ZIP if the export results in multiple files):

export_type Content
csv, json Transaction metadata (no transaction files)
raw_files Raw transaction files as stored, one per transaction
parsed_files Parsed transaction files (JSON representation).
raw_virtual_files, parsed_virtual_files Files with virtual account numbers substituted. VA ACH transactions only
images Check images extracted from the parsed file. ICL only
iso20022, iso20022_merged ISO 20022 XML, one file per WIRE transaction, or merged into a single envelope
raw_merged Raw files for all selected ACH/BOOK transactions merged into a single file
url = f"{BASE_API_URL}/transaction/export"

params = {
    "export_type": "csv",
    "posted_date_from": "2026-06-01",
    "posted_date_to": "2026-06-08",
}

response = requests.request("GET", url, params=params, headers=headers)

response.raise_for_status()

download_url = response.json()["url"]

Check the X-Export-Warnings response header for any warnings raised during the export.

When to Contact GIB

Most status and proof-of-payment questions are answerable from the endpoints above. Contact GIB when:

Situation Contact
A Transaction is under_review and a user-facing situation requires escalation operations@gibank.com with the Transaction ID
An international wire is delayed or appears stuck info@gibank.com with the UETR
Production incidents operations@gibank.com
Implementation and integration questions operations@gibank.com

Resources

For more information on the endpoints used in this guide, see these API docs:

Related concepts: Transactions, Webhooks, Returns, Reconciliation.