When you're integrating a payment flow that can route over the SEPA or SEPA Instant schemes, the postal address you attach to the creditor (and optionally the debtor) needs to meet the European Payments Council's structured address requirements from the 15th November 2026. It is recommended you consider this for your implementation as soon as possible.
You need to read this page if any of the following apply to your integration:
- You initiate SEPA or SEPA Instant payments (including via
AUTO_SELECTresolving to one of these rails), and you populatecreditor.addressordebtor.addressacross our Payments v1 or Payments v2 API. - You integrate with a bank that mandates a creditor address. In Token.io's registry, 113 banks currently require one, concentrated in Italy (94 banks, via CBI Globe), with the rest spread across the UK, Poland, Spain, Hungary, Norway, Finland and Sweden.
- You're deciding how to model postal addresses in your own data layer before mapping them onto Token.io's API.
You can skip this if you only use rails outside the SEPA schemes —
FASTER_PAYMENTS,ELIXIR,BANKGIRO,PLUSGIRO,EU_DOMESTIC_NON_EURO,EU_DOMESTIC_NON_EURO_INSTANT— or you never supply an address object and no bank in your flow requires one. Note that no bank in Token.io's registry requires a debtor address — where an address is mandated, it's always on the creditor.
The European Payments Council's guidance EPC153-22 v2.1, Provision of Addresses under the EPC Payment Schemes, removes the fully unstructured postal address from the SEPA schemes from 15th November 2026. From that date, any postal address carried in a SEPA Credit Transfer or SEPA Instant Credit Transfer must be either structured or hybrid:
| Format | Structured (townName + country) | addressLine | Accepted from 15th November 2026 |
|---|---|---|---|
| Structured | Yes | Not used | Yes |
| Hybrid | Yes | Yes — max 2 lines × 70 characters | Yes |
| Unstructured | No | Yes, lines only | No |
Token.io's address object already supports the hybrid format — structured fields alongside a free-text line — so there's no need to wait for a schema change. The design goal for your integration is simple: never rely on addressLine alone. Build your mapping so the structured fields are always populated when you have the data, and use addressLine only for what genuinely doesn't fit a structured field — a building name, floor, or department.
Getting this right at initiation means a bad address surfaces as an immediate 400 with the exact field to fix, rather than the payment failing later at the payer's bank, or being silently repaired or rejected downstream after the payer believes it's succeeded.
| Purpose | Field (v2, address) | Field (v1, customer_data.address) | Requirement | Max length | Error code |
|---|---|---|---|---|---|
| Town / city | townName | city | Mandatory whenever an address object is supplied | 35 | Field.Expected / Field.InvalidFormat |
| Country | country | country | Mandatory whenever an address object is supplied; ISO 3166-1 alpha-2, upper case | 2 | Field.Expected / Field.Invalid |
| Street | streetName | street | Optional | 70 | Field.InvalidFormat |
| Building number | buildingNumber | houseNumber | Recommended | 16 | Field.InvalidFormat |
| Post code | postCode | postCode | Recommended | 16 | Field.InvalidFormat |
| Remaining unstructured text | addressLine | full | Recommended, last resort | 2 entries, 70 characters each | Field.InvalidFormat |
Note: an earlier version of this content listed
streetNameas the v2 field for Building number — that's been corrected tobuildingNumberabove to match the field name used elsewhere in the API and in the reference docs. Worth a final check against the OpenAPI schema before this goes live.
These lengths aren't Token.io-specific limits — they're the ISO 20022 lengths that the SEPA schemes and the underlying open banking standards apply. Since the API doesn't currently enforce them, it's worth building your own client-side validation against this table rather than discovering the limits from a live rejection.
townName is worth checking first. At 35 characters it's the shortest of the two mandatory fields, and unlike country, town names vary a lot in length. If your own data model allows longer values, decide deliberately how you'll truncate or reject them, rather than letting the value pass through unexamined.
An address expressed as a single free-text line won't be considered structured or hybrid:
"address": {
"addressLine": ["Palazzo Vecchio, Piano 2, Via Roma 12, 50122 Firenze, Italia"]
}The same address, split into structured fields with only the non-structured remainder left in addressLine, is the pattern to build towards:
"creditor": {
"iban": "IT60X0542811101000000123456",
"name": "Customer Inc.",
"address": {
"addressLine": ["Palazzo Vecchio, Piano 2"],
"streetName": "Via Roma",
"buildingNumber": "12",
"postCode": "50122",
"townName": "Firenze",
"country": "IT"
}
}A couple of things to avoid when building your mapping:
- Don't duplicate an element in both places. If you populate
townName, don't also repeat the town insideaddressLine— duplicated elements may be rejected or duplicated in the payment message by the payer's bank. - Don't let
addressLinegrow past 2 entries or 70 characters each. If your source address data doesn't fit, that's a sign it should be broken into structured fields instead of truncated.
A non-compliant address returns a 400 with the standard field-error object, listing the offending JSON paths:
{
"error": {
"errorCode": "Field.Expected",
"message": "The fields 'townName' and 'country' are required when an address is supplied for a SEPA payment.",
"paths": [
"initiation.creditor.address.townName",
"initiation.creditor.address.country"
],
"tokenTraceId": "eASI3Onqkpi1unAM59O5"
}
}These are existing error codes (Field.Expected, Field.Invalid, Field.InvalidFormat) already used for field validation elsewhere in the API — no new codes are introduced for this.
The same address object is shared across several Token.io products. Design your address-handling logic once and reuse it everywhere you touch these endpoints:
Payments v2 — POST /v2/payments
initiation.creditor.addressinitiation.debtor.address— applies when you supply full debtor account details (not when using an Account on File identifier), and is validated on the same terms ascreditor.address.
Payments v1 — POST /token-requests Uses a different address model with different field names: transfer_body.instructions.transfer_destinations.customer_data.address. Field lengths are the same as v2 — they come from ISO 20022, not the API version. If you're integrating fresh, prefer v2's field names and structure. If you're on v1 and use the full field, be aware it's documented as free text that "typically cannot be parsed by software." Pair it with city and country, and keep it within the 2×70 character limit.
Pay by Link — POST /v2/payment-links — paymentTemplate.creditor.address
Refunds — POST /refunds doesn't take a postal address at all; a refund's creditor.address/debtor.address are derived from the original payment. No extra handling needed here.
Variable Recurring Payments — POST /vrp-consents — initiation.creditor.address, initiation.debtor.address. VRP consents currently only support UK Faster Payments accounts, which sit outside the SEPA schemes, so these rules don't currently bite on VRP — but the same object is used, so build to this standard now if you want to be ready should a SEPA rail be added later.
- Populate
townNameandcountry(v1:cityandcountry) on every SEPA/SEPA Instant address you send.countrymust be upper-case ISO 3166-1 alpha-2. - Map any single free-text address into structured fields, keeping only the genuine remainder in
addressLine. - Validate field lengths client-side against the table above before sending — don't rely on the API to catch it.
- Avoid duplicating the same address element across a structured field and
addressLine. - Populate
streetName,buildingNumberandpostCodewherever you hold the data — recommended, not mandatory, but the safer default as more banks complete their own migrations. - Parse the
pathsarray onField.*errors so validation failures surface as actionable, field-level messages to your own users. - Test address handling in Sandbox before going live.
- EPC153-22 v2.1 — Provision of Addresses under the EPC Payment Schemes
- POST /v2/payments API reference
For help with any of the above, contact Token.io Support or speak with your implementation manager.
If you have any feedback about the developer documentation, please contact devdocs@token.io