← All proposals
OFP-021 OpenMedium

Correct formats for five Data Sharing fields

Ozone Connect Bank Data Sharing v2.2.6 aligned five fields to the types in the Standards Account Information API. Those types are wrong for the data: identifiers that lose their leading zeros and cannot hold letters, an exchange rate with no precision limit, and a salary with no currency or period. This proposal sets one correct format for each field, in both specifications, for V2.2.

Proposed by
Nebras
Author
Thomas Catchpole
Target
V2.2
Opened
2 Nov 2026
Closes
9 Nov 2026
Decision

Cast your vote

Sign in with the Trust Framework to vote — For, Against, or Abstain — recorded in the open with your reasoning. Your organisation and name come from your directory profile, and each person may vote once. Two questions are attached to this vote — set out in section 04 below. The first asks LFIs whether their identifiers fit the proposed formats; the second asks LFIs whether the Frequency values let them populate Salary Frequency.

§ BallotOFP-021Closes 9 Nov 2026 ·
Where do you stand?
Pick a stance to add your name & a comment.
0%
in favour
0
votes cast
0
For
0
Against
0
Abstain
The proposal
01 · Background

Aligned, but to the wrong types

In V2.1, Ozone Connect carries all five fields as strings, while the Standards Account Information API defines them as numbers. The API Hub converts each value to a number when it maps the Ozone Connect response to the Standards response. A value that is not a number is not mapped, and the TPP receives null.

FieldStandards V2.1Ozone Connect V2.1Problem
MerchantIdinteger, minLength 8, maxLength 20stringA merchant identifier containing a letter reaches the TPP as null, and a numeric one loses its leading zeros. The length limits have no effect on an integer.
TerminalIdinteger, minLength 8, maxLength 20string, 8–20As for MerchantId.
BillerIdnumberBillerID: stringA biller code containing a letter reaches the TPP as null, and 015 becomes 15. Both descriptions refer to SADAD, Saudi Arabia’s bill-payment system.
ExchangeRatenumberstringA rate that is not a number reaches the TPP as null. The Standards set no limit on decimal places, and many systems parse a JSON number as a binary floating-point value, which rounds and can be written in exponent form.
SalarynumberstringA salary written with a currency or separators, such as AED 25,000, reaches the TPP as null. A numeric salary has no currency and no period, so a TPP cannot tell what the figure means.

In V2.2-rc2, Ozone Connect Bank Data Sharing v2.2.6 narrows the Ozone Connect side to match the Standards (v2.1 → v2.2 changelog, §16, item 4): salary and exchangeRate become numbers, and BillerID, merchantId and TerminalId become strings of digits only. That stops the nulls by rejecting non-numeric values at the LFI, but it keeps the Standards types. Leading zeros are still lost in the Standards response, an identifier containing a letter cannot be sent at all, and ExchangeRate and Salary are unchanged.

The four transaction fields are returned by GET /accounts/{AccountId}/transactions. Salary is part of the party identity returned by GET /parties and GET /accounts/{AccountId}/parties.

02 · Recommendation

One format per field, in both specifications

Identifiers become strings of letters and digits, ExchangeRate becomes a decimal string, and Salary becomes an amount with a currency and an optional frequency.

FieldProposed formatBasis
MerchantIdstring, ^[A-Za-z0-9]{1,15}$ISO 8583 field 42, the card acceptor identification code: 15 characters, letters allowed.
TerminalIdstring, ^[A-Za-z0-9]{1,16}$ISO 8583 field 41, the card acceptor terminal identification: 8 characters, letters allowed. The limit of 16 leaves room for longer acquirer identifiers.
BillerIdstring, ^[A-Za-z0-9]{1,35}$The 35-character identifier length used throughout ISO 20022.
ExchangeRatestring, ^\d{1,11}(\.\d{1,10})?$The ISO 20022 exchange-rate type (BaseOneRate) allows at most 10 decimal places. A string carries the value exactly, as amounts already are.
SalaryObject: Amount, Currency, optional FrequencyThe amount and currency formats already used for transaction amounts. Frequency values are taken from the existing direct debit frequency list.
Proposed rules
  • MerchantId, TerminalId and BillerId are strings of letters and digits. The LFI MUST send each identifier as it holds it, including leading zeros, and MUST NOT pad it with spaces.
  • BillerId is described for the UAE. The SADAD wording is removed. BillerId is the identifier of the biller as assigned by the LFI or by the bill-payment service it uses.
  • ExchangeRate is a decimal string with at most 10 decimal places. Its meaning is unchanged: the rate between UnitCurrency and the quoted currency.
  • Salary is an object of Amount, Currency and an optional Frequency. When Salary is present, Amount and Currency MUST be present. Frequency is not required; where the LFI holds the period, it SHOULD send it as one of Weekly, Fortnightly, Monthly or Annual. Salary itself stays optional.
  • Both specifications use the same formats. Each Ozone Connect field has the same type and pattern as its Standards counterpart, so the API Hub maps it across unchanged.
Before and after — Standards responses
# GET /accounts/{AccountId}/transactions - V2.1
"TerminalId": null,                                  # "T0012345" at the LFI is not a number
"MerchantDetails": { "MerchantId": 450012345678, ... },   # "000450012345678" at the LFI
"BillDetails": { "BillerId": 15, ... },              # "015" at the LFI arrives as 15
"CurrencyExchange": { "ExchangeRate": 0.27229407760381213, ... }   # no limit on decimal places

