Current (2025-04-01)

Migrate from 2024-03-18 to 2025-04-01

This guide describes every change between API version 2024-03-18 and 2025-04-01 for both the Merchants API and the Platforms API. The deltas below come from comparing the two OpenAPI specs directly, so each item reflects an actual difference in paths, request bodies, response schemas, enums, or required fields.

Version 2025-04-01 introduces breaking changes. Read the sections that apply to your integration before you switch.

This is not a drop-in upgrade

Several endpoints from 2024-03-18 are not present in 2025-04-01, and shared endpoints changed their request and response shapes. Plan to update your code, not just the version string in the URL.

How to set the version

Chargeflow uses date-based versioning in the request path. The version is the date segment after /public/. To move to 2025-04-01, replace the date in every request path.

Authentication did not change. Both versions use the x-api-key request header with the same production server, https://api.chargeflow.io.

Terminal
curl https://api.chargeflow.io/public/2024-03-18/disputes \
  -H "x-api-key: YOUR_API_KEY"

For background on how versions work, see API versioning.

Merchants API changes

Endpoint changes

Method and path2024-03-182025-04-01Change
GET /disputesYesYesResponse shape changed, query parameters reduced
GET /disputes/{disputeId}NoYesNew endpoint
PATCH /disputes/{disputeId}NoYesNew endpoint (Enrich Dispute)
POST /disputesYesNoRemoved
POST /disputes/{disputeId}/orderYesYesCarried over
POST /disputes/{disputeId}/evidenceYesYesUnchanged
POST /disputes/{disputeId}/subscriptionNoYesNew endpoint
POST /disputes/{disputeId}/transactionNoYesNew endpoint
POST /disputes/{disputeId}/user_events_logNoYesNew endpoint
GET /alertsNoYesNew endpoint
GET /alerts/{alertId}NoYesNew endpoint
POST /alerts/{alertId}/outcomeNoYesNew endpoint
POST /customer-communicationNoYesNew endpoint
POST /data-subject/removalNoYesNew endpoint
GET /webhooksYesYesResponse shape changed
POST /webhooksYesYesUnchanged ({event, url}, one event per registration)
DELETE /webhooks/{id}YesYesUnchanged
GET /health-checkYesYesUnchanged
GET /health-check/access-keyYesYesUnchanged

Removed endpoints

These endpoints exist in 2024-03-18 but are not in 2025-04-01. If you call them, you need to stop or move to a replacement.

Removed endpointNotes
POST /disputesNo direct equivalent in the Merchants API for 2025-04-01. To enrich an existing dispute, use PATCH /disputes/{disputeId} and the per-resource POST endpoints instead.

GET /disputes response changed

The list response was restructured. The top-level fields and the per-item shape both changed.

2024-03-182025-04-01
totalCount (number)moved under pagination.totalCount (integer)
hasMore (boolean)removed
data (array of objects)renamed to disputes (array)
no pagination objectnew pagination object with totalCount, offset, limit, totalPages

In 2024-03-18, each item in data had a fixed shape with chargeflowDisputeId, a nested dispute object (with processorId, processor, amount, status, reason, responseDueDate), and a nested transaction object. In 2025-04-01, the disputes array items use the flat snake_case dispute shape (id, source, source_id, account_id, created_at, reason, due_by, amount, currency, status, stage, closed_at), with related resources referenced rather than embedded - do not rely on the old data[].dispute and data[].transaction structure. To read a single dispute with full detail, use the new GET /disputes/{disputeId} endpoint.

The query parameters on GET /disputes were also reduced.

Query parameter2024-03-182025-04-01
offsetYes (number)Yes (integer)
limitYes (number)Yes (integer)
dateCreatedFromYesRemoved
dateCreatedToYesRemoved
amountFromYesRemoved
amountToYesRemoved
statusNamesYes (enum)Removed
reasonYes (enum)Removed
processorNamesYes (enum)Removed

Filtering

