Trust & ToolingRound-trip Verification

Round-trip verification

Check a conversion for silent data loss. Verify re-reads the converted output and reports every value that did not survive, split into warned and silent losses.

What verify answers

Some conversions cannot carry everything. A camt.053 statement can name the counterparty's bank; MT940 has no field for it. transmute reports each such loss as a warning. Verify checks that promise for one specific message: was anything lost without a warning?

It converts your message exactly as Convert does, reads the output back, and compares the result with your source. The comparison walks a checklist of value-bearing fields for the message family (payments, statements, initiations, and so on): amounts, dates, BICs, IBANs, references, UETRs, names, addresses and free text. Each value either comes back, or it is reported as lost.

Two ways to call it

RouteReturnsUse when
POST /v1/verifyThe loss report, the conversion's warnings and meta, but not the converted documentYou want to check a message, not use the output
POST /v1/convert with verifyThe normal convert response plus the same loss reportYou want the converted document and the check in one call

To add the report to a conversion, send "options": { "verify": true } in the JSON envelope, or ?verify=true (or the X-Transmute-Verify: true header; the query parameter wins) with a raw body. The conversion runs once; verify only reads its output back.

POST /v1/verify takes the same request forms, query parameters, headers and options as POST /v1/convert (a JSON envelope, raw MT as text/plain, or raw XML), with to required:

curl -sS -X POST "https://api.transmute.403fin.io/v1/verify?to=camt.053" \
  -H "Authorization: Bearer $TRANSMUTE_KEY" \
  -H "Content-Type: text/plain" \
  --data-binary @statement.mt940
{
  "verify": {
    "family": "statement",
    "survived": 14,
    "lost": [],
    "warned": [],
    "silent": []
  },
  "warnings": [ { "code": "MISSING_REQUIRED_DEFAULTED", "...": "..." } ],
  "meta": { "detectedType": "mt940", "targetType": "camt.053.001.08", "durationMs": 4 }
}

The report is JSON only. With verify on /v1/convert, a bare-document or zip Accept is an invalid-input 400. Batch items reject verify.

Read the report

FieldMeaning
familyThe message family whose checklist was used, such as payment or statement
survivedHow many value-bearing source values were found again in the output
lostEvery value that was not found again. Always warned plus silent
warnedLost values that a loss warning names. These are expected and documented
silentLost values that no warning names. This list should always be empty

Each entry in lost, warned and silent looks like this:

{ "invariant": "counterparty-bics", "class": "bic", "value": "AAAADEFFXXX", "codes": ["DROP_FIELD"] }
FieldMeaning
invariantThe checklist row, such as settled-amount, agent-bics or counterparty-bics
classThe kind of value: amount, date, bic, iban, ref, uetr, text or address
valueThe source value that did not come back
codesThe loss warnings that name this field. Absent on a silent entry

A value counts as warned when the conversion raised a loss warning for its field: a TRUNC_*, DROP_* or CHARSET_* code, OVERRIDE_SUPPRESSED or FIELD_OVERSIZED. Any other lost value is silent.

Two rules keep the report free of noise:

  • Re-wrapped text survives. MT fields have short lines, so long text is split differently on the way. Text that only changed by line breaks counts as found.
  • Transliterated text is a warned loss. When text had to be rewritten into the SWIFT character set (for example Ä to AE) for an MT target, it counts as lost under the matching CHARSET_* warning.

What to do with the result

  • silent is empty and warned is empty: every checked value made it across.
  • warned has entries: the target format cannot hold these values. The warnings tell you which fields and why. Decide whether that is acceptable for your flow, or send the values another way. A camt.053 converted to MT940, for example, loses counterparty BICs, names and addresses under DROP_FIELD.
  • silent has entries: transmute lost a value without telling you. That is a defect. Contact support with the request id from the X-Request-Id header and, if you can, an anonymized copy of the message.

Limits

  • Targets that transmute writes but cannot read back cannot be verified: csv-xero, ofx, qfx and qbo return unsupported-conversion 422.
  • Everything that would make the conversion fail (an unknown format, an unsupported pair, a body over the size cap) fails verify the same way.

Privacy

Report entries quote the source value, so you can find the field in your message. Like the converted document, the report exists only in the HTTP response. transmute does not store or log it.

Access and billing

Both forms need the convert scope. POST /v1/verify counts as one conversion, and verify on a convert request is part of that conversion, with no separate charge. The usual billing rules apply.