Skip to content
Inkoxide

Search covers every page and heading of the docs. Use ↑ ↓ and ↵.

Schema reference

Every node, style key and value of document schema version 1.

Edit this page

Conventions

  • Units. Every length is in PDF points (1/72 in). Percentages ("50%") are allowed only where the type says Length or LengthPercent; they resolve against the containing block (width for padding and horizontal properties, as in CSS). Gaps resolve against the box's own content box, and a percentage height needs a containing block with a set height: the page content box, for a child of the page.
  • Numbers. An integer may be written with a zero fraction (400.0), as JSON Schema reads it. Other numbers are read as 32-bit floats, so a number past a bound by less than a float's precision there is read as the bound and accepted (1000000.01 where the maximum is 1000000). Percentages and fr sizes are bounded as written: "10000.0001%" is out of range.
  • Colours. [r, g, b, a] floats in [0, 1], DeviceRGB.
  • Strictness. Unknown properties are errors (UNKNOWN_FIELD), as are properties on the wrong node type (e.g. runs on a box) and text-only style properties on non-text nodes (STYLE_NOT_APPLICABLE).
  • Resolved input. Nothing is inherited: every text run carries its own font, size and colour.
  • Defaults follow CSS flexbox except flexDirection, which defaults to column (document flow is vertical).
  • Header/footer. Laid out at the full page width: once, or again on every page when it shows page numbers. The header is painted at the top of every physical page (y = 0), the footer with its bottom edge on the bottom of the page. Use their padding to inset them and size the page margins so the flow does not overlap them.
  • Placeholders. A run with placeholder: "pageNumber" | "totalPages" is filled in after pagination, and the text wraps and aligns at the width of the digits. A header, a footer or an overlay is laid out with each page's numbers. Flow text is laid out with the numbers of the page it lands on, and the flow is paginated again if they move it. Flow text painted on several pages (in a fixed node or a table's header rows) reserves the width of 999 in the run's font for each page's digits; a longer number can overflow that space.
  • Images. Intrinsic size is the pixel size at 96 dpi (1 px = 0.75 pt), like CSS. An image with no width and no height that is wider than the room it has is scaled down to fit it, keeping its aspect ratio (CSS would let it overflow). fit defaults to fill, like CSS object-fit, and objectPosition places a fitted image in its box like object-position (centred by default; what falls outside the box is clipped).

Validation error codes

