Skip to main content

Attribute Types

Every AttributeDefinition returned by meta.v1 carries an attributetype attribute whose value is one of the following.

List of Attribute Types​

Attribute TypeData TypeDescription
Booleanbooleantrue or false
Numericdoublefloating point number
Datedatetimedate and possibly time
Durationstringa string with syntax N UnitType where N is an integer and UnitType is Days, Weeks, or Months
Textstringstring limited to 4000 characters
LongTextstringstring limited by database. Often contains html or rich text
RelationOida relationship to another asset
RankRankAn arbitrary object that represents one rank object relative to another
AssetTypeAssetTypethe name or token of an asset type
OpaqueOpaqueAn internal value that has no external meaning.
StateintegerThe asset's lifecycle state. Rendered as a number by rest-1.v1 and by name everywhere else; see AssetState values.
PasswordstringA string that represents the password for a login. A password attribute type is write-only. It can never be retrieved.
BlobBlobA stream of binary data such as the content of an Attachment asset.

AssetState Values​

Every asset carries AssetState, a State attribute. The stored value is a byte; the named values are the meaningful points on it:

ValueNumberMeaning
Future0Not yet active (a story in a future timebox, a scope not started).
Active64In use.
Closed128Closed; for a List value, inactive.
Dead192Retired.
OldBrokenDownStory208A story that was broken down under the old breakdown model.
Deprecated254Deprecated.
Deleted255Deleted. Excluded from reads unless deleted=true (rest-1) or IsDeleted is queried.

The endpoints do not agree on how to render it. rest-1.v1 renders the number (<Attribute name="AssetState">128</Attribute>, "value": 128 in JSON); query.v1 and api/asset render the name ("AssetState": "Closed"). There is no way to ask rest-1 for the name: AssetState is a State, not a relation, so AssetState.Name and AssetState.Code are rejected (Unknown token), and a list value's RollupState (Status.RollupState) renders as a number too. What rest-1 does offer readably is the derived booleans IsClosed, IsDead, IsDeleted and IsInactive; otherwise map the number with the table above. A client that reads through more than one endpoint should normalise to the name once, at the edge, rather than compare a 128 from one call with a "Closed" from another.

Filters accept either spelling, and they are not plain comparisons. On every endpoint:

  • The value may be a name (case-insensitive) or a number that is one of the seven codes: AssetState='Closed', AssetState='closed' and AssetState='128' are the same filter. An unknown name is rejected (Invalid QueryFilter2 token), but a number that is not one of the codes is accepted and compared exactly: AssetState='200' finds templates.
  • Only = and != are allowed. AssetState<'Closed' is rejected (InequalityNotSupported), even though the value is a number underneath.
  • Equality on a name is a band, not a point: Future matches anything below 64, Active anything from 64 up to 128, Closed from 128 up to 192, Dead from 192 up to 255, and Deleted exactly 255. So AssetState='Dead' also matches an asset stored as 200 or 208. OldBrokenDownStory and Deprecated match their exact code.
  • != on a name means below the band's start, which is where the ordinary filters get their meaning: AssetState!='Closed' is "state < 128" (Future and Active only; it excludes Dead and Deleted too), AssetState!='Dead' is "state < 192" (everything not retired or deleted), AssetState!='Active' is "below 64 or 128 and above".
  • A list ORs the bands (AssetState='Active','Future'), and a negated list ANDs the negations.