If you relied on date, amount, status, reason, or processor filters in the query string, that filtering is no longer available on GET /disputes in 2025-04-01. Plan to filter on your side after fetching, or fetch individual disputes by ID.

GET /webhooks response changed

The webhook list items are simpler in 2025-04-01.

Field2024-03-182025-04-01
successbooleanboolean
data[].idstringstring
data[].eventenum (webhook.test, dispute.created, evidence.ready, evidence.error, alerts.created, alerts.updated, alerts.transaction.linked, *)plain string, no enum
data[].urlstringstring
data[].activebooleanremoved
data[].versionstringremoved

Unchanged Merchants endpoints

POST /disputes/{disputeId}/evidence, DELETE /webhooks/{id}, GET /health-check, and GET /health-check/access-key have the same request and response shapes in both versions. The evidence upload still accepts the same two oneOf variants and the same evidenceUploadCategory enums (tracking_information, customer_communication, invoice for the first variant, and additional_evidence, additional_notes for the second).

New Merchants endpoints

2025-04-01 adds several endpoints. The notable request and response details are below.

GET /disputes/{disputeId} returns a single dispute with nested transaction, subscription, and order objects. Note that its reason enum is the smaller set fraud, not_received, not_as_described, canceled_recurring_billing, duplicate_charge, credit_not_processed, other, and status is one of needs_response, under_review, won, lost. It also includes a stage enum (Chargeback, Inquiry, Pre_arbitration, Arbitration) and a source enum listing supported processors.

POST /disputes/{disputeId}/subscription creates subscription context for a dispute. Required fields: source_id, created_at, start_date, frequency (day, week, month, year), and frequency_count.

GET /alerts and GET /alerts/{alertId} return alert records, including a nested network_transaction object and an optional transaction. GET /alerts wraps results in alerts plus the same pagination object used by GET /disputes.

POST /alerts/{alertId}/outcome records an alert outcome. Required field: outcome, one of refunded, previously_refunded, duplicate, decline, error. It returns 202 with no body.

POST /customer-communication submits communication tied to one or more disputes. Required fields: source_id, disputes (array of strings), and messages. Each message requires sender, date, and body_plain_text, and may set a type of email, chat, transcript, form, or sms.

Platforms API changes

The Platforms API changed more than the Merchants API. Every 2024-03-18 Platforms endpoint was removed, and 2025-04-01 introduces a new set of endpoints with a new naming and data model.

Endpoint changes

Method and path2024-03-182025-04-01Change
GET /disputesYesNoRemoved
POST /disputesYesNoRemoved
POST /disputes/{disputeId}/orderYesNoRemoved
POST /platform/disputesNoYesNew endpoint (replaces dispute creation)
POST /accountsNoYesNew endpoint
GET /accounts/{accountId}NoYesNew endpoint
POST /evidenceNoYesNew endpoint
GET /evidence/{evidenceId}NoYesNew endpoint

No shared Platforms endpoints

There are no Platforms endpoints common to both versions. The 2025-04-01 Platforms API is a new surface, so treat the migration as a rewrite of your Platforms integration rather than a field rename.

Removed Platforms endpoints

Removed endpoint2025-04-01 direction
GET /disputesNo list endpoint in 2025-04-01. Fetch a single record instead, for example via GET /evidence/{evidenceId}.
POST /disputesReplaced by POST /platform/disputes with a new request body.
POST /disputes/{disputeId}/orderOrder data is now nested inside the dispute or evidence request body, not a separate call.

Dispute creation model changed

The old POST /disputes and the new POST /platform/disputes both create a dispute, but the request bodies are different. The data model moved from a flat, processor-oriented payload to a nested model with transaction, subscription, and order objects, and the field names changed from camelCase to snake_case.

