Draft API (v0.3.0-draft) — The transaction ledger surface is currently in draft. Schemas and behavior may change before the stable release.

What Is the Transaction Ledger?

The transaction ledger is a read-only record of every balance-affecting event on your OpenFX accounts. Every payment, conversion, transfer, inbound deposit, fee, and adjustment creates one or more transaction entries. You cannot create, update, or delete transactions directly — they are generated by the system as a side effect of other operations. The ledger provides a complete, auditable trail of how every account balance changed over time.
Account (acc_)
  ├── txn_001  payment_out     debit   $1,500.00   balance: $8,500.00
  ├── txn_002  fee             debit       $2.50   balance: $8,497.50
  ├── txn_003  payment_in      credit  $5,000.00   balance: $13,497.50
  ├── txn_004  conversion_debit  debit $10,000.00  balance: $3,497.50
  └── txn_005  transfer_in     credit  $7,500.00   balance: $10,997.50

Transaction Types

Every transaction has a type that describes the operation that created it:
TypeDirectionDescription
payment_outdebitOutbound payment debited from the account
payment_increditInbound payment credited to the account
conversion_debitdebitSell side of an FX conversion
conversion_creditcreditBuy side of an FX conversion
transfer_outdebitInternal transfer sent from this account
transfer_increditInternal transfer received into this account
feedebitFee charged against the account
auto_conversion_debitdebitSell side of an automatic conversion (via settlement route)
auto_conversion_creditcreditBuy side of an automatic conversion (via settlement route)
adjustmentdebit or creditManual adjustment by OpenFX operations
reversaldebit or creditReversal of a previous transaction

Direction: Debit vs Credit

Every transaction has a direction field:
DirectionMeaningEffect on Balance
debitFunds leaving the accountDecreases balance
creditFunds entering the accountIncreases balance
The balance field on each transaction shows the running balance after that transaction was applied.

Linked Transactions

Many operations create paired entries across accounts. The linkedTransactionId and transactionGroupId fields connect related transactions.

linkedTransactionId

Links a transaction to its counterpart. For example, a reversal entry links back to the original transaction it reverses.

transactionGroupId

Groups all entries from a single operation. For example, an FX conversion creates two entries (a debit in the sell currency and a credit in the buy currency) that share the same transactionGroupId. A transfer creates a debit on the source account and a credit on the destination account with the same group ID.
FX Conversion (cnv_01953e1a5f4b7007)
  ├── txn_010  conversion_debit   $10,000.00 USD  (group: grp_abc123)
  └── txn_011  conversion_credit   EUR 9,250.00   (group: grp_abc123)

Transfer (trf_01953e1a5f4b7008)
  ├── txn_012  transfer_out       $2,500.00 USD  (group: grp_def456) — source account
  └── txn_013  transfer_in        $2,500.00 USD  (group: grp_def456) — destination account

Reference Fields

Each transaction includes a reference to the originating resource:
FieldDescription
referenceTypeThe type of resource that created this transaction: payment, inbound_payment, conversion, transfer, or refund
referenceIdThe ID of the originating resource (e.g., pmt_01953e1a5f4b7005, cnv_01953e1a5f4b7007)
These fields enable you to trace any transaction entry back to the operation that caused it.

Listing Transactions

curl -X GET "https://sandbox.api.openfx.com/v1/transactions?accountId=acc_01953e1a5f4b7002&limit=50" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

Filtering Transactions

The transactions endpoint supports several filters for narrowing results:
ParameterTypeDescription
accountIdstringFilter by account ID
customerIdstringFilter by customer ID (cross-account)
typeenumFilter by transaction type (e.g., payment_out, conversion_debit)
limitintegerPage size (default 50, max 200)
starting_afterstringCursor for forward pagination
ending_beforestringCursor for backward pagination
createdAt[gte]datetimeCreated on or after this timestamp
createdAt[lte]datetimeCreated on or before this timestamp

Filter by transaction type

