Added

App - transact V2 - Validation and normalization


What is this about?

We’re rolling out stricter validation and normalization across several safe-transact API endpoints.

This change is intended to make asset, address, identifier, and relationship inputs more consistent and predictable, while reducing cases where malformed data is accepted.

How is this affecting me?

If you are integrating with these APIs, or already have an integration running, this change may affect you in two ways:

  1. Validation: you will receive a 400 error if you submit an invalid payload according to the new validation requirements.
  2. Normalization: the API will return normalized values. For GET endpoints, data returned by the API may be normalized according to the logic described below.

Affected endpoints

Validation rules

DID fields must match /^did:[a-z0-9]+:.+/

  • ✅ did:key:z6mkh...
  • ❌ user_123

IRI-style fields affect fields such as @id and delegateId must match /^[a-zA-Z][a-zA-Z0-9+.-]*:.+$/

  • ✅ https://example.com/id/123
  • ✅ urn:uuid:123e4567-e89b-12d3-a456-426614174000
  • ❌ 12345

Address validation checks that addresses are valid for the relevant chain when chain context is available.

  • ✅ Plain address, CAIP-10, and did:pkh inputs are accepted where supported
  • ✅ Existing did:pkh values are checked for consistency with the provided asset chain
  • ❌ Invalid address format for the given chain returns 400
  • ❌ Chain/address mismatches return 400

Examples:

  • ✅ 0xAbC123... with an EVM asset
  • ✅ did:pkh:eip155:1:0xabcd1234...
  • ❌ BTC address provided with an EVM asset
  • ❌ Malformed did:pkh value

Transaction hash validation checks settlement and transfer hash inputs for valid structure.

  • ✅ Raw chain hashes may be accepted and normalized where supported
  • ✅ CAIP-220 formatted values are accepted
  • ❌ Invalid or malformed transaction hash values return 400

Examples:

  • ✅ 0x4e3f...
  • ✅ eip155:1:tx/0x4e3f...
  • ❌ not-a-hash
  • ❌ eip155:1:tx/

Asset validation checks that asset values are valid CAIP-19 identifiers and that the chain can be resolved.

  • ✅ Supported CAIP-19 asset values are accepted, ticker symbol is also accepted, learn more here
  • ❌ Unknown or unresolvable asset values return 400

Examples:

  • ✅ eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
  • ❌ Invalid CAIP-19 asset format
  • ❌ Asset with an unresolvable chain

Memo tag validation checks memo or destination-tag values extracted from CAIP-10 addresses and validates them per chain.

  • ✅ Chain-specific memo formats are accepted
  • ❌ Invalid memo format returns 400
  • ❌ Conflicting memo values return 400

Examples:

  • ✅ XRP address with numeric destination tag
  • ❌ XRP address with non-numeric destination tag
  • ❌ Conflicting memo tag values in the same request

Array-typed fields enforce schema shape, per-field length checks, and maxItems: 25

Free-form string fields, including IVMS-related values and txAppend payload fields, enforce length limits of 2–255 characters

Endpoint validation matrix

EndpointDID regexIRI regexAddress validationTx hash validationAsset validationMemo tag validationUnknown address 2–255Array validation
POST /entities/{entityDID}/txYesYesYesYesYesYesYesNo
POST /entities/{entityDID}/tx/{transferId}/settleNoNoNoYesNoNoNoNo
GET /entities/{entityDID}/tx/matchNoNoYesYesYesYesYesNo
POST /entities/{entityDID}/tx/{transferId}/agentsYesYesYesNoYesYesYesNo
POST /entities/{entityDID}/tx/{transferId}/agents/replaceYesYesYesNoYesYesYesNo
POST /entities/{entityDID}/relationshipsYesNoYesNoYesNoNoNo
PATCH /entities/{entityDID}/relationshipsYesNoYesNoYesNoNoNo
GET /entities/{entityDID}/relationshipsYesNoYesNoYesNoNoNo
DELETE /entities/{entityDID}/relationshipsYesNoYesNoYesNoNoNo
POST /entities/{entityDID}/transfers/{transferId}/appendNoYesNoNoNoNoNoYes
POST /entities/{entityDID}/delegateTokenYesYesNoNoNoNoNoNo
POST /entity/{entityDID}/address-ownership/discoverYesNoYesNoYesYesYesNo

Normalization

EVM addresses are normalized to lowercase on write, with case-insensitive lookup on read.

  • Input: 0xABCD1234...
  • Stored/compared as: 0xabcd1234...

Address inputs are normalized to did:pkh format where applicable.

  • Input: plain address / CAIP-10 / did:pkh
  • Normalized form: did:pkh:<namespace>:<reference>:<address>

Transaction hashes are normalized to CAIP-220 format where applicable.

  • Input: raw chain hash
  • Normalized form: <namespace>:<reference>:tx/<hash>