The restriction object
Every key is always present;null means not set.
A
TOKEN restriction is published on that token’s stream; an ASSET or UNDERLYING_MARKET one on every token stream of the asset. A halt is of the share class, not of a chain, which is why those two carry the assetId.
Reason codes
New codes can be added in minor versions; treat one you do not know as a restriction like any other.
The effective market status
GET /tokens/{tokenId}/status computes one answer from the restrictions and the market:
SPECIAL_RESTRICTION is listed in activeRestrictions but does not make the token UNAVAILABLE on its own. The market’s reasons are not restriction reason codes; reason carries one vocabulary or the other depending on marketStatus.
GET /assets/{assetId}/status lists the ASSET and UNDERLYING_MARKET restrictions in force, without a market status. GET /tokens?status= filters tokens by marketStatus.
Resumption
A restriction ends only with an explicitca.restriction.removed for its restrictionId, even when expectedEnd was given. For underlying-market restrictions the resumption event follows the exchange’s and can arrive with a short delay: rely on your own market data for the moment of resumption and use the event for confirmation and audit.
Underlying-market restrictions are best effort in this version: Securitize publishes halts and suspensions when known to it, and short limit-up/limit-down pauses are not retransmitted. A market-wide halt arrives as one UNDERLYING_MARKET restriction per asset you hold, lifted together.