curl -X GET "https://sandbox.api.openfx.com/v1/transactions?accountId=acc_01953e1a5f4b7002&type=payment_out" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

Filter by customer (cross-account)

Use the customerId filter to see transactions across all of a customer’s accounts in one query. This is useful for generating cross-account statements.
curl -X GET "https://sandbox.api.openfx.com/v1/transactions?customerId=cus_01953e1a5f4b7000&limit=100" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

Filter by date range

curl -X GET "https://sandbox.api.openfx.com/v1/transactions?accountId=acc_01953e1a5f4b7002&createdAt%5Bgte%5D=2026-02-01T00:00:00Z&createdAt%5Blte%5D=2026-02-28T23:59:59Z" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

Getting a Specific Transaction

curl -X GET https://sandbox.api.openfx.com/v1/transactions/txn_01953e1a5f4b7600 \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"
The response returns the full transaction resource:
{
  "id": "txn_01953e1a5f4b7600",
  "accountId": "acc_01953e1a5f4b7002",
  "type": "payment_out",
  "direction": "debit",
  "value": "150250",
  "currency": "USD",
  "balance": "8497.50",
  "linkedTransactionId": null,
  "transactionGroupId": "grp_01953e1a5f4b7601",
  "referenceType": "payment",
  "referenceId": "pmt_01953e1a5f4b7005",
  "description": "ACH payment to Globex Corporation",
  "createdAt": "2026-02-23T12:05:00Z"
}

Reconciliation Patterns

Daily account reconciliation

Pull all transactions for an account within a date range and verify that the running balances are consistent:
import requests

response = requests.get(
    "https://sandbox.api.openfx.com/v1/transactions",
    headers={...},
    params={
        "accountId": "acc_01953e1a5f4b7002",
        "createdAt[gte]": "2026-02-25T00:00:00Z",
        "createdAt[lte]": "2026-02-25T23:59:59Z",
        "limit": 200,
    },
)

transactions = response.json()["items"]

# Sum debits and credits for the day
total_debits = sum(
    float(t["amount"]) for t in transactions if t["direction"] == "debit"
)
total_credits = sum(
    float(t["amount"]) for t in transactions if t["direction"] == "credit"
)
net_change = total_credits - total_debits

print(f"Total debits:  {total_debits:.2f}")
print(f"Total credits: {total_credits:.2f}")
print(f"Net change:    {net_change:.2f}")

Matching paired legs

Use transactionGroupId to find all entries from a single operation:
# Find the matching credit for a conversion debit
conversion_debit = txn  # A transaction with type "conversion_debit"
group_id = conversion_debit["transactionGroupId"]

# Query for all transactions in the same group
all_transactions = requests.get(
    "https://sandbox.api.openfx.com/v1/transactions",
    headers={...},
    params={"accountId": "acc_01953e1a5f4b7002"},  # May need to check other accounts
).json()["items"]

related = [t for t in all_transactions if t["transactionGroupId"] == group_id]
for t in related:
    print(f"{t['type']}: {t['direction']} {t['amount']} {t['currency']}")

Tracing back to source operations

Use referenceType and referenceId to look up the originating resource:
txn = response.json()

if txn["referenceType"] == "payment":
    payment = requests.get(
        f"https://sandbox.api.openfx.com/v1/payments/{txn['referenceId']}",
        headers={...},
    ).json()
    print(f"Payment to: {payment['counterpartyId']}, status: {payment['status']}")
elif txn["referenceType"] == "conversion":
    conversion = requests.get(
        f"https://sandbox.api.openfx.com/v1/fx/conversions/{txn['referenceId']}",
        headers={...},
    ).json()
    print(f"Converted {conversion['sellAmount']} to {conversion['buyAmount']}")

Webhook Events

EventDescription
transaction.createdA new transaction entry has been created on an account.
The transaction.created event fires for every ledger entry. If you need real-time balance tracking, subscribe to this event rather than polling the transactions endpoint.

API Reference