Reconciliation

The Reconciliation API lets you pull transaction, chargeback, and subscription data for settlement matching, financial reporting, and audit purposes. All three endpoints support JSON, XML, and CSV output with cursor-based pagination.

Endpoints

Endpoint Date filter field Description
GET /api/v1/reconciliation/transactions/ date_processed Payment transactions
GET /api/v1/reconciliation/chargebacks/ report_date Chargebacks and disputes
GET /api/v1/reconciliation/subscriptions/ created_at Recurring billing subscriptions

All endpoints require Bearer API key authentication (rk_...).

Querying transactions

curl "https://api.catalystpay.com/api/v1/reconciliation/transactions/?start_date=2025-01-01&end_date=2025-03-31" \
  -H "Authorization: Bearer rk_your_api_key"
import requests

response = requests.get(
    "https://api.catalystpay.com/api/v1/reconciliation/transactions/",
    headers={"Authorization": "Bearer rk_your_api_key"},
    params={
        "start_date": "2025-01-01",
        "end_date": "2025-03-31",
    },
)

data = response.json()
transactions = data["results"]
next_cursor = data.get("next")  # URL for next page, or null
const params = new URLSearchParams({
  start_date: "2025-01-01",
  end_date: "2025-03-31",
});

const response = await fetch(
  `https://api.catalystpay.com/api/v1/reconciliation/transactions/?${params}`,
  { headers: { Authorization: "Bearer rk_your_api_key" } }
);

const data = await response.json();
const transactions = data.results;
const nextPage = data.next;

Query parameters

Transactions

Parameter Type Required Description
start_date YYYY-MM-DD Yes Start of date range. Filters on date_processed.
end_date YYYY-MM-DD No End of date range (max 90 days from start).
status String No Comma-separated statuses (e.g., approved,declined).
type String No Comma-separated types (e.g., sdd_sale,sdd_refund).
payment_gateway_id UUID No Filter by specific gateway.
page_size Integer No Results per page, 1-1000 (default: 100).
format String No json (default), xml, or csv.

Chargebacks

Parameter Type Required Description
start_date YYYY-MM-DD Yes Start of date range. Filters on report_date.
end_date YYYY-MM-DD No End of date range (max 90 days from start).
status String No Comma-separated statuses (e.g., charged_back).
type String No Comma-separated types (e.g., chargeback).
payment_gateway_id UUID No Filter by specific gateway.
page_size Integer No Results per page, 1-1000 (default: 100).
format String No json (default), xml, or csv.

Subscriptions

Parameter Type Required Description
start_date YYYY-MM-DD Yes Start of date range. Filters on created_at.
end_date YYYY-MM-DD No End of date range (max 90 days from start).
status String No Comma-separated statuses (e.g., ACTIVE,CANCELLED).
payment_gateway_id UUID No Filter by specific gateway.
next_billing_date_from YYYY-MM-DD No Subscriptions with next_billing_date on or after this date.
next_billing_date_to YYYY-MM-DD No Subscriptions with next_billing_date on or before this date.
page_size Integer No Results per page, 1-1000 (default: 100).
format String No json (default), xml, or csv.

Transaction and chargeback statuses use snake_case (e.g., approved, charged_back). Subscription statuses use UPPERCASE (e.g., ACTIVE, CANCELLED).

Pagination

The Reconciliation API uses cursor-based pagination for stable iteration over large datasets. Each response includes next and previous URLs:

{
  "next": "https://api.catalystpay.com/api/v1/reconciliation/transactions/?cursor=cD0yMDI1LTAz&start_date=2025-01-01",
  "previous": null,
  "results": [ ... ]
}

Follow the next URL to retrieve the next page. Continue until next is null.

all_transactions = []
url = "https://api.catalystpay.com/api/v1/reconciliation/transactions/"
params = {"start_date": "2025-01-01", "end_date": "2025-03-31", "page_size": 1000}
headers = {"Authorization": "Bearer rk_your_api_key"}

while url:
    response = requests.get(url, headers=headers, params=params)
    data = response.json()
    all_transactions.extend(data["results"])
    url = data.get("next")
    params = None  # next URL includes all params
const allTransactions = [];
let url = `https://api.catalystpay.com/api/v1/reconciliation/transactions/?start_date=2025-01-01&end_date=2025-03-31&page_size=1000`;
const headers = { Authorization: "Bearer rk_your_api_key" };

while (url) {
  const response = await fetch(url, { headers });
  const data = await response.json();
  allTransactions.push(...data.results);
  url = data.next;
}

Cursor pagination guarantees you see every record exactly once, even if new records are inserted during iteration. Never construct or decode cursor values -- always follow the next URL.

Output formats

JSON (default)

Standard JSON response with results array and pagination URLs.

XML

Append ?format=xml to get XML output:

curl "https://api.catalystpay.com/api/v1/reconciliation/transactions/?start_date=2025-01-01&format=xml" \
  -H "Authorization: Bearer rk_your_api_key"

CSV

Append ?format=csv to download a CSV file:

curl "https://api.catalystpay.com/api/v1/reconciliation/transactions/?start_date=2025-01-01&format=csv" \
  -H "Authorization: Bearer rk_your_api_key" \
  -o transactions.csv

CSV responses include a Content-Disposition header with a descriptive filename (e.g., transactions_2025-04-01.csv).

IBAN masking

IBAN values in all reconciliation responses are masked, showing only the last 4 characters (e.g., DE89370400440532013000 becomes ******************3000). This is a security measure that cannot be disabled via the API.

Use merchant_transaction_id, tenant_reference_id (when supplied on /pay/ submission), or lead_id for record matching, not IBAN values.

Date field differences

Transactions filter on date_processed (when the payment event occurred at the gateway). Chargebacks filter on report_date (when the chargeback was reported to the merchant). Subscriptions filter on created_at (when the subscription was created).

This distinction matters for reconciliation workflows. When you query "what happened yesterday," you want transactions that were processed yesterday and chargebacks that were reported yesterday -- not chargebacks whose underlying transactions were processed yesterday.

The maximum date range is 90 days. Requests exceeding this limit return a 400 validation error. For longer periods, make multiple requests with consecutive date ranges.

Transaction sources

Every transaction carries a source field indicating how it was created:

Source Description
csv_import Imported from a gateway settlement CSV
api_submission Submitted via the batch submission service
hosted_page Created through the hosted payment page
admin_refund Initiated by an admin refund action
webhook Created or updated via inbound gateway webhook

Settlement matching workflow

A typical reconciliation integration follows this pattern:

  1. Daily pull: Query transactions for the previous day with ?start_date=YYYY-MM-DD&status=approved
  2. Match records: Use merchant_transaction_id to match CatalystPay transactions against your accounting system, or supply your own tenant_reference_id on /pay/ submission and match on that
  3. Check chargebacks: Query chargebacks for the same period to identify disputed transactions (chargebacks echo the original transaction's tenant_reference_id)
  4. Monitor subscriptions: Query subscriptions to track active billing and upcoming rebills

Next steps