Old field (POST /disputes)New field (POST /platform/disputes)
disputeId (required)not used as input; the response returns id
creationDate (required)created_at (required)
due_by (required)due_by (required)
disputeAmount (required)amount (required)
currency (required)currency (required)
processor (required)not present; use source_id (required) plus the response source enum
isChargeRefundable (required)removed
handleByChargeflow (required)removed
reason (required, large enum)reason (required, smaller enum)
status (enum needs_response, warning_needs_response)status (required, enum needs_response, under_review, won, lost)
no account_idaccount_id (required)
products, pastPayments (flat arrays)nested under order and transaction objects

New required fields on POST /platform/disputes: source_id, account_id, created_at, reason, due_by, amount, currency, status.

The reason enum is smaller and uses different values.

Old reason valuesNew reason values
general, fraudulent, duplicate, subscription_canceled, product_unacceptable, product_not_received, unrecognized, credit_not_processed, incorrect_account_details, insufficient_funds, bank_cannot_process, debit_not_authorized, goods_services_returned_or_refused, goods_services_cancelled, transaction_amount_differs, retrievedfraud, not_received, not_as_described, canceled_recurring_billing, duplicate_charge, credit_not_processed, other

Map your old reason values to the new set before you send them. There is no automatic conversion.

The new request body also supports rich nested objects:

  • transaction with payment_method (including brand, wallet, and a checks object for 3-D Secure and AVS results) and billing_address.
  • subscription with frequency, frequency_count, collection_method, pricing_model, and status.
  • order with customer, products (each requiring name, type, quantity, price), shipping_address, and fulfillments.

The response is a full dispute object with id, a source enum, status (needs_response, under_review, won, lost), stage, and the nested transaction, subscription, and order objects.

New Platforms endpoints

POST /accounts creates a platform account. Required fields: owner_name, business_name, business_url, email. The status enum is active or inactive. The response returns the account with a generated id.

GET /accounts/{accountId} returns a single account in the same shape as the create response.

POST /evidence generates evidence. Required fields: account_id and dispute. The dispute field is an anyOf: either { "dispute_id": "..." } to reference an existing dispute, or { "dispute_data": { ... } } to pass the full dispute payload inline. The inline dispute_data uses the same nested transaction, subscription, and order model as POST /platform/disputes. The response returns an evidence record with id, status (in_progress, completed, error), file_url, and file_version.

GET /evidence/{evidenceId} returns an evidence record. Its dispute field is an anyOf of a string ID or the full nested dispute object.

Upgrade checklist

Update the version segment in every request path from /public/2024-03-18/ to /public/2025-04-01/. Keep the x-api-key header as is.

For Merchants GET /disputes, read results from disputes instead of data, and read counts from the new pagination object instead of totalCount and hasMore. Remove any reliance on the old data[].dispute and data[].transaction structure.

Replace removed Merchants query filters (dateCreatedFrom, dateCreatedTo, amountFrom, amountTo, statusNames, reason, processorNames) with client-side filtering or per-dispute lookups via GET /disputes/{disputeId}.

For Merchants GET /webhooks, stop reading data[].active and data[].version, and treat data[].event as a plain string rather than a fixed enum.

Stop calling the removed Merchants endpoint POST /disputes. Adopt the new endpoints (GET /disputes/{disputeId}, PATCH /disputes/{disputeId}, POST /disputes/{disputeId}/subscription, POST /disputes/{disputeId}/transaction, the alerts endpoints, and POST /customer-communication) where they fit your flow.

For Platforms, rebuild your dispute creation against POST /platform/disputes. Rename camelCase fields to snake_case, send the new required fields (source_id, account_id, created_at, reason, due_by, amount, currency, status), and map old reason values to the new seven-value enum.

For Platforms, move order, transaction, and subscription data into the nested objects in the dispute body instead of calling the removed POST /disputes/{disputeId}/order.

Adopt the new Platforms endpoints you need: POST /accounts and GET /accounts/{accountId} for account management, and POST /evidence and GET /evidence/{evidenceId} for evidence generation.

Confirm connectivity and credentials on the new version with GET /health-check and GET /health-check/access-key, which are unchanged.

Next steps

Was this page helpful?

On this page