SPEI Transactions API — V1 to V2 Migration Guide

Why Migrate?

The V1 SPEI Transactions API (/spei/v1/deposits and /spei/v1/withdrawals) uses offset-based pagination, which suffers from increasing latency as you paginate deeper into large result sets. Clients performing reconciliation over wide date ranges have experienced significant slowdowns on V1.

The V2 APIs resolve these performance issues by replacing offset pagination with token-based pagination. These changes bring many benefits:

  • Consistent performance: response times remain stable regardless of how deep you paginate. Latency spikes are not expected with the new APIs.
  • Incremental synchronization: you can resume from the last token without re-fetching earlier pages.
  • Cleaner response format: response payloads were improved to contain the most relevant and useful data for the deposits and withdrawals.
  • Bidirectional refund linking: both deposits and withdrawals include cross-references to their counterpart, simplifying refund reconciliation.

Endpoint Mapping

ResourceV1 EndpointV2 Endpoint
DepositsGET /spei/v1/depositsGET /spei/v2/deposits, see API reference.
WithdrawalsGET /spei/v1/withdrawalsGET /spei/v2/withdrawals, see API reference.
Single WithdrawalNot availableGET /spei/v2/withdrawals/{wid}, see API reference.

Pagination Details

The V1 API responses included page, page_size, total_pages, and total_elements. With the V2, these fields were deprecated, and the new response includes a next_page_token field.

Pass it as page_token in the next request to retrieve the following page. When next_page_token is absent, you have reached the end of the collection.

📘

Opaque page tokens

The page_token values are opaque. Do not parse, decode, or construct them. They are only valid for the original query parameters — changing filters while reusing a token produces undefined behavior.


Deposits

Removed Query Parameters

The following V1 query parameters have been removed in V2 and have no direct equivalent:

V1 ParameterNotes
pageReplaced by token-based pagination. Use page_token instead.

Query Parameter Equivalents

The following V1 query parameters have a direct or renamed equivalent in V2:

V1 ParameterV2 ParameterNotes
only_refundsonly_refundsUnchanged.
receiver_clabereceiver_clabeUnchanged.
sender_clabesender_clabeUnchanged.
clabe_typeclabe_typeUnchanged.
deposit_statusstatusRenamed. Values are now uppercase (e.g., COMPLETE, PENDING, FAILED).
tracking_keytracking_keyUnchanged.
start_datecreated_at_gteISO 8601 timestamp (e.g., 2025-04-10T00:00:00Z). Inclusive. Defaults to the start of the previous day when not provided.
end_datecreated_at_lteISO 8601 timestamp. Inclusive. When both bounds are provided, created_at_gte must be less than or equal to created_at_lte.
page_sizepage_sizeUnchanged. The maximum is 1000. Default is 25.

Removed Response Fields

The following V1 response fields have been removed in V2 and have no direct equivalent:

V1 FieldNotes
depositIdNo longer exposed.
currencyAlways MXN; no longer returned.

Response Field Equivalents

The V1 response nests most transaction metadata inside a details object. V2 promotes these fields to the top level for a flatter, more ergonomic structure.

V1 FieldV2 FieldNotes
fidfidUnchanged.
senderClabesender.clabeMoved into a structured sender object that also includes name, bank, and rfc_curp.
receiverClabereceiver_clabeUnchanged.
statusstatusValues are now uppercase.
amountamountUnchanged.
details.claveRastreotracking_keyPromoted to top level.
details.numericReferencenumeric_referencePromoted to top level.
details.conceptodescriptionRenamed and promoted to top level.
details.cepLinkcep_linkPromoted to top level.
details.senderNamesender.nameMoved into sender object.
details.senderBanksender.bankMoved into sender object.
details.paymentIdpayment_idPromoted to top level.

New Fields in V2

The following fields are new in V2 and were not available in V1:

V2 FieldDescription
operation_dateThe date the deposit was processed by the banking system. Format: ISO 8601 date (YYYY-MM-DD).
refunded_withdrawalLightweight reference to the original withdrawal that was reversed, containing wid, tracking_key, and origin_id. See Refund Reconciliation.
errorsArray of error objects describing why the deposit reached a non-successful final state. Each error contains a code and message. null when the deposit has no errors.