CodeMeaning
PARSE_ERRORInput is not well-formed JSON or MessagePack
UNSUPPORTED_VERSIONversion is not 1
UNKNOWN_FIELDProperty not allowed at this position
MISSING_FIELDRequired property missing
INVALID_TYPEWrong JSON type
INVALID_VALUEValue not in the allowed set / wrong format; a string too short or too long; an array with more items than its fixed length; break where pagination does not apply (headers, footers, table cells, fixed overlays), or a forced break where it would do nothing (see Break.before)
OUT_OF_RANGENumber outside its allowed range; page margins that leave no room for content
DUPLICATE_IDFont id declared twice, or form field name used twice (except by the buttons of one radio group), or used both for a field and for a group of fields (a and a.b)
UNKNOWN_FONTFont id not declared in fonts
FONT_NOT_REGISTEREDDeclared font has no registered bytes
UNKNOWN_IMAGEImage src not provided in the render options
INVALID_IMAGEImage data cannot be decoded (a JPEG is not decoded: its structure is checked)
IMAGE_TOO_LARGERaster image (not SVG) over 50 megapixels (width × height). An SVG has its own limit: a width or height over 100,000 px is INVALID_IMAGE
STYLE_NOT_APPLICABLEStyle property set on a node type it does not apply to
INVALID_TABLEInconsistent table structure (spans, columns, header rows)
INVALID_NODENode type not allowed here (e.g. pageBreak in a header)
UNKNOWN_ANCHORA #id link names no displayed node id in the page body, flow or overlays (ids in headers, footers and under display: none are not destinations)
PDFA_CONFLICTThe document uses something the PDF/A level does not allow: at any level, a page side under 3 points (at the page's size); under PDF/A-1b, transparency (a colour with alpha below 1, opacity below 1, debug, an image, inline image, emoji image or background image with an alpha channel, an SVG drawn with opacity, a mask, a blend mode, an isolated group or a clip path other than one path, or a colour glyph that needs transparency: a bitmap with an alpha channel or a layer with an opacity). Only a render reports it, at the first such use

Each error is { "code", "path", "message" }, with path like pages[0].children[3].runs[1].font. Validation returns at most 100 errors. A problem found while reading the document's structure (input that does not parse, an unknown or missing property, a wrong type, a value the reader rejects) is returned alone, as the rest cannot be checked.

Document (top level)

A fully resolved, declarative document tree rendered to PDF by the Inkoxide engine. All lengths are PDF points (1/72 in); all colours are RGBA floats in [0, 1]. Unknown properties are errors.

PropertyTypeRequiredNotes
version1yes
metaMeta
fontsarray of FontDeclFonts the document references. Bytes are registered through the API (registerFont / options); this list lets validation fail early.
fallbackFontsarray of Idmax items 256; Font ids tried, in order, for characters missing from a run's font. Every id must be declared in fonts; an id listed again is skipped.
emojiImagesobjectmax properties 4096; Emoji drawn as images: each key is one emoji sequence (😀, 👍🏽, 🇫🇷, 👩‍💻; U+FE0F is ignored) of at most 64 bytes in UTF-8, each value the id of an image in the render option images. Where text has the sequence with emoji presentation, the image is drawn in its place, 1em high (the run's size), its bottom 0.1em below the run's baseline (which its verticalAlign raises or lowers), and the sequence is its text for copying and search. A ZWJ sequence without an image tries its parts.
pagesarray of PageSpecyesmin items 1

Definitions

Id

Type: string (min length 1, max length 256)

Link target. #id jumps to the top of the first node with that id in the page body (the flow or an overlay): a node in a header or footer, or hidden by display: none, is not a destination (UNKNOWN_ANCHOR if there is none). Anything else must be an absolute URI with a scheme (https:, mailto:, …) and opens in the viewer. javascript: is rejected.

Type: string (min length 1, max length 2048)

Bookmark

Document outline entry pointing at the top of its node. Entries appear in document order; an entry nests under the nearest earlier entry with a lower level. Flowing content only (not headers or footers).

PropertyTypeRequiredNotes
titlestringyesmin length 1, max length 1024
levelinteger≥ 1, ≤ 32, default 1

Debug

A development aid: draws the element's boxes on top of the page, its margin (orange), border (yellow) and padding (green) as light fills and its content box as a blue outline, with its border-box size in points as a small label. On a text node it also outlines each line: its line box (dashed), its baseline, and the glyphs of each run on it, from the run font's ascender to its descender. The label is drawn with lines, so no text is added to the document. A box split across pages is drawn on each page it crosses. It changes the output: leave it off in production.

Type: boolean (default false)

Meta

PropertyTypeRequiredNotes
titlestring
authorstring
subjectstring
keywordsstring
creatorstring
producerstringThe PDF producer, written to the PDF Info dictionary (and to the XMP metadata of PDF/A). Default Inkoxide <version>.
langstringBCP-47 language tag of the document, e.g. "en" or "en-GB".
creationDatestringformat date-time; RFC 3339 timestamp written to the PDF Info dictionary. Overridden by the creationDate render option. When neither is set, no date is written (output stays deterministic).
pageMode"useNone" | "useOutlines" | "useThumbs" | "fullScreen"What the viewer shows when it opens the document: no panel (useNone), the bookmarks (useOutlines), page thumbnails (useThumbs) or the pages full screen (fullScreen). Default: useOutlines when the document has bookmarks, else useNone.
pageLayout"singlePage" | "oneColumn" | "twoColumnLeft" | "twoColumnRight" | "twoPageLeft" | "twoPageRight"How the viewer lays out the pages: one at a time (singlePage), one scrolling column (oneColumn), two scrolling columns with odd pages on the left or right (twoColumnLeft, twoColumnRight), or two pages at a time with odd pages on the left or right (twoPageLeft, twoPageRight). Default: the viewer's own setting.

FontDecl

PropertyTypeRequiredNotes
idIdyes
familystringyesmin length 1; The family name. Text runs name fonts by id; text in SVG images is matched to the declared fonts by its font-family against this (ignoring ASCII case), then weight and style, as CSS matches fonts.
weightinteger≥ 1, ≤ 1000, default 400; The weight SVG text's font-weight is matched against.
style"normal" | "italic"default "normal"; The style SVG text's font-style is matched against.

NonNegative

A non-negative number of at most 1000000.

Type: number (≥ 0, ≤ 1000000)

Percent

A percentage within ±10000%, like "50%".

Type: string matching ^-?0*([0-9]{1,4}(\.[0-9]+)?|10000(\.0+)?)%$

NonNegativePercent

A percentage within [0%, 10000%], like "50%".

Type: string matching ^(0*([0-9]{1,4}(\.[0-9]+)?|10000(\.0+)?)|-0+(\.0+)?)%$

Fr

A flexible size, a share of the free space, of at most 1000000fr, like "1fr".

Type: string matching ^0*([0-9]{1,6}(\.[0-9]+)?|1000000(\.0+)?)fr$

Length

Points (within ±1000000), a percentage of the containing block (within ±10000%), or "auto". A percentage height needs a containing block with a definite height, as in CSS: a child of the page takes it of the page content height; in a header or footer, or in a box whose height is not set, it is auto.

Type: number (≥ -1000000, ≤ 1000000) or Percent or "auto"

LengthPercent

Points (within ±1000000) or a percentage of the containing block's width (within ±10000%). In gap, rowGap and columnGap, a percentage is of the box's own content box instead, as in CSS: a column gap of its width, a row gap of its height.

Type: number (≥ -1000000, ≤ 1000000) or Percent

NonNegativeLength

A Length that is not negative: points (at most 1000000), a percentage of the containing block (at most 10000%), or "auto". A percentage height needs a containing block with a definite height, as for Length.

Type: number (≥ 0, ≤ 1000000) or NonNegativePercent or "auto"

NonNegativeLengthPercent

A LengthPercent that is not negative: points (at most 1000000) or a percentage (at most 10000%), of what LengthPercent says.

Type: number (≥ 0, ≤ 1000000) or NonNegativePercent

Color

[r, g, b, a], each in [0, 1].

Type: array of number (each ≥ 0, ≤ 1) (exactly 4 items)

Size

Page size in points. PDF/A, at any level, takes sides of 3 points or more: a render of a smaller page as PDF/A fails with PDFA_CONFLICT at the page's size.

PropertyTypeRequiredNotes
widthnumberyes> 0, ≤ 14400
heightnumberyes> 0, ≤ 14400

EdgesNumber

PropertyTypeRequiredNotes
topNonNegative
rightNonNegative
bottomNonNegative
leftNonNegative

EdgesLengthPercent

Padding: a NonNegativeLengthPercent per side.

EdgesLength

PropertyTypeRequiredNotes
topLength
rightLength
bottomLength
leftLength

EdgesColor

PropertyTypeRequiredNotes
topColor
rightColor
bottomColor
leftColor

PageSpec

A page template. Its content flows across as many physical pages as needed.

PropertyTypeRequiredNotes
sizeSizeyes
marginEdgesNumberleft + right must be less than the page width and top + bottom less than its height; margins that leave no room for content are OUT_OF_RANGE at margin.
backgroundColorFills the whole page behind its content. The fill is opaque: the alpha of the colour is ignored, so [1, 0, 0, 0] paints solid red.
debugDebugDraws the boxes of the page (its margins and content area) and of every element on it, the header and footer included.
headerNodeLaid out at the full page width, once, or again on every page when it shows page numbers, and painted at the top of every physical page (y = 0). Use padding to inset it. Size the top margin to leave room for it. break (other than its defaults) and pageBreak are not allowed in it, at any depth.
footerNodeLaid out at the full page width, once, or again on every page when it shows page numbers, and painted with its bottom edge on the bottom of every physical page. break (other than its defaults) and pageBreak are not allowed in it, at any depth.
childrenarray of Node

Break

Pagination controls. They apply to flowing content only: on a header or footer, on a node in a table cell, or on any node inside these, a break with a value other than the defaults is INVALID_VALUE. For fixed overlays, see fixed. A box laid out as a row, a grid, wrapping or reversed moves to the next page whole when it fits on one; taller than a page, it splits between its rows (children whose extents overlap), each child continuing from the row's top. Content that cannot split (an image, an absolutely positioned, rotated, transformed or fixed node, table rows tied by a row span) is cut across pages when it is taller than a page.

PropertyTypeRequiredNotes
before"auto" | "page"default "auto"; page starts a new page before the node, unless it is at the top of one already. INVALID_VALUE inside a row, grid, wrapping or reversed box, or inside an absolutely positioned, rotated, transformed, floated or fixed node, or on an absolutely positioned or floated node: there it would do nothing.
after"auto" | "page"default "auto"; page starts a new page after the node when in-flow content follows it: a break at the end of the flow adds no page. Allowed where before is.
inside"auto" | "avoid"default "auto"; avoid keeps the node on one page: it moves to the next page whole when it does not fit. A node taller than a page splits anyway, and a forced page break inside it still starts a new page; the part before the break moves whole.
minPresenceAheadNonNegativePoints of room the node needs from its top: when less is left on the page than this (or than its first unbreakable piece, when taller), the node moves to the next page. The node's own height counts, and nothing needs to follow it. On a box's first in-flow child it applies to the box too, so a box never leaves its top padding behind. break.before: "page" on a first child moves the box the same way.
fixedbooleandefault false; Paint the node on every page of its flow. A child of the page with position: "absolute" is laid out on its own, against the page content box (inset and percentages are relative to one page's content box, inside the margins), takes no space and is painted over the flow, or under it when its zIndex is negative; no other pagination control applies to it or inside it, and it cannot hold a pageBreak. Any other fixed node is laid out in the flow, takes its space there once, and is painted at the same place on every page.

GridPlacement

1-based CSS grid line placement. Negative lines count from the end; there is no line 0. Use span alone, with start or with end. With both start and end, span is ignored.

PropertyTypeRequiredNotes
startinteger≥ -32767, ≤ 32767, ≠ 0
endinteger≥ -32767, ≤ 32767, ≠ 0
spaninteger≥ 1, ≤ 65535

TrackSize

Grid track: a breadth, {min, max} (CSS minmax(); min cannot be fr) or {fitContent} (CSS fit-content()).

Type: TrackBreadth or {min, max} (min: TrackBreadth; max: TrackBreadth) or {fitContent} (fitContent: NonNegativeLengthPercent)

BorderRadius

One radius for every corner, or one per corner (a missing corner is square). Radii that would overlap are scaled down together, as in CSS.

Type: NonNegative or object with topLeft, topRight, bottomRight, bottomLeft

BorderStyles

One style for every side, or one per side (an unset side is solid).

Type: "solid" | "dashed" | "dotted" or object with top, right, bottom, left

TransformOp

One transform function, as an object with exactly one key. Lengths are points or percentages of the node's own border box; angles are degrees, clockwise. Scale factors, rotate and matrix entries are within ±1000000; skew angles are within (−90, 90).

Type: {translate} (translate: array of LengthPercent (exactly 2 items)) or {scale} (scale: array of number (each ≥ -1000000, ≤ 1000000) (exactly 2 items)) or {rotate} (rotate: number (≥ -1000000, ≤ 1000000)) or {skew} (skew: array of number (each > -90, < 90) (exactly 2 items)) or {matrix} (matrix: array of number (each ≥ -1000000, ≤ 1000000) (exactly 6 items))

Style

PropertyTypeRequiredNotes
display"flex" | "grid" | "none"default "flex"
flexDirection"row" | "column" | "row-reverse" | "column-reverse"default "column"
flexWrap"nowrap" | "wrap" | "wrap-reverse"default "nowrap"
justifyContent"flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "start" | "end" | "stretch"
alignItems"flex-start" | "flex-end" | "center" | "baseline" | "stretch" | "start" | "end"
alignSelf"auto" | "flex-start" | "flex-end" | "center" | "baseline" | "stretch" | "start" | "end"
alignContent"flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | "start" | "end"
flexGrowNonNegative
flexShrinkNonNegative
flexBasisNonNegativeLength
gapNonNegativeLengthPercentSets both rowGap and columnGap; either of those, when present, wins.
rowGapNonNegativeLengthPercentA percentage is of the box's own content height, as in CSS. In a box whose height is not set, it is of the height of the content without the gaps, so it adds little: use points.
columnGapNonNegativeLengthPercent
widthNonNegativeLength
heightNonNegativeLength
minWidthNonNegativeLength
minHeightNonNegativeLength
maxWidthNonNegativeLength
maxHeightNonNegativeLength
aspectRationumber≥ 0.000001, ≤ 1000000; Width divided by height.
paddingEdgesLengthPercent
marginEdgesLength
position"relative" | "absolute"default "relative"
insetEdgesLengthtop/right/bottom/left offsets for positioned boxes. A relative box (the default position) is moved by them before pagination, so pagination sees it where it is drawn: moved past the foot of a page, it moves to the next page or runs onto it.
gridTemplateColumnsarray of TemplateTrack
gridTemplateRowsarray of TemplateTrack
gridTemplateAreasarray of stringmin items 1; Rows of whitespace-separated area names, as in CSS; a token of dots is an unnamed cell. Every row has the same number of cells and each area is a rectangle. At most 10000 cells (rows × columns; OUT_OF_RANGE).
gridAutoColumnsarray of TrackSize
gridAutoRowsarray of TrackSize
gridAutoFlow"row" | "column" | "row dense" | "column dense"
gridColumnGridPlacement
gridRowGridPlacement
gridAreastringmin length 1; Name of an area in the parent's gridTemplateAreas; replaces gridRow and gridColumn, and cannot be combined with them (INVALID_VALUE).
justifyItems"flex-start" | "flex-end" | "center" | "baseline" | "stretch" | "start" | "end"Grid only: default inline-axis alignment of the items.
justifySelf"auto" | "flex-start" | "flex-end" | "center" | "baseline" | "stretch" | "start" | "end"Grid only: inline-axis alignment of this item.
overflow"visible" | "hidden"default "visible"
float"left" | "right" | "none"default "none"; Children of a column box (not of a row, grid, wrapping or reversed box, and not a table cell itself) only; not with position: absolute. Floats the node to that side of its parent's content box, shrink-to-fit, at or below where it occurs, as CSS floats rectangles: lines of text after it wrap beside it, and boxes after it are narrowed to the room beside it, or move below it when their min-content width does not fit there. The parent's height includes its floats. Its children take no flexGrow or flexBasis, and it takes no justifyContent or alignContent. At most 1000 floated children per box. A float forces no page break: break.before or break.after "page" on it, or on a node inside it, and a pageBreak node inside it, are rejected. A float moves to the next page with the lines beside it, and is sliced when taller than a page.
clear"left" | "right" | "both" | "none"default "none"; Puts the node's border box below the margin boxes of the earlier floats of its parent on these sides.
backgroundColorColor
opacitynumber≥ 0, ≤ 1; Multiplies the alpha of what the node paints and of everything inside it, element by element: unlike CSS, it does not fade the node and its children as one group, so overlapping children show through each other. 0 draws nothing for the node's children and leaves out the links, form fields and notes inside them.
borderWidthEdgesNumber
borderColorEdgesColor
borderRadiusBorderRadius
borderStyleBorderStylesdefault "solid"
rotatenumber≥ -1000000, ≤ 1000000; Degrees, clockwise, around the box centre.
transformarray of TransformOpTransform functions, as in CSS: the list applies right to left, after rotate. Not on table cells. A transformed node moves to the next page as a whole.
transformOriginarray of LengthPercentexactly 2 items; x and y of the origin of rotate and transform within the border box. Default ["50%", "50%"]. Not on table cells.
zIndexinteger≥ -2147483648, ≤ 2147483647; Paint order among siblings: higher paints later (above); equal values keep document order. Default 0. Not on table cells.
textAlign"left" | "center" | "right" | "justify" | "start" | "end"text nodes only; start/end follow the paragraph direction. Default start.
lineHeightnumber> 0, ≤ 100; text nodes only; multiplier of the largest run size on the line
maxLinesinteger≥ 1, ≤ 4294967295; text nodes only
ellipsisbooleantext nodes only; requires maxLines
hyphenatebooleantext nodes only. Hyphenates the words in the language of the node (lang, or meta.lang); with no language, nothing is hyphenated and the render logs a warning. A word wider than its line breaks between any two characters, hyphenated or not.
langstringtext nodes only; BCP-47, selects hyphenation patterns
whiteSpace"normal" | "pre" | "nowrap" | "pre-wrap" | "pre-line"text nodes only. normal collapses spaces and keeps newlines as breaks (as pre-line); pre-wrap keeps spaces and tabs and wraps. As in CSS, only spaces, tabs and line breaks collapse: other space characters (thin, em, figure, no-break, …) keep their width, and only the breaking ones are break opportunities. pre and pre-wrap advance a tab to the next tab stop (CSS tab-size: 8): stops are 8 spaces of the tab's font apart, from the start of the line (a line pre-wrap wraps keeps the stops of the line it continues), and a tab narrower than half a 0 goes on to the next stop.
textWrap"wrap" | "pretty"default "wrap"; text nodes only. How lines break: wrap fills each line in turn (first fit); pretty chooses the breaks over each stretch of the paragraph between forced breaks to make its lines even (Knuth and Plass's total fit, as TeX), with fewer hyphens, and lets the spaces of justified lines shrink by up to a third. A stretch with more than 20 000 break opportunities, or past 512 open breakpoints or 2 097 152 lines tried in the paragraph, falls back to wrap, as do pre and nowrap text, justified text without spaces, and a word wider than its line. balance is reserved.
textIndentnumber≥ -10000, ≤ 10000; text nodes only; indent of the first line in points (negative: hanging indent)
direction"ltr" | "rtl" | "auto"default "ltr"; text nodes only; base direction of the paragraph (auto: from its first strong character). Right-to-left runs are reordered with the Unicode bidi algorithm in any direction.
orphansinteger≥ 1, ≤ 100, default 1; text nodes only; minimum number of lines left at the bottom of a page when the paragraph breaks
widowsinteger≥ 1, ≤ 100, default 1; text nodes only; minimum number of lines carried to the top of the next page when the paragraph breaks
verticalAlign"top" | "middle" | "bottom"table cells only
borderCollapse"collapse" | "separate"default "collapse"; Tables only. collapse: adjacent cell borders merge into one, drawn in the winner's style and colour: the wider wins, and at equal widths solid wins over dashed and dashed over dotted. separate: every cell draws its own borders, background and borderRadius, borderSpacing apart.
borderSpacingNonNegativeTables with borderCollapse: separate only: space between cells and around them, in points. Default 0.

TextRun

PropertyTypeRequiredNotes
textstringRequired unless placeholder, image or note is set; forbidden when one is.
fontIdyes
sizenumberyes> 0, ≤ 1000
colorColor
letterSpacingnumber≥ -1000, ≤ 1000
decoration"none" | "underline" | "lineThrough"
decorationColorColorDefault: the run colour.
decorationThicknessnumber> 0, ≤ 100; Points. Default: from the font.
decorationStyle"solid" | "double" | "dotted" | "dashed" | "wavy"default "solid"
placeholder"pageNumber" | "totalPages"
linkLinkMakes the run a link; the clickable area covers the run's glyphs on each line.
hyphenatebooleanOverrides the text node's hyphenate for this run's words, in the node's language.
verticalAlign"baseline" | "super" | "sub" | "middle" | "textTop" | "textBottom" | "top" | "bottom" or number (≥ -14400, ≤ 14400)default "baseline"; Moves the run's baseline: super raises it and sub lowers it, by the offsets the font gives for superscripts and subscripts (OS/2), for text of the run's size. The size stays the run's own: give a superscript a smaller size. The line grows to fit the moved glyphs. An image run also takes middle (its middle at the baseline plus half the x-height of the run's font), textTop and textBottom (its top at the font's ascender, its bottom at its descender), top and bottom (its top or bottom at the line's), and a number: points its bottom sits above the baseline (negative: below).
fontFeaturesobjectmax properties 32; OpenType features by tag, as CSS font-feature-settings: 1 turns a feature on, 0 off, and a larger number picks an alternate ({"tnum": 1, "liga": 0}). Tags are four printable ASCII characters, and a value is 0 to 65535. A run may have at most 32 features, and a document at most 64 different sets of features.
imageInlineImage
noteNoteA note in the line, in place of text: it takes no room, and its icon (20 pt square, the same at any zoom) hangs from the top of the line where the run is, on the page where the line starts. The run's font and size are the line's strut. Line breaking keeps it with the character before it, or after a space, the one after it.

InlineImage

An image in a line of text, as wide as width and as high as height, in points. With one of them, the other follows the image's aspect ratio; with neither, it is as high as the run's size (1em). The run's font and size still set the line's strut, and its verticalAlign places the image.

PropertyTypeRequiredNotes
srcIdKey into the render option images.
datastringInline image bytes (JPEG, PNG, GIF, WebP or SVG; the first frame of an animation), base64-encoded; a data:<mime>;base64, URL is also accepted.
widthnumber> 0, ≤ 14400
heightnumber> 0, ≤ 14400
fit"fill" | "contain" | "cover" | "none"default "fill"
objectPositionObjectPositionWhere the image sits in its box with fit contain, cover or none (CSS object-position); fill ignores it. Default centred.
altstringmax length 1024; Alternative text: what copying, searching and screen readers get for the image.

ColumnSpec

PropertyTypeRequiredNotes
widthnumber (> 0, ≤ 1000000) or Fr (not matching ^0+(\.0+)?fr$) or "auto"yes

TableCell

PropertyTypeRequiredNotes
idId
debugDebug
colSpaninteger≥ 1, ≤ 4294967295, default 1
rowSpaninteger≥ 1, ≤ 4294967295, default 1
styleStyleThe table places and sizes the cell: its columns set the width, and height and minHeight are minimums (the row grows to fit the content). The cell's own placement, size and effects are STYLE_NOT_APPLICABLE: width, minWidth, maxWidth, maxHeight, margin, position, inset, alignSelf, justifySelf, flexGrow, flexShrink, flexBasis, gridRow, gridColumn, gridArea, overflow, opacity, rotate, transform, transformOrigin, zIndex, float and clear.
childrenarray of Node

TableRow

PropertyTypeRequiredNotes
idId
debugDebug
minHeightNonNegative
backgroundColorColor
cellsarray of TableCellyes

Node

PropertyTypeRequiredNotes
type"box" | "text" | "image" | "table" | "pageBreak" | "spacer" | "field" | "note"yes

BoxNode

PropertyTypeRequiredNotes
type"box"yes
idId
styleStyle
breakBreak
linkLink
bookmarkBookmark
pagesPageFilter
debugDebug
childrenarray of Node
backgroundImageBackgroundImage

TextNode

PropertyTypeRequiredNotes
type"text"yes
idId
styleStyle
breakBreak
linkLink
bookmarkBookmark
pagesPageFilter
debugDebug
runsarray of TextRunyes

ImageNode

PropertyTypeRequiredNotes
type"image"yes
idId
styleStyle
breakBreak
linkLink
bookmarkBookmark
pagesPageFilter
debugDebug
srcIdKey into the render option images.
datastringInline image bytes (JPEG, PNG, GIF, WebP or SVG; the first frame of an animation), base64-encoded; a data:<mime>;base64, URL is also accepted.
fit"fill" | "contain" | "cover" | "none"default "fill"
objectPositionObjectPositionWhere the image sits in its box with fit contain, cover or none (CSS object-position); fill ignores it. Default centred.

ObjectPosition

Position of a fitted image in its box, per axis: a keyword, points from the left or top edge, or a percentage (that point of the image goes to that point of the box: "0%" is the start edge, "100%" the end edge). Points are within ±14400 and percentages within ±10000%. What falls outside the box is clipped.

PropertyTypeRequiredNotes
x"left" | "center" | "right" or number (≥ -14400, ≤ 14400) or Percentdefault "center"
y"top" | "center" | "bottom" or number (≥ -14400, ≤ 14400) or Percentdefault "center"

BackgroundImage

An image painted behind the box's children and over its backgroundColor, under its borders. It fills the padding box (inside the borders), placed by fit and objectPosition, and is clipped to that box, rounded by borderRadius. A box split across pages is sliced, like its background colour.

PropertyTypeRequiredNotes
srcIdKey into the render option images.
datastringInline image bytes (JPEG, PNG, GIF, WebP or SVG; the first frame of an animation), base64-encoded; a data:<mime>;base64, URL is also accepted.
fit"fill" | "contain" | "cover" | "none"default "fill"
objectPositionObjectPositionWhere the image sits in the padding box with fit contain, cover or none (CSS object-position); fill ignores it. Default centred.

TableNode

PropertyTypeRequiredNotes
type"table"yes
idId
styleStyle
breakBreak
linkLink
bookmarkBookmark
pagesPageFilter
debugDebug
columnsarray of ColumnSpecyesmin items 1
headerRowsinteger≥ 0, ≤ 4294967295, default 0
rowsarray of TableRowyes

PageBreakNode

Starts a new page when in-flow content follows it: at the end of the flow it adds no page. Flowing content only: in a header, a footer, a table cell or a fixed overlay, and inside a row, grid, wrapping or reversed box, or inside an absolutely positioned, rotated, transformed, floated or fixed node, it is INVALID_NODE.

PropertyTypeRequiredNotes
type"pageBreak"yes
idId

SpacerNode

PropertyTypeRequiredNotes
type"spacer"yes
idId
styleStyle
breakBreak
linkLink
bookmarkBookmark
pagesPageFilter
debugDebug

FieldNode

An interactive AcroForm field. style sizes and decorates its box (background, border, padding); the widget covers the content box. Without a width or height it takes an intrinsic size (text and select: 150 pt wide, one line, or three when multiline; list: 150 pt wide, one row per option up to four; checkbox and radio: size + 2 pt square).

PropertyTypeRequiredNotes
type"field"yes
idId
styleStyle
breakBreak
pagesPageFilter
debugDebug
fieldFieldyes

Field

Fields with the same name are one field with several widgets (for example a field in a header, repeated on every page); only radio buttons may share a name with different values.

PropertyTypeRequiredNotes
namestring matching ^[^.]{1,128}(\.[^.]{1,128}){0,31}$yesmin length 1, max length 512; Field name; unique in the document except for the buttons of one radio group. Dots make groups: address.street is the field street in the group address, as in PDF's own field names. At most 32 parts of 1 to 128 characters, and 512 characters in all. A name used again, or used both for a field and for a group (a and a.b), is DUPLICATE_ID.
kind"text" | "checkbox" | "radio" | "select" | "list"yesselect is a drop-down list, list a list box that shows several options at once
valuestring (max length 8000) or array of string (each max length 1000) (max items 1000)text: the initial text, at most maxLength characters (OUT_OF_RANGE); select and list: the selected option (one of options), or for a list with multiSelect an array of them, each at most once; radio: the value this button exports when selected, required and non-empty (MISSING_FIELD). A string is at most 8000 characters.
checkedbooleandefault false; checkbox and radio: initially selected; at most one button of a radio group (INVALID_VALUE), and buttons of the group with the same value are selected together
optionsarray of string (each max length 1000)min items 1, max items 1000; select and list only (required there): the choices, at most 1000 of at most 1000 characters each
multiSelectbooleandefault false; list only: several options can be selected at once
multilinebooleandefault false; text only
passwordbooleandefault false; text only; the value is neither shown nor stored
maxLengthinteger≥ 1, ≤ 4294967295; text only; maximum number of characters
readOnlybooleandefault false
requiredbooleandefault false
fontIdtext, select and list (required there): a declared font for the value, with outlines (a font with colour bitmaps only is INVALID_VALUE). Its glyphs for the common Latin range are embedded so edits display. The value and the options are drawn with this font only, a glyph per character: no fallback fonts, no shaping and no right-to-left ordering, as viewers redraw them. A character the font has no glyph for is INVALID_VALUE at the value or the option.
sizenumber> 0, ≤ 1000, default 10; font size; also the mark size of checkboxes and radio buttons
colorColortext and mark colour; default black
formatFieldFormat

FieldFormat

Single-line, non-password text fields only: how the field shows and takes its value. The field shows value formatted; viewers format what the user types with the standard form scripts (AFNumber_Format and the like), which PDF/A leaves out (the formatted text and value stay). value must fit the format (INVALID_VALUE): a number or percent is -?digits[.digits] (at most 15 digits on each side; a percent is a fraction, 0.125 shows 12.50%), a date YYYY-MM-DD with an optional THH:MM[:SS], a time HH:MM[:SS] or a date with a time, zip 5 digits, zipPlus4 9, phone 10 and ssn 9. A key that does not apply to the type is INVALID_VALUE.

PropertyTypeRequiredNotes
type"number" | "percent" | "date" | "time" | "zip" | "zipPlus4" | "phone" | "ssn"yes
decimalsinteger≥ 0, ≤ 10; number and percent: digits after the decimal separator, rounded half away from zero; default 2
separators"1,234.56" | "1234.56" | "1.234,56" | "1234,56"number and percent: the thousands and decimal separators, by example; default 1,234.56
negative"minus" | "red" | "parens" | "parensRed"number: how a negative number shows: -1.00, 1.00 in red, (1.00) or (1.00) in red; default minus
currencystring matching ^[^\u0000-\u001f\u007f-\u009f"'\\\u2028\u2029]*$max length 8; number: a currency symbol, shown as it is (add a space to separate it); no control characters, quotes or backslashes
currencyBeforebooleandefault true; number: the currency goes before the number
patternstringmin length 1, max length 64; date and time (required there): how the value shows, with d, dd, ddd (Mon), dddd (Monday), m, mm, mmm (Jan), mmmm (January), yy, yyyy, H, HH (0–23), h, hh (1–12), M, MM (minutes), s, ss, t (a/p), tt (am/pm) and the characters .,/:-; a time shows only H, h, M, s and t. Names are English.

NoteNode

A text annotation: a sticky-note icon that opens its text in the viewer. It takes no space; its icon (20 pt square, the same at any zoom) sits at the top-left corner of its box, inside the page, on the page where the box starts. Under a transform, the icon stays upright and the same size: only its corner moves. In a header, a footer or a fixed element it is on every page.

PropertyTypeRequiredNotes
type"note"yes
idId
styleStyle
breakBreak
pagesPageFilter
debugDebug
noteNoteyes

Note

PropertyTypeRequiredNotes
contentsstringyesmin length 1, max length 8000; The text of the note.
authorstringmax length 256; Who wrote it; viewers show it as the note's title.
colorColorThe icon's colour, also the colour viewers give the note (its alpha is not used); default yellow, [1, 0.82, 0.2, 1].
openbooleandefault false; Whether viewers show the text when the document opens.

TrackBreadth

Grid track breadth: points, a percentage, "fr", "auto", "min-content" or "max-content". Points and fr are at most 1000000.

Type: number (≥ 0, ≤ 1000000) or NonNegativePercent or Fr or "auto" | "min-content" | "max-content"

TemplateTrack

Entry of a track template: a track, or CSS repeat() as {repeat, tracks}. auto-fill/auto-fit may appear once per list, and then every track in the list needs a fixed (points or percentage) minimum or maximum.

Type: TrackSize or {repeat, tracks} (repeat: integer (≥ 1, ≤ 1000) or "auto-fill" | "auto-fit"; tracks: array of TrackSize (min items 1))

PageFilter

Pages that show the node, by physical page number (as the pageNumber placeholder). The node keeps its place in the layout on every page; it is only painted on the matching ones.

Type: "first" | "last" | "notFirst" | "notLast" | "odd" | "even" or array of integer (each ≥ -2147483648, ≤ 2147483647, ≠ 0) (min items 1)

Synced from docs/SCHEMA.md in the inkoxide repository.