Mastercard Transaction Link ID (TLID)

A guide to Spreedly's implementation of Transaction Link Identifiers according to the Mastercard specification.

Mastercard has recently introduced the Transaction Link Identifier (TLID), a 22-character identifier carried in DE 105 that replaces legacy linking fields (Banknet Reference Number, Trace ID, Switch Serial Number). Starting October 23, 2026, the TLID from an original cardholder-initiated transaction (CIT) should be included on later merchant-initiated transactions (MITs) that reference it, such as, a subscription sign-up (CIT) followed by a renewal charge (MIT) months later.

TLID also applies to voids, refunds, incremental authorizations, and chargebacks, but CIT-to-MIT linking for recurring billing and installment plans is the most immediate requirement for most Spreedly customers.

How Spreedly handles TLID

Spreedly captures the TLID returned on an original CIT and can attach it to the corresponding MIT automatically so long as your integration follows the pattern below. For a single subscription per payment method, no extra field is needed. For multiple concurrent subscriptions or installment plans on the same payment method, you need to pass customer_agreement_id so Spreedly attaches the correct TLID rather than guessing.

  • Single subscription or installment plan per payment method: no action required. Spreedly links the CIT to its MITs automatically using the payment method.
  • Multiple subscriptions or installment plans on the same payment method: pass a customer_agreement_id with the CIT so Spreedly can disambiguate which chain a given MIT belongs to. If this is omitted in that scenario, the wrong TLID could be applied to the transaction.
    • Note: If you pass a customer_agreement_id that Spreedly hasn't seen before, it's treated as the start of a new chain, the same as if you hadn't passed one at all.

TLID is returned on every transaction response from a supported gateway. You can also pass a TLID explicitly on a request if you want to manage it yourself.

📘

No fees or declines today

Mastercard has confirmed there is no network logic that declines or fails a transaction due to a missing or incorrect TLID. TLID can't be retrieved retroactively; however, capturing it now on your CITs protects against a compliance gap once the October 23, 2026 rule takes effect.

Gateway support

TLID capture and forwarding is being rolled out gateway by gateway, since it depends on each gateway's ability to return and accept a third-party TLID. Check the table below for current status, or reach out to your Spreedly contact if your gateway isn't listed yet.


GatewayStatusLast VerifiedNotes
EBANX✅ Supported2026-07-24Live in production. Supports capture, retention, and echo of TLID via API, webhooks, and reporting. If you're using EBANX's Direct API, a minor integration update is required. See EBANX's developer portal for field mapping.
Checkout.com✅ Supported2026-07-24TLID is returned today live in production. Passthrough support is being confirmed.
Stripe✅ Supported2026-07-24TLID is returned today live in production. Passthrough support is being confirmed.
Adyen✅ Supported2026-07-24TLID is returned today live in production. Passthrough support is being confirmed.
Moneris✅ Supported2026-09-11TLID is returned today live in production and saved as NTID. Passthrough support is being confirmed. See the gateway guide for more information.
Worldpay / Litle🔄 In progress2026-07-21
Orbital (Chase Paymentech)🔄 In progress2026-08-27
Braintree / PayPal⏳ Not yet supported2026-07-21
dLocal⏳ Not yet supported2026-07-21
CyberSource⏳ Not yet supported2026-07-21
NMI⏳ Not yet supported2026-07-21
Shift4⏳ Not yet supported2026-07-21
PPRO⏳ Not yet supported2026-07-21
2C2P⏳ Not yet supported2026-07-21
Rapyd⏳ Not yet supported2026-07-21

This table isn't exhaustive and gateway support is being assessed and added on a rolling basis. If your gateway isn't listed above, contact your Spreedly representative to check current status or contact customer support to make your request.

What "Last Verified" means: For Supported, it's the date TLID capture/forwarding was confirmed live in production for that gateway. For In progress, it's the date we last checked in on development status internally — not the start date of work. For Not yet supported, it's the date we last checked with the gateway on their roadmap. We recheck and update this table on a rolling basis.