The V1 field details.multiclabe_validation_error has been deprecated. In V2, deposit errors are now defined in the errors field, which provides structured error information with a code and message for each error. The complete error catalogue can be found in the API Reference.


Withdrawals

Removed Query Parameters

The following V1 query parameters have been removed in V2 and have no direct equivalent:

V1 ParameterNotes
widUse GET /spei/v2/withdrawals/{wid} to fetch a single withdrawal by ID instead.
pageReplaced by token-based pagination. Use page_token instead.

Query Parameter Equivalents

The following V1 query parameters have a direct or renamed equivalent in V2:

V1 ParameterV2 ParameterNotes
origin_idorigin_idUnchanged.
receiver_clabeaccount_numberRenamed. Searches across CLABE, debit card, and phone number.
withdrawal_statusstatusRenamed. Values are now uppercase (e.g., COMPLETE, PENDING, FAILED, PROCESSING).
tracking_keytracking_keyUnchanged.
only_refundsonly_refundsUnchanged.
start_datecreated_at_gteISO 8601 timestamp. Inclusive. Defaults to the start of the previous day when not provided.
end_datecreated_at_lteISO 8601 timestamp. Inclusive. When both bounds are provided, created_at_gte must be less than or equal to created_at_lte.
page_sizepage_sizeUnchanged. The maximum is 1000. Default is 25.

Removed Response Fields

The following V1 response fields have been removed in V2 and have no direct equivalent:

V1 FieldNotes
currencyAlways MXN; no longer returned.

Response Field Equivalents

The V1 response nests most transaction metadata inside a details object. V2 promotes these fields to the top level and replaces the embedded full deposit object with a lightweight reference.

V1 FieldV2 FieldNotes
widwidUnchanged.
details.originIdorigin_idPromoted to top level.
amountamountUnchanged.
statusstatusValues are now uppercase.
details.claveDeRastreotracking_keyPromoted to top level.
details.conceptodescriptionRenamed and promoted to top level.
details.beneficiaryNamebeneficiary.nameMoved into structured beneficiary object.
details.beneficiaryClabebeneficiary.account.numberMoved into beneficiary.account with a type discriminator (CLABE, DEBIT_CARD, PHONE). Debit card numbers are obfuscated for security.
details.cepLinkcep_linkPromoted to top level.
details.fechaOperacionoperation_datePromoted to top level; formatted as ISO 8601 date (YYYY-MM-DD).
refundDeposit (full deposit)refunded_deposit (lightweight)Replaced with a lightweight reference. See Refund Reconciliation.

New Fields in V2

The following fields are new in V2 and were not available in V1:

V2 FieldDescription
operation_dateThe specific date when the withdrawal was processed by the banking system. Format: ISO 8601 date (YYYY-MM-DD).
refunded_depositLightweight reference to the compensatory deposit, containing fid and tracking_key. See Refund Reconciliation.

Refund Reconciliation

When a withdrawal fails, the banking system may issue a compensatory deposit back to the sender.

V2 Approach

V2 provides bidirectional linking with lightweight references on both sides:

  • A withdrawal includes a refunded_deposit object with the compensatory deposit's fid and tracking_key.
  • A deposit includes a refunded_withdrawal object with the original withdrawal's wid, tracking_key, and origin_id.
V2 Withdrawal                     V2 Deposit
┌─────────────────────────┐       ┌─────────────────────────┐
│ wid: "w-123"            │       │ fid: "d-456"            │
│ status: "FAILED"        │       │ status: "COMPLETE"      │
│ refunded_deposit: {     │──────▶│ refunded_withdrawal: {  │
│   fid: "d-456"          │       │   wid: "w-123"          │
│   tracking_key: "..."   │◀──────│   tracking_key: "..."   │
│ }                       │       │   origin_id: "a261847a" │
└─────────────────────────┘       │ }                       │
                                  └─────────────────────────┘

To reconcile refunds in V2:

  1. Starting from withdrawals: Search the refunded withdrawals, using the only_refunds param. Each result contains a refunded_deposit with the fid and tracking_key of the compensatory deposit. These two fields allow us to match the deposit that was created to compensate the withdrawal.

  2. Starting from deposits: Search the refunded deposits, using the only_refunds param. Each result contains a refunded_withdrawal with the wid, tracking_key, and origin_id of the compensated withdrawal. These three fields allow us to match the withdrawal that originated the compensatory deposit.


Did this page help you?