Skip to content

OpenPrintTag format

What the station reads from a tag and what it writes to one. For which tags to buy, see Which tags work.

Tag profile

Property Value
Technology NFC-V (ISO 15693). Other NFC types are never detected.
Writable tag NXP ICODE SLIX2: UID starts E0:04, 80 blocks × 4 bytes
Memory used Bytes 0–311 (blocks 0–77), 312 bytes
Never written Blocks 78–79 (bytes 312–319) and the UID
Blank tag All 312 usable bytes are 0x00
Protected tag Refused if any of blocks 0–77 is locked, or the tag data declares write protection

A tag that is neither blank nor a valid OpenPrintTag is refused for writing and for clearing. The station does not overwrite data it cannot identify.

Messages for a refused tag:

Message Cause
Incompatible tag: this release approves NXP 80 x 4-byte SLIX2 only Wrong chip or memory size
Place exactly one stable NFC-V tag No tag, or more than one
Tag has protected blocks A block in 0–77 is locked
OpenPrintTag declares write protection The tag data marks itself read-only
Unsupported or incomplete OpenPrintTag; refusing unknown data overwrite Other data on the tag

Memory layout

The tag holds an NDEF message with one MIME record of type application/vnd.openprinttag. The record payload contains CBOR maps in three regions:

Region Content
Meta Offsets and sizes of the other regions
Main Material and package data that rarely changes
Auxiliary Data that changes during use, such as consumed weight

Fields are identified by integer keys.

Reader limits: tag image at most 4,096 bytes, each CBOR region at most 512 bytes, at most 128 map entries, nesting depth at most 12. A tag outside these limits is reported as invalid.

Fields the station writes

A full write builds a new 312-byte image from the Spoolman spool. The mapping lives in spoolman_mapping.cpp.

Region, key Tag field Source in Spoolman Rule
Main 0 Instance UUID (16 bytes) With the extra fields: the spool's opentag_instance_uuid, else the tag's current UUID if the spool's nfc_uid already names this tag. Without them: the tag's current UUID if Spoolman's tag list already links this tag to the target spool. Otherwise a new random UUID. Always written
Main 8 Material class Fixed: FFF filament Always written
Main 9 Material type Filament material Only if exactly PLA, PETG, TPU, ABS, ASA, PC, PCTG, PP, PA6, PA11 or PA12
Main 10 Material name Filament name At most 63 bytes
Main 11 Brand Vendor name At most 31 bytes
Main 52 Material abbreviation Filament material At most 7 bytes
Main 6 Brand-specific ID Filament article_number At most 16 bytes
Main 16 Nominal weight (g) Filament weight
Main 17 Actual initial weight (g) Spool initial_weight
Main 18 Empty spool weight (g) Spool spool_weight, else filament spool_weight, else vendor empty_spool_weight A value of 0 does not hide a greater value further down; it is written only when no source has a weight above 0
Main 29 Density Filament density
Main 61 Diameter (µm) Filament diameter × 1000 Must be a whole number of micrometres, at most 65,535
Main 19 Colour Filament color_hex 6 or 8 hex digits
Auxiliary 0 Consumed weight (g) Spool used_weight Required

Rules that apply to every row:

  • A missing Spoolman value is left out. A real zero is written as zero.
  • Text longer than its limit, or empty, is left out. It is never shortened. The write preview reports each value that will be left out (name, vendor, material, material type, article number, or the colour of a multi-colour filament) in dropped_fields; see the Tag writer API.
  • Numbers must be finite and not negative.
  • Archived spools are refused: Canonical active Spoolman spool required.

Errors that stop a write before any byte changes:

Message Cause
Canonical used_weight is missing or invalid Spool has no valid used_weight
Spoolman diameter is not representable in integer micrometres Diameter is not a whole number of µm
Canonical filament color is malformed color_hex is not 6 or 8 hex digits
Canonical metadata does not fit this tag; no bytes written The encoded values need more space than the tag has
Spoolman has an unusable <field> value (wrong type or negative); correct it in Spoolman. No bytes written A numeric field is negative, not finite or not a number, or a text field is not a string. <field> names it: filament name, vendor name, filament material, article number, filament weight, initial weight, spool weight or filament density

Not written: print and bed temperatures, price, location, lot number, comment. These stay in Spoolman.

Consumed-weight update

Update consumed weight in the browser writer changes only the consumed weight in the auxiliary region. The main region stays byte for byte the same. It needs a tag that already carries the same spool's instance UUID and an auxiliary region.

How a write is carried out

  1. The whole tag is read twice. Both reads must match.
  2. Only blocks that differ from the new image are written. Each block is read back and compared right after it is written.
  3. The blocks holding the instance UUID are written second to last and block 0 last.
  4. The whole tag is read again, compared with the new image and decoded.
  5. The station stores the tag UID and instance UUID on the spool in Spoolman.

Clearing writes zeros to every non-zero block in 0–77, block 0 last, then checks that all 312 bytes read back as zero.

One physical write or clear may take at most 120 seconds. Saving a weight to Spoolman never writes to the tag.

Fields the station reads

The reader decodes the main and auxiliary fields of the pinned specification revision and ignores keys it does not know. Filament diameter is read from key 61 (µm) and from the older key 30 (mm); if both are present they must agree.

Two places in Spoolman tie a tag to a spool. The Spool extra fields are required on Spoolman < 0.27 and optional on 0.27+; the tag list exists only on 0.27+. Both are kept when both exist. See Required extra fields and Native tag list.

Where Content
Spool extra field opentag_instance_uuid (default key) The UUID written to main key 0
Spool extra field nfc_uid (default key) The tag's UID
Spool tag list (Spoolman 0.27+) The tag's UID, format openprinttag

Specification revisions

Use Pinned commit
Reader field definitions e0dab1ae16838d2c342e7cfc509455441b7d8eba
Writer and blank-image layout 7e09cc38df1c8e7824a67f5b1ae93071f52519ad

CI checks out the writer revision from https://github.com/OpenPrintTag/openprinttag-specification and compares the station's images with the upstream tools.

Not supported

  • Tags other than NXP ICODE SLIX2, and any tag memory size other than 80 × 4 bytes, for writing.
  • NFC-A tags (NTAG, MIFARE). The reader does not see them.
  • Erasing tags that carry other data, such as a URL written by a phone.
  • Locking, password protection or privacy mode.
  • Writing raw blocks. The API accepts only a reviewed write or clear of the tag on the reader.