# Proposed
"TerminalId": "T0012345",
"MerchantDetails": { "MerchantId": "000450012345678", ... },
"BillDetails": { "BillerId": "015", ... },
"CurrencyExchange": { "ExchangeRate": "0.2722940776", ... }

# GET /parties - V2.1
"Salary": 25000                                      # which currency? per month or per year?

# Proposed
"Salary": { "Amount": "25000.00", "Currency": "AED", "Frequency": "Monthly" }
03 · Technical changes

What changes

Five property definitions in each of two specifications. No endpoint is added or removed.

01 · Standards specification — uae-account-information-openapi.yaml

Change TerminalId, AEMerchantDetails1.MerchantId, BillDetails.BillerId and AECurrencyExchange.ExchangeRate on AETransaction, and Claims.Salary on the party identity, to the formats above. Rewrite the BillerId description without SADAD. Targets V2.2.

02 · Ozone Connect — uae-ozone-connect-bank-data-sharing-openapi.yaml

Apply the same formats to TerminalId, MerchantDetails.merchantId, BillDetails.BillerID and CurrencyExchange.exchangeRate, which the LFI returns from its Ozone Connect GET /accounts/{accountId}/transactions endpoint, and to CustomerPersonClaims.salary, which it returns from GET /customer and GET /accounts/{accountId}/customer. This replaces the digits-only patterns and the number types introduced in v2.2.6.

03 · API Hub

Validate each field against its new format and map it from Ozone Connect to the Standards response. With both sides using the same format, no type conversion is needed.

04 · Documentation and scope

Update item 4 of the V2.2 changelog entry to describe the new formats. The copies of the identity object in the account-opening, FX and Ozone Connect payment specifications are outside this proposal and keep Salary as a number until they are aligned separately.

Proposed definitions
# Standards - uae-account-information-openapi.yaml
TerminalId:
  type: string
  pattern: ^[A-Za-z0-9]{1,16}$
AEMerchantDetails1:
  MerchantId:
    type: string
    pattern: ^[A-Za-z0-9]{1,15}$
BillDetails:
  BillerId:
    type: string
    pattern: ^[A-Za-z0-9]{1,35}$
AECurrencyExchange:
  ExchangeRate:
    type: string
    pattern: ^\d{1,11}(\.\d{1,10})?$
Claims:
  Salary:
    type: object
    required: [ Amount, Currency ]          # Frequency is optional
    properties:
      Amount:    $ref AEActiveCurrencyAndAmount_SimpleType   # ^\d{1,13}$|^\d{1,13}\.\d{1,5}$
      Currency:  $ref ActiveOrHistoricCurrencyCode_1         # ISO 4217
      Frequency: { type: string, enum: [ Weekly, Fortnightly, Monthly, Annual ] }

# Ozone Connect - uae-ozone-connect-bank-data-sharing-openapi.yaml
# The same formats on terminalId, merchantId, BillerID, exchangeRate,
# and salary { amount, currency, optional frequency }.
04 · Questions

Two questions, asked with the vote

These appear as optional boxes when you confirm your vote.

01 · LFIs

Do the card and biller identifiers you hold fit these formats: MerchantId up to 15, TerminalId up to 16 and BillerId up to 35 letters and digits? Do any contain other characters, such as spaces or hyphens?

The limits follow ISO 8583 and are tighter than the 8 to 20 characters the Standards state today. Any identifier that does not fit must be found before the patterns are fixed in V2.2.

02 · LFIs

Salary Frequency is not required. Do the values Weekly, Fortnightly, Monthly and Annual allow you to populate it for the salaries you hold? If not, which values are missing?

Frequency is optional so that an LFI which does not hold a period can still send Salary. Where an LFI does hold one, the list must cover it, or the field cannot be populated.

05 · Pros

What the correct formats buy

  • ✓No value reaches the TPP as null because of its format. A value the LFI holds is a value the TPP receives.
  • ✓Identifiers keep their leading zeros and can carry the letters that card identifiers allow.
  • ✓Each field has the same format in the Standards and in Ozone Connect, so the API Hub maps it across without changing its type.
  • ✓ExchangeRate has a defined precision and arrives exactly as the LFI sent it, with no floating-point rounding or exponent notation.
  • ✓Salary carries its currency, and its period wherever the LFI holds one, so a TPP knows what the figure means.
  • ✓Length limits take effect. Today minLength and maxLength sit on integer fields, where they have no effect.
  • ✓The change is small: five fields in one API, in its two specifications.
06 · Cons

What it costs

  • ×All five fields change type between V2.1 and V2.2, so a TPP that reads them must change its parsing.
  • ×It reverses part of Ozone Connect v2.2.6. An LFI that has already built digits-only identifiers, or a numeric exchangeRate or salary, must change them again.
  • ×The identifier limits are tighter than the 8 to 20 characters the Standards state today. An LFI holding longer merchant or terminal identifiers would fail validation.
  • ×An LFI that holds salary as a bare figure must decide which currency to send with it.
  • ×The identity object that holds Salary is also copied into the account-opening, FX and Ozone Connect payment specifications. Those copies keep number until they are aligned, so Salary differs between specifications for a time.