How Spreedly decides which TLID to use


Every transaction is evaluated against the following logic, in order:

  1. You pass tlid explicitly. Spreedly always uses the value you provide, sends it to the gateway, and stores it for future lookups if you also passed a customer_agreement_id.
  2. You pass customer_agreement_id, and Spreedly has a stored TLID for it. Spreedly sends that stored TLID to the gateway — this is the normal renewal/MIT case.
  3. You pass customer_agreement_id, but Spreedly has no record of it yet. Treated as the start of a new chain: no TLID is sent, and whatever the gateway returns is stored against that customer_agreement_id going forward.
  4. You don't pass customer_agreement_id or tlid, but the transaction directly references an earlier one (e.g., a capture referencing its auth, or a refund referencing its purchase). Spreedly carries the TLID forward from that referenced transaction directly — no lookup table involved.
  5. None of the above apply. Treated as a new, unlinked transaction: no TLID sent, and the gateway-returned TLID is stored against the payment method for possible future use.

customer_agreement_id only matters when a single payment method has more than one active subscription or installment plan, otherwise Spreedly can resolve the correct chain from the payment method alone.


Examples

1. Receiving a TLID (first transaction in a chain | CIT)

When you run the initial authorization for a subscription or installment plan, pass customer_agreement_id so Spreedly can later disambiguate which chain a follow-up MIT belongs to. Spreedly captures whatever tlid the gateway returns and includes it in the response with no extra work required.

RequestPOST /v1/gateways/{gateway_token}/purchase.json

{
  "transaction": {
    "payment_method_token": "AbC123examplePMtoken",
    "amount": 1999,
    "currency_code": "USD",
    "customer_agreement_id": "sub_9F2K-customer-example"
  }
}

Response

{
  "transaction": {
    "token": "XyZ789exampleTxnToken",
    "state": "succeeded",
    "customer_agreement_id": "sub_9F2K-customer-example",
    "tlid": "MC0001A2B3C4D5E6F7G8H9",
    "created_at": "2026-07-21T14:02:11Z"
  }
}

Spreedly retains the tlid, keyed to the payment method and customer_agreement_id; therefore, you don't need to store it yourself.

2. Sending a TLID automatically (renewal | MIT)

For a later merchant-initiated transaction against the same agreement, pass customer_agreement_id again (or nothing, if there's only one active chain on that payment method). Spreedly looks up the stored tlid and attaches it before sending to the gateway.

Request

{
  "transaction": {
    "payment_method_token": "AbC123examplePMtoken",
    "amount": 1999,
    "currency_code": "USD",
    "customer_agreement_id": "sub_9F2K-customer-example"
  }
}

Response

{
  "transaction": {
    "token": "Qrs456exampleTxnToken",
    "state": "succeeded",
    "customer_agreement_id": "sub_9F2K-customer-example",
    "tlid": "MC0001A2B3C4D5E6F7G8H9",
    "created_at": "2026-10-24T09:15:47Z"
  }
}

Same tlid as the original CIT — Spreedly echoed it forward automatically.

3. Sending a TLID explicitly (self-managed)

If you want to override or manage TLID yourself, pass tlid directly on the request. When present, Spreedly uses the supplied value instead of doing its own lookup, and still saves it for future use.

Request

{
  "transaction": {
    "payment_method_token": "AbC123examplePMtoken",
    "amount": 1999,
    "currency_code": "USD",
    "tlid": "MC0001A2B3C4D5E6F7G8H9"
  }
}

Response

{
  "transaction": {
    "token": "Tuv321exampleTxnToken",
    "state": "succeeded",
    "tlid": "MC0001A2B3C4D5E6F7G8H9",
    "created_at": "2026-10-24T09:16:03Z"
  }
}

Did this page help you?