Skip to main content

Affinity SDK — C++ Exposure Map

What this document is: A complete map of how the Affinity C++ engine is exposed to JavaScript, derived by analysing every SDK source file. This answers: what can you touch, what is hidden, and what signals clearly indicate a boundary between JS and C++.


How the binding works​

The SDK is a three-layer sandwich:

Your JavaScript script
↓
JS wrapper classes (the .js files you require())
↓
Native C++ bindings (affinity:dom, affinity:commands, affinity:common, affinity:story, affinity:ui)
↓
Affinity C++ engine (NOT accessible — no escape hatch)

The native bindings are loaded with require('affinity:xxx') — a special scheme that is not the file system. These resolve to compiled C++ extension objects baked into the Affinity binary.

You can never call into a C++ binding that the JS SDK doesn't already expose. There is no ffi, no nativeModule, no way to call arbitrary C++ from JS. If something isn't in the binding table below, it does not exist for your scripts.


The four native C++ binding modules​

ModuleWhat it provides
affinity:domDocument object model — all nodes, spreads, adjustments, filters
affinity:commandsCommand construction — DocumentCommand, CompoundCommandBuilder, etc.
affinity:commonShared types — EnumerationResult, ErrorCode
affinity:storyText story model — StoryIoFormat
affinity:uiDialog system — all Dialog* APIs, UiApi for alerts/prompts
affinity:applicationApp-level — ApplicationApi, ApplicationSettingsApi

Everything in the JS SDK is a wrapper around calls into one of these six modules.


The architecture signal: *Api classes​

Every C++ method is accessed through a class ending in Api. These are the exact boundary points between JS and C++. The JS wrapper classes receive a native handle from these Api calls and wrap it in a typed JS object.

// This is what happens inside the SDK — not in your scripts
class ShapeNode extends VectorNode {
get shapeInterface() {
// ShapeNodeApi is C++ — returns a native handle
return new ShapeInterface(ShapeNodeApi.getShapeInterface(this.handle));
// ^^^^^^^^^^^^ C++ boundary
}
}

The handle is an opaque integer pointer into the C++ heap. You never construct handles — you only receive them from Api calls and pass them back.


What IS exposed to JavaScript​

Node types (affinity:dom → nodes.js)​

All 29 concrete node classes are accessible:

Node classType guardKey interfaces
SpreadNodeisSpreadNodephysicalRootInterface, artboards, layers
DocumentNodeisDocumentNodepageCount, spreadCount
GroupNodeisGroupNodechildren, visibility
ContainerNodeisContainerNodechildren, fill, line
ShapeNodeisShapeNodeshapeInterface, fill, line, artboard
PolyCurveNodeisPolyCurveNodecurvesInterface, artboard
ImageNodeisImageNoderasterInterface, imageResourceInterface
RasterNodeisRasterNoderasterInterface
ArtTextNodeisArtTextNodestoryInterface, fill, line
FrameTextNodeisFrameTextNodestoryInterface, fill, line
TableTextNodeisTableTextNodestoryInterface (grid-based cells)
CurvePathTextNodeisCurvePathTextNodestoryInterface
PolyCurveTextNodeisPolyCurveTextNodestoryInterface
ShapeTextNodeisShapeTextNodestoryInterface, shapeInterface
ShapePathTextNodeisShapePathTextNodestoryInterface, shapeInterface
EmbeddedDocumentNodeisEmbeddedDocumentNodespreads, artboards, layers
VectorNodeisVectorNodefill, line, curves, pictureFrame
LogicalNodeisLogicalNodefill, line, transparency
ColouredLogicalNodeisColouredLogicalNodelayerColour
PhysicalNodeisPhysicalNode(base class)
PatternRasterNodeisPatternRasterNoderasterInterface (tiled image)
EnclosureRasterNodeisEnclosureRasterNoderasterInterface (wrapped raster)
MeasurementNode(created via MeasurementNodeDefinition.create(start, end, factor, unitType))measurement annotation
DevelopNodeisDevelopNode.parameters, .sourceIsRaw, .imageSize (RAW develop)

Adjustment layer nodes (all exposed)​

Node classParameters type
BlackAndWhiteAdjustmentRasterNodeBlackAndWhiteAdjustmentParameters
BrightnessContrastAdjustmentRasterNodeBrightnessContrastAdjustmentParameters
ColourBalanceAdjustmentRasterNodeColourBalanceAdjustmentParameters
CurvesAdjustmentRasterNodeCurvesAdjustmentParameters (handle-based)
ExposureAdjustmentRasterNodeExposureAdjustmentParameters
HSLShiftAdjustmentRasterNodeHSLShiftAdjustmentParameters (handle-based)
InvertAdjustmentRasterNode(no parameters)
LevelsAdjustmentRasterNodeLevelsAdjustmentParameters + colourSpace
NormalsAdjustmentRasterNodeNormalsAdjustmentParameters
PosteriseAdjustmentRasterNodePosteriseAdjustmentParameters
RecolourAdjustmentRasterNodeRecolourAdjustmentParameters
SelectiveColourAdjustmentRasterNodeSelectiveColourAdjustmentParameters
ShadowsHighlightsAdjustmentRasterNodeShadowsHighlightsAdjustmentParameters
SplitToningAdjustmentRasterNodeSplitToningAdjustmentParameters
ThresholdAdjustmentRasterNodeThresholdAdjustmentParameters
ToneCompressionAdjustmentRasterNodeToneCompressionAdjustmentParameters
ToneStretchAdjustmentRasterNodeToneStretchAdjustmentParameters
VibranceAdjustmentRasterNodeVibranceAdjustmentParameters
WhiteBalanceAdjustmentRasterNodeWhiteBalanceAdjustmentParameters

Filter layer nodes (all exposed)​

Node class
AddNoiseFilterRasterNode
BilateralBlurFilterRasterNode
BloomFilterRasterNode
BoxBlurFilterRasterNode
ClarityFilterRasterNode
DefringeFilterRasterNode
DenoiseFilterRasterNode
DepthOfFieldFilterRasterNode
DiffuseFilterRasterNode
DiffuseGlowFilterRasterNode
DustAndScratchFilterRasterNode
FieldBlurFilterRasterNode
GaussianBlurFilterRasterNode
HighPassFilterRasterNode
LensBlurFilterRasterNode
MaximumBlurFilterRasterNode
MedianBlurFilterRasterNode
MinimumBlurFilterRasterNode
MotionBlurFilterRasterNode
PinchPunchFilterRasterNode
PixelateFilterRasterNode
RadialBlurFilterRasterNode
RippleFilterRasterNode
ShadowsHighlightsFilterRasterNode
SphericalFilterRasterNode
TwirlFilterRasterNode
UnsharpMaskFilterRasterNode
VignetteFilterRasterNode
VoronoiFilterRasterNode
HalftoneFilterRasterNode

Node interfaces (exposed as lazy-loaded properties)​

Every node exposes some of these interfaces — which ones depend on the node type:

InterfaceAccessed viaKey properties/methods
BaseBoxInterfacenode.baseBoxInterface.baseBox, .constrainingBaseBox
BlendModeInterfacenode.blendModeInterface.blendMode, .blendOptions, .antialiasingMode
BrushFillInterfacenode.brushFillInterface.currentDescriptor, .isNoFill
CompoundOperationInterfacenode.compoundOperationInterface.compoundOperation
CurvesInterfacenode.curvesInterface.polyCurve
DescriptionInterfacenode.descriptionInterface.description, .userDescription, .tagColour
EditabilityInterfacenode.editabilityInterface.isEditable, .isLocalEditable, .isMasterEditable
ExportableInterfacenode.exportableInterface.exportConfig
ImageResourceInterfacenode.imageResourceInterface.imageFilePath, .imageFileSize, .fileType
LayerEffectsInterfacenode.layerEffectsInterface.effects
LineStyleInterfacenode.lineStyleInterface.lineStyle, .penFillDescriptor, .lineWeight
PhysicalRootInterfacenode.physicalRootInterface.physicalRootProperties
PictureFrameInterfacenode.pictureFrameInterface.enabled, .description
RasterInterfacenode.rasterInterface.width, .height, .format, .pixelSize
ShapeInterfacenode.shapeInterface.shape, .type, .boundingBox
StoryInterfacenode.storyInterface.story, .storyRange, .getText()
TransformInterfacenode.transformInterface.transform, .baseBox
TransparencyInterfacenode.transparencyInterface.fillDescriptor
VisibilityInterfacenode.visibilityInterface.globalOpacity, .fillOpacity, .isVisibleInExport
ArtboardInterfacenode.artboardInterface.isArtboardEnabled, .name, .baseBox, .origin
TagInterfacenode.tagInterface.tagColour
MarginsInterfacenode.marginsInterfacemargins data
TextFrameInterfacenode.textFrameInterface.ignoreBaselineGrid, .ignoreTextWraps, .isMultiFrameTextFlow

C++ Api classes from affinity:dom — full method inventory​

From nodes.js alone, 142 C++ Api binding classes are imported. Here are the key ones with their exposed method counts:

Api classMethods exposed to JSNotes
NodeApi32Core tree navigation + box queries
NodeCastApi74Type dispatch — one handler per node class
NodeDefinitionApi2setTransform, setUserDescription
EmbeddedDocumentNodeApi26Placed document properties
VectorNodeDefinitionApi17Multi-fill/stroke slot management
DepthOfFieldFilterParametersApi12Depth of field parameters
SpreadNodeApi11Spread extents, page indices, artboards
ImageNodeApi10Image properties, stock info
CurvesAdjustmentParametersApi9Curves spline management
HSLShiftAdjustmentParametersApi9HSL channel parameters
FieldBlurFilterParametersApi7Field blur point management
TextNodeApi6Text-specific interfaces
VectorNodeApi7Vector-specific interfaces
LogicalNodeApi5Fill/line/transparency for logical nodes
CurvesAdjustmentRasterNodeDefinitionApi6Curves + colour space
LevelsAdjustmentRasterNodeDefinitionApi6Levels + colour space

Most filter/adjustment Api classes have exactly 4 methods: create, createDefault, getParameters, setParameters.


What is NOT exposed to JavaScript​

This is the critical part. The following categories of C++ functionality have no binding visible in the SDK — there is no JS wrapper for them:

1. Pixel-level raster manipulation​

/pixelaccessor adds PixelReaderRGBA8, PixelReaderWriterRGBA8, and equivalents for all 10 colour formats (RGBA8, RGBA16, IA8, IA16, CMYKA8, LABA16, M8, M16, RGBAuf, Mf). Both read and write pixel access is supported across all formats. Use node.rasterInterface.createCompatibleBitmap(true) to get a writable bitmap, then PixelReaderWriterRGBA8.create(bitmap) to read/write pixels, then DocumentCommand.createReplaceBitmap(sel, bitmap) to push changes back.

2. Master pages / master spreads​

The EmbeddedDocumentNode can enumerate spreads including masters via enumerateSpreads(includeMasters), but there is no MasterSpreadApi or MasterPageApi. You can detect and navigate to master content but cannot programmatically create, link, or manage master pages from JS.

3. Styles (character, paragraph, object)​

The story system exposes GlyphAttStringType.StyleName for applying named character styles by name. But there is no StyleSheetApi, ParagraphStyleApi, or CharacterStyleApi. You can apply a style by name if you already know it, but you cannot enumerate all styles, create new styles, modify existing styles, or read a node's applied style name from the C++ side.

4. Tables — partially available​

TableTextNode exposes a grid-based text node accessible via /nodes. It has a storyInterface where cells are separated by HardBreakType.TableCell glyphs. There is no dedicated TableApi, TableCellApi, or TableRowApi — you navigate cells through the story text model. Complex table operations (row/column insert/delete, merge, split) are still not exposed.

5. Find/Replace​

No FindReplaceApi. You can implement your own text search by reading storyRanges, but the application's built-in find/replace engine is not accessible.

6. Symbols / Assets panel​

No SymbolApi or AssetApi. Affinity's Symbols feature (reusable components) has no JS representation.

7. Live paint / pixel persona tools​

No PaintBrushApi, LivePaintApi, or InpainterApi beyond the high-level DocumentCommand.createGenerativeEditImage(). The pixel-level painting tools have no programmatic API.

8. Constraints / layout rules​

No ConstraintApi. The auto-layout and constraint system used in Affinity for responsive artboards has no JS binding.

9. Linked resources / package management​

The SDK has PackageResourcesPolicy in exports but no LinkedResourceApi or PackageApi for managing linked file relationships or repackaging documents.

10. Colour swatches / palettes​

No SwatchApi, PaletteApi, or ColourGroupApi. Document colour palettes and global swatches are not accessible.

11. Grids and snapping​

No GridApi, SnapApi. The grid and snapping system is UI-side only.

12. Print / preflight​

No PrintApi or PreflightApi. Printing and PDF preflight checking are not exposed.

13. History beyond undo/redo​

DocumentHistory exposes position, size, canUndo, canRedo, and enumeration of history items. But items are read-only — you cannot inject arbitrary history entries or branch history. The setPosition setter exists but only navigates linearly.

14. Plugin metadata / custom properties​

/taginterface provides TagInterface — a per-node key-value store that persists in the file. Use node.tagInterface.hasKey(key), .getValueForKey(key), and DocumentCommand.createSetTagValueForKey(sel, key, value) to read and write arbitrary string metadata on any node. PredefinedTagKey enumerates Affinity's built-in tag keys.


Boundary signals — how to detect what's missing​

When working with the SDK, these patterns indicate you've hit a boundary:

Pattern 1: No *Api class exists If you want to do something and can't find an *Api class for it in the native module imports, the feature is not bound. Example: searching for StyleSheetApi — doesn't exist.

Pattern 2: Interface exists but is read-only Some interfaces expose getters but no corresponding DocumentCommand.createSet* factory. Example: you can read node.visibilityInterface.fillOpacity but the only way to set it is through DocumentCommand.createSetVisibility().

Pattern 3: NOT_ALLOWED error code If a script command returns NOT_ALLOWED, it means the user has restricted AI, filesystem, or network access in Affinity settings — not that the API doesn't exist.

Pattern 4: Class defined but not exported Some classes are defined in the SDK source but not in module.exports. Example: NodeFactory is defined but not exported — it's used internally by createTypedNode().


The complete native method call inventory (nodes.js only)​

The following 95 unique C++ method calls are made from nodes.js alone. This is the exact set of C++ operations that the node system relies on:

getFirstChild, getLastChild, getNextSibling, getPreviousSibling, getParent, moveToFirstChild, moveToLastChild, moveToNextSibling, moveToPreviousSibling, moveToParent, isSameNode

Bounding boxes​

getSpreadBaseBox, getExactSpreadBaseBox, getExactSpreadVisibleBox, getSpreadVisibleBox, getLocalVisibleBox, getLineBox, getTransformedLineBox, getContentExtentsBox, getContentExtentsBoxOfChildren

Transforms​

getBaseToSpreadTransform, getLocalToSpreadTransform, getSpreadToBaseTransform

Interface accessors​

getBaseBoxInterface, getBlendModeInterface, getBrushFillInterface, getCompoundOperationInterface, getCurvesInterface, getDescriptionInterface, getEditabilityInterface, getExportableInterface, getImageResourceInterface, getLayerEffectsInterface, getLineStyleInterface, getPhysicalRootInterface, getPhysicalRootPropertiesInterface, getPictureFrameInterface, getRasterInterface, getShapeInterface, getStoryInterface, getTransformInterface, getTransparencyInterface, getVisibilityInterface, getArtboardInterface

Document/spread​

getDocument, getPageCount, getSpreadCount, getSpreadExtents, getFirstPageIndex, getLastPageIndex, isFirstPage, getPageIndexOfPoint, getPageIndexOfBox, enumerateArtboards, getArtboard, getArtboardCount

Image/raster​

getBitmapBrushFillDescriptor, getExtendType, getUpsamplerType, getStockURL, getStockUserProfileURL, getStockAuthor, getLastRendered, isKOnly, getExtendEmpty, getLayerColour

Embedded documents​

getSelectedSpreadId, getSelectedArtboardId, embeddedDocumentHasSpreads, embeddedDocumentHasArtboards, embeddedDocumentHasPageBoundingBoxes, embeddedDocumentHasLayers, getSelectedArtboardOffset, getPageBoundingBoxType, getPDFPassthrough, canSetPDFPassthrough, getRasterDPI, getOriginalHostDPI, isAffinityFile, canMakeLinked, canEditEmbeddedImage, getLoadDocumentOptions, shouldAllowSelectDocument, isArtboardSelected, isArtboardDoc, needsPassword, enumerateSpreads, enumeratePageBoundingBoxes, enumerateLayerVisibilities

Logical nodes​

hasNonMaskChildren, hasNonMaskOrAdjustmentChildren

Physical nodes​

canTransformWhileProtectingChildList, canBeExpressedAsVectorClip


Runtime capability detection​

There is no SDK_VERSION constant or capability query system. You cannot ask the SDK at runtime "does this method exist?" — you have to try it and catch errors, or check the source. The module.exports list in each wrapper file is the authoritative list of what's available, and app.shortVersion from /application reports the running Affinity build.


SDK modules​

ModuleNative bindingKey capability
/pixelaccessoraffinity:rasterRead+write pixels in all 10 colour formats
/fontsaffinity:fontsEnumerate all fonts, families, collections
/exportconfigaffinity:domPer-node export settings (ExportConfig/ExportFormat/ExportScale)
/glyphsaffinity:storyTyped glyph classes, CharGlyph.create(), glyph enums
/hatchaffinity:domHatchPattern/HatchLine construction
/rasterbrushaffinity:brushesRaster brush properties (size, flow, opacity, etc.)
/buffer(internal)Binary buffer manipulation
/rasterobject(internal)Raster object handle wrapper
/documentpropertiesaffinity:domDocument metadata (DPI, size, colour space)
/drawingscaleaffinity:domMap/drawing scale (1:100 etc.)
/taginterfaceaffinity:domCustom key-value tags per node
/marginsinterfaceaffinity:domSpread margin information
/pageboxinterfaceaffinity:domBleed, trim, slug boxes
/artboardpropertiesaffinity:domArtboard metadata
/osaffinity:osOS platform/arch/osName/osVersion/Eol
/environmentaffinity:applicationEnvironment permissions, fileSystemRoots, sdkVersion
/loggingaffinity:commonLogFile file-based logging
/configurationaffinity:commonConfigurationItem JSON config parsing
/pathbrushaffinity:brushesPathBrush vector brush access

New native C++ binding modules (affinity:xxx)​

ModuleProvides
affinity:rasterAll PixelReader/Writer Api classes for 10 colour formats
affinity:fontsFontApi, FontFamilyApi, FontCollectionApi, PanoseApi, font enums
affinity:brushesRasterBrushApi, BrushDynamicApi, brush enums

DocumentCommand factories​

Key additions grouped by purpose:

Macro system: createStartRecordingMacro, createStopRecordingMacro, createReplayMacro, createClearMacro, createImportMacro(path), createExportMacro(path)

Raster selections: createRasterSelectAll, createRasterDeselect, createRasterInvertSelection, createRasterReselect, createSetRasterSelectionFromPolygon(polygon, op, antialias, feather) (replaces createRasterSelectPolygon), createSetRasterSelectionFromObject(sel, op, antialias, feather), createGrowShrinkRasterSelection(radius, circular), createFeatherRasterSelection(radius), createSmoothRasterSelection(radius), createOutlineRasterSelection(radius, alignment, circular), RasterSelectionOutlineAlignment enum

Opacity control: createSetOpacity(sel, opacity), createSetBrushFillOpacity(sel, opacity, opts), createSetLineFillOpacity(sel, opacity, opts)

Fill anchoring: createSetBrushFillIsAnchoredToSpread, createSetPenFillIsAnchoredToSpread, createSetTransparencyFillIsAnchoredToSpread

Tag metadata: createSetTagValueForKey(sel, key, value), createSetTagValueForPredefinedKey(sel, predefinedKey, value)

Blend options: createSetBlendGamma(sel, gamma), createSetBlendRanges(sel, blendOptions), createSetAntialiasingMode(sel, mode)

Snapshots: createAddDocumentSnapshot, createDeleteDocumentSnapshot, createRestoreDocumentSnapshot, createSetCurrentSnapshot, createSetCurrentSnapshotFromHistoryItem

Document: createSetDocumentProperties, createConvertDocumentFormat(format), createGroupTransform, createSetWindingMode, createSetExportConfig, createMoveNodes, createFlatten, createMergeVisible, createSetSelection(sel)

Spread: createSetSpreadSizeWithAnchor, createSetSpreadDocumentProperties

History: createSetHistoryIndex(index), createCycleAlternateFutures(index)

Text frame: createSetTextFrameIgnoreBaselineGrid(sel, ignore), createSetTextFrameIgnoreTextWraps(sel, ignore)

Layer effects — outline fill: createSetOutlineLayerEffectFill(sel, fill, index, enableIfDisabled), createSetOutlineLayerEffectFillTransform(sel, transform, index, enableIfDisabled), createSetOutlineLayerEffectFillType(sel, type, index, enableIfDisabled), createSetGradientOverlayLayerEffectFill(sel, fill, index, enableIfDisabled), createSetGradientOverlayLayerEffectFillTransform(sel, transform, index, enableIfDisabled)

AI: createRemoveBackground(sel), createSelectSubject(sel) Artboard: createAddArtboard(spread, bounds) Curve editing: createAddCurve(sel), createAddCurveNode(sel, point, type), createSmoothCurves(sel), createDeleteCurveNodes(sel), createScissorCut(sel), createKnifeCut(sel) Document: createSetDocumentUnits(sel, units), createSetPageDocumentProperties(sel, props) Guides: createAddHorizontalGuide(pos), createAddVerticalGuide(pos), createMoveHorizontalGuide(sel, pos), createMoveVerticalGuide(sel, pos), createRemoveHorizontalGuide(sel), createRemoveVerticalGuide(sel) Embedded documents: createSetEmbeddedDocumentAllLayersVisibility(sel, visible), createSetEmbeddedDocumentLayerVisibility(sel, layerIndex, visible), createSetEmbeddedDocumentPDFPassthrough(sel, passthrough), createSetEmbeddedDocumentPageBoundingBoxType(sel, type), createSetEmbeddedDocumentSelectedArtboardID(sel, id), createSetEmbeddedDocumentSelectedSpreadID(sel, id) Layer effects: createSetAllLayerEffectsScaleWithObject(sel, scale), createSetOuterShadowLayerEffectKnocksOut(sel, knocksOut, index, enableIfDisabled), createSetBevelEmbossLayerEffectAzimuth(sel, azimuth, enableIfDisabled), createSetBevelEmbossLayerEffectElevation(sel, elevation, enableIfDisabled) Raster selection: createRasterFloodSelect(x, y, tolerance, antialias, feather) (magic wand), createRasterSelectPolygon(polygon, operation, antialias, feather) (available alongside createSetRasterSelectionFromPolygon) Other: createHideSelection, createSplitCurve, createInsertGlyph

Additional factories​

Boolean operations: createBoolOpUnion(sel), createBoolOpSubtract(sel), createBoolOpIntersect(sel), createBoolOpXor(sel), createDivideShapes(sel)

Text frame threading: createLinkTextFrame(srcNode, destNode), createUnlinkTextFrame(node)

Merge: createMergeDown(), createMergeSelected()

Picture frame: createPopulatePictureFrame(contentNode, selection)

Raster auto-fixes: createRasterAutoLevels(sel), createRasterAutoContrast(sel), createRasterAutoColours(sel), createRasterAutoWhiteBalance(sel)

Raster fill: createRasterFill(sel, mode, colour, opacity, blendMode), createRasterFloodFill(sel, point, tolerance, isContiguous, antialias, samplingSource, blendMode, colour)

RAW Develop: createSetDevelopParameters(sel, developParameters)

Measurement: createSetMeasurementUnits(unitType), createSetMeasurementPrecision(useDocumentPrecision, decimalPlaces), createSetMeasurementAnnotationOffset(node, offset), createSetMeasurementShowEndpointMarkers(show)

Enum member reference​

Values below marked ★ were read at runtime (Object.entries dump in Affinity 3.3); the rest are member names from the official docs at https://sdk.affinity.studio/ (which publishes no values — never infer values from documentation order).

Runtime-verified (name = value) ★:

EnumMembers
GradientFillType ★Linear=0, Elliptical=1, Radial=2, Conical=3
RasterSelectionLogicalOperation ★New=0, Add=1, Subtract=2, Intersect=3 (no Replace — use New)
NodeMoveType ★Before=0, After=1, Inside=2
NodeChildType ★Main=0, Enclosure=1, MasterSpread=2, WrapShape=3, StoryPin=4
ShapeCornerType ★Round=0, Straight=1, RoundInverse=2, Cutout=3, None=4
ContentType ★Main=0, Frame=1, Cell=2
VisibilityMode ★Main=0, Export=1
ShapeArrowEndStyle ★None=0, Arrow=1, TailTriangular=2, TailSquare=3, Circle=4, HalfCircleInner=5, HalfCircleOuter=6, Diamond=7, Box=8, Barb=9, Chevron=10 (no Triangle — use Arrow)
QRPayloadType ★Text=0, URL=1, Phone=2, SMS=3, Email=4, WhatsApp=5, FaceTime=6, Location=7, Wifi=8, VEvent=9, VCard=10, DataMerge=11
FillType ★Unknown=0, None=1, Solid=2, Gradient=3, Bitmap=4, Mesh=5, Hatch=6, Diffusion=7

Member names from official docs (values not published):

EnumMembers
SubSelectionTypeCurveEdge, CurveNode, Text, Table, ExportFormat, Fill, LineFill, Transparency, FillMesh, LineFillMesh, TransparencyMesh, GeometryModifier, FillDiffusion
DialogItemTypeUnknown, Separator, Switch, ComboBox, ButtonSet, RadioGroup, StaticText, UnitValueEditor, CheckBox, SpatialAnchor, ColourPicker, TextBox, FontPicker, FillEditor, StrokeEditor, Group, Column, ColumnStack, Button
SpatialAnchorNone, TopLeft, CentreLeft, BottomLeft, TopCentre, Centre, BottomCentre, TopRight, CentreRight, BottomRight, FocalPoint
PackageResourcesPolicyNone, IncludeImages, IncludeTexts, IncludeCSS, IncludeUnrestrictedFonts, IncludeRestrictedFonts
PageBoundingBoxTypeMediaBox, CropBox, TrimBox, ArtBox, BleedBox, MinimumContent, MinimumVisibleContent, MaximumContent, MaximumVisibleContent
RasterFillModeColour, Foreground, Background, Inpainting, History
SamplingSourceCurrentLayer, AllLayers
RasterFloodFillSamplingSourceCurrentLayer, CurrentLayerAndBelow, LayersBeneath
RasterSelectionOutlineAlignmentOutside, Centre, Inside
CurveNodeStyleNone, Cusp, Smooth, Smart
CurveNodeTypeOnCurve, Cubic1, Cubic2
CurveCornerTypeNone, Round, Inverse, Straight, CutOut
LayerEffectTypeBevelEmboss, Outline, PhongBevel, InnerShadow, InnerGlow, ColourOverlay, GradientOverlay, OuterGlow, OuterShadow, GaussianBlur
DevelopToneCurveMethodStandard, Compressed, Natural, HighContrast, Log
DevelopInvertMethodInfraredRB, InfraredRGB, Negative
DevelopDetailRefinementMethodUnsharpMask, HighPass, MultiBand
RasterExtendTypeZero, Repeat, Wrap, Mirror
RasterResamplerTypeDefault, BilinearMipmap, NearestNeighbourMipmap, NearestNeighbour, Bilinear, Bicubic, SeparableLanczos3, NonseparableLanczos3, AntialiasedNearestNeighbourMipmap, Mitchell
ConstraintTypeNotSizable, FixedMinX, ScaleWidth, FixedMaxX, FixedMinY, ScaleHeight, FixedMaxY, FixedAspectMin, FixedAspectMax, ForceAspectMin, ForceAspectMax, StretchToFit, NoScale, Default
FontFieldPostscriptName, FamilyName, Weight, IsItalic, Width, Panose, VarParams, RibbiFamily, WwsFamily
CopyOptionsNone, SkipExisting, OverwriteExisting, UpdateExisting, Recursive, CopySymlinks, SkipSymlinks, DirectoriesOnly, CreateSymlinks, CreateHardLinks
FileOriginBegin, Current, End
PathTypeNone, NotFound, File, Directory, Symlink, Block, Character, Fifo, Socket, Unknown
PermOptionsReplace, Add, Remove, NoFollow
UnitCategoryDistance, Angle, Relative, Data, Temperature
ShapeBoolParamArrow_LeftIsProportional, Arrow_RightIsProportional, CalloutEllipse_AbsoluteSizes, CalloutRectangle_SingleRadius, CalloutRectangle_AbsoluteSizes, Polygon_SmoothPoints, Rectangle_SingleRadius, Tear_FixedBallSize
ShapeEnumParamRectangle_BottomLeftCornerType, Rectangle_BottomRightCornerType, Rectangle_TopLeftCornerType, Rectangle_TopRightCornerType, Arrow_LeftEndStyle, Arrow_RightEndStyle
ShapeFloatParamArrow_LeftLength, Arrow_LeftInnerOffset, Arrow_RightLength, Arrow_RightInnerOffset, Arrow_Thickness, CalloutEllipse_TailAngle, CalloutEllipse_TailEndPosition, CalloutEllipse_TailHeight, CalloutRectangle_BottomLeftRadius, CalloutRectangle_BottomRightRadius, CalloutRectangle_TopLeftRadius, CalloutRectangle_TopRightRadius, CalloutRectangle_TailEndPosition, CalloutRectangle_TailHeight, CalloutRectangle_TailPosition, CalloutRectangle_TailWidth, Cloud_InnerRadius, Cog_Curve, Cog_HoleRadius, Cog_InnerRadius, Cog_NotchSize, Cog_ToothSize, Crescent_ArcLeft, Crescent_ArcRight, Diamond_Position, DoubleStar_InnerRadius, DoubleStar_PointRadius, Heart_Spread, Pie_InnerRadius, Pie_StartAngle, Pie_EndAngle, Pie_Sweep, Polygon_Curve, Rectangle_BottomLeftRadius, Rectangle_BottomRightRadius, Rectangle_TopLeftRadius, Rectangle_TopRightRadius, Segment_Angle, Segment_LowerLine, Segment_UpperLine, SquareStar_Cutout, Star_CircleOuterRadius, Star_CircleInnerRadius, Star_InnerRadius, Star_LeftCurve, Star_RightCurve, Trapezoid_LeftPosition, Trapezoid_RightPosition, Triangle_Position, Tear_BallSize, Tear_Curve, Tear_Bend, Tear_TailPosition
ShapeIntParamCloud_BubbleCount, Cog_ToothCount, DoubleStar_PointCount, Polygon_SideCount, SquareStar_SideCount, Star_PointCount

Enum behavior (per the September 2026 release notes): SDK enums expose parse(name, throwIfMissing) — returns null for an unknown name unless throwIfMissing is true. Enum values compare directly without extracting .value, and value is now an instance property. | TonalRangeType | Shadows, Midtones, Highlights | | ToneCompressionMethod | Basic, Natural, Bright, Contrast, Filmic, Punchy, PBRNeutral, Log | | ToneStretchMethod | Basic, Arcsinh, Logarithmic, Structural, ColourPreserving | | DevelopDetailRefinementMethod / DevelopToneCurveMethod / DevelopInvertMethod | UnsharpMask, HighPass, MultiBand / Standard, Compressed, Natural, HighContrast, Log / InfraredRB, InfraredRGB, Negative | | DocumentLoadMode | Application, Spreads, Artboards | | HalftoneDotType / HalftoneScreenType | Cosine, Round, Line / Mono, Colour, Line, Circular | | AntialiasingMode | Inherit, ForceOn, ForceOff | | CompoundOperation | Union, Intersect, Subtract, Xor | | ExportScalePreset | Standard, Mult2x, Mult3x, Width100, Height50, Square64, Square64Mult2x, Width32Height32 | | ExportScaleSizeType | None, Width, Height, Square, WidthHeight | | FileType | JPEG, PNG, TIFF, WEBP, HDPhoto, RAW, GIF, JPEG2000, BMP, TGA, OpenEXR, HDR, Unknown, Affinity, HEIF, FITS, Plugin | | ShapeMajorAxis / ShapeSpiralStyle / Shape*Param / ShapeCornerIndex | See /shapes module; corner indices TopLeft/TopRight/BottomLeft/BottomRight | | CapsType, SuperSubType, LeadingOverrideType, OpticalAlignmentType, TocRoleType, TypographicLineType | Glyph typography enums (see /glyphatts) | | ParagraphAlignXType, ParagraphLeadingType, ParagraphStartAtHardBreakType, ParagraphUseSpaceBeforeMode, ParagraphPDFExportTagType, ParagraphLineBreakModeType | Paragraph behaviour enums (see /paragraphatts) | | StoryIoFormat, TextDefaultType (Art, Frame, Unknown, Measurement), WordPartType | Story/text enums | | TableEdgeSelector (None … All, 14) / TableAxis | Table enums | | WifiEncryptionType, DocumentFieldType, FieldDataType, FillerTextType, NoteType, NotePosition | Field/QR enums | | UnitCategory, UserUnitType, UnitType | Units enums | | AddNoiseType (Gaussian, Uniform), BloomMethod (Contrast, Bright), DepthOfFieldMode (Elliptical, TiltShift), SelectiveColour (9 channels), ShadowsHighlightsVersion (Default, V16) | Filter/adjustment enums | | LineCommandDefaultsMode, StrokeFillType, WindingOrder, BevelEmbossType, ImagePlacement, ColourSpaceType, RasterIntent | Named in module indexes; members per official docs |

Documented officially but NOT script-reachable in 3.3 (present in the web API index, absent from JSLib — native layer only, do not use from scripts; re-verified against the 3.3 JSLib): QRPayloadDataMerge (QR payload kind 11 exists in the QRPayloadType enum but has no JSLib wrapper; VEvent (9) likewise), ImportOptions (CAD import options), DocumentView (empty handle).

Geometry classes (from /geometry)​

ClassKey factories/methods
Polygoncreate(), createLine(), createTriangle(p1,p2,p3), createDiamond(rect), createLozenge(p1,p2,radius), createRectangle(rect)
Curvecreate(), createLine(), createRectangle(), createEllipse(), createDiamond(), createLozenge(), createPrecisionUnitCircle()
CubicBezier.evaluate(t), .split(t), .getTangent(t), .getNormal(t), .getCurvature(t), .getClosestPoint(pt), .length, .getParamAtLength(len), .clone(), .reversed(), .transformed(xf)
CurveBuildercreate(), .begin(), .lineTo(), .close(), .addBezier(), .addArc(), .addEllipse(), .versineTo(), .bulgeTo(), .createCurve()

Selections (from /selections)​

ClassKey factories/methods
TableSubSelectionfromSubSelection(sub) — .anchor, .caret, .isRectangle, .cells, .enumerateCells(), .enumerateEdges()
TextSelectioncreate(ranges) — .ranges, .caret, .anchor, .isEmpty
FillSubSelectionfromSubSelection(sub) — .index
LineFillSubSelectionfromSubSelection(sub) — .index

Story attribute runs​

IteratorYields
story.glyphAttRuns{glyphAtts, begin, end}
story.paragraphAttRuns{paragraphAtts, begin, end}
story.attRuns{glyphAtts, paragraphAtts, begin, end}

Dialog controls (from /dialog)​

ClassKey properties/methods
Dialogcreate(title), .addColumn(), .runModal(), .findControl(id), .isRunningModal, .setItemsVisibility(showIDs, hideIDs)
DialogFontPicker.font (Font), .fontFamily (FontFamily), .fontCollection (FontCollection), .isFullWidth
DialogFillEditor.fill, .isStrokeFill
DialogStrokeEditor.stroke (LineStyleDescriptor)
DialogSpatialAnchor.value (SpatialAnchor enum)
DialogButton.alignment, .onClickHandler, .isFullWidth
DialogUnitValueEditor.value, .units, .noMinValue, .noMaxValue, .precision
DialogColourPicker.value (Colour), .allowPickNone, .allowNoise

createSetEditable — argument order​

// Selection is first argument, editable flag is second
DocumentCommand.createSetEditable(selection, true) // unlock
DocumentCommand.createSetEditable(selection, false) // lock

Layer effect families​

The following effect families are available in addition to OuterShadow, Outline, InnerGlow, and GaussianBlur:

EffectKey commands
OuterGlowcreateSetOuterGlowLayerEffect* — colour, radius, opacity, intensity, blend mode
InnerShadowcreateSetInnerShadowLayerEffect* — colour, offsetAngle, radius, opacity, intensity (indexed)
ColourOverlaycreateSetColourOverlayLayerEffect* — colour, opacity, blend mode (indexed)
GradientOverlaycreateSetGradientOverlayLayerEffect* — fill, fillTransform, blend mode (indexed)
BevelEmbosscreateSetBevelEmbossLayerEffect* — radius, depth, direction, soften, type, shadow/highlight colours
PhongBevelcreateSetPhongBevelLayerEffect* — ambient, diffuse, specular, shininess, createSetPhongBevelLayerEffectLights(count)

All layer effects must be executed individually — CompoundCommandBuilder is a silent no-op for effect commands.

Fill types​

ClassFactoryDescription
HatchFillHatchFill.create(pattern, units, penColour, brushColour, lineWeight)Repeating line pattern
BitmapFillBitmapFill.create(bitmap, extendType, resamplerType, ignoreAlpha)Tiled raster image
GradientFillGradientFill.create(gradient, gradientType)Linear/radial/conical gradient
MeshFillMeshFill.create(mesh) + ColourMesh.createFromColour(colour, nodes)Mesh gradient grid (ColourMesh with setNodePosition/setNodeColour)
DiffusionFillDiffusionFill.create(curveSet) + DiffusionCurveSet.create()Diffusion curve fill (DiffusionCurveKind: Bezier/Ellipse/Arc/Line)

FillDescriptor.createSolid() accepts a Colour directly, as do createSetBrushFill / createSetPenFill. The FillType enum includes Mesh and Diffusion.

Document convenience methods​

Document exposes direct convenience methods for most common operations, eliminating the need to call DocumentCommand.create* explicitly. These include: doc.undo(), doc.redo(), doc.selectAll(), doc.deleteSelection(), doc.showSelection(), doc.hideSelection(), doc.lockSelection(), doc.unlockSelection(), doc.setOpacity(), doc.setBrushFillOpacity(), doc.setLineFillOpacity(), doc.setBrushFillDescriptor(), doc.setPenFillDescriptor(), doc.setLineWeight(), doc.setLineWeightPts(), doc.setLineCap(), doc.setLineJoin(), doc.convertToCurves(), doc.rasteriseObjects(), doc.flatten(), doc.mergeVisible(), doc.addGuide(), doc.moveGuide(), doc.removeGuide(), doc.addRectangularArtboard(), doc.imageTrace().

AI convenience methods: doc.generateImage(prompt), doc.detectDepth(), doc.colourise(), doc.generativeEditImage(prompt), doc.removeBackground(), doc.selectSubject().

Document classes​

ClassPurpose
DocumentHistoryAccess undo history — position, size, canUndo, canRedo, getItem(index), items
DocumentHistoryItemIndividual history entry — description, thumbnail, command
NewDocumentOptionsFull control over new document creation — dimensions, DPI, margins, colour profile
DocumentPresetEnumerate built-in presets via DocumentPreset.all
LoadDocumentOptionsControl DPI, password, colour space when loading
FileExportAreacreateForSpreads(str), createForSelection(sel) in addition to existing factory methods

Summary counts​

CategoryCount
Native C++ binding modules9
C++ Api classes in nodes.js142
JS wrapper modules~75
DocumentCommand factories~351
Node types accessible31 concrete + ~10 base
Adjustment layer types19
Filter layer types30 (+ HalftoneFilterRasterNode)
Node interfaces21+
Major feature categories exposedpixel access, custom tags, tables, fills, AI, develop
Major features still NOT exposedseveral categories

Release 3.3 — analysed from live Affinity SDK via MCP.


Official SDK example scripts​

The SDK ships 34 official example scripts that are instructive as canonical patterns from the Affinity team. They are mirrored 1:1 in phase-5-official-examples/ — see its [README(./phase-5-official-examples/README.md) for the full table:

FileWhat it demonstrates
examples/boldItalics.jsStoryDelta.createWeight(), StoryDelta.createItalic(), StoryDelta.createComposite()
examples/addGuides.jsDocumentCommand.createAddGuide(), unionRects(), UnitType.Pixel/Millimetre
examples/setDocumentFormat.jsdoc.format = RasterFormat.xxx, dialog combo pattern
examples/addPoints.jsCurve node manipulation
examples/alignToPage.jsAlignment via transform
examples/adjustPageItems.jsBatch node adjustment

Additional confirmed APIs​

StoryDelta factory methods:

  • StoryDelta.createWeight(FontWeight.Bold) — applies font weight
  • StoryDelta.createItalic(bool) — applies italic
  • StoryDelta.createComposite([delta1, delta2]) — combines multiple deltas

Geometry utility:

  • unionRects(rect1, rect2) from /geometry — combines two Rectangle bounding boxes

LoadDocumentOptions (exported from /document):

  • Properties: dpi, hostDpi, password, colourSpace, format, loadMode

Confirmed patterns:

  • alert(string) is a global — shorthand for a simple message dialog
  • node.getSpreadBaseBox() returns a Rectangle with .x, .y, .width, .height, .centre
  • UnitType.Millimetre (singular) — all unit names are singular (Pixel, Millimetre, Point)
  • result == DialogResult.Ok — loose == equality is idiomatic; .equals() also works