Skip to main content
LayerInput is the flat, one-object authoring format for all ten layer types. Every place in the SDK that accepts a layer — decks.create, slides.create, layers.create, and layouts.create — accepts a LayerInput. The object is discriminated on type: set type to the kind of content you want and add the matching fields alongside the required at geometry. The compiler validates your input through Zod, maps friendly input types ('bar', 'donut') to their stored representation ('chart'), and builds canonical structured documents for text, charts, and tables — you never write those by hand.

Common fields

Every layer type shares these fields.
at
At
required
Layer geometry in 1920×1080 slide coordinates.
z
number
Integer stacking order (z-index). Higher values render on top of lower values. When omitted, the server assigns a value based on insertion order.
prompt
string
AI brief — a plain-language instruction for what the AI should generate for this layer. Stored in layer metadata and read by Ablo’s generation pipeline.
examples
string[]
Sample outputs that guide AI generation for this layer. Each string is one example of the content you expect.
effects
EffectsInput
Visual effects applied to the layer box: opacity, corner radius, blur, vertical alignment, and drop shadows.

type: 'text'

A text layer. The text field accepts a single string or an array of strings (each string becomes a paragraph).
type
"text"
required
text
string | string[]
required
The content. An array of strings produces multiple paragraphs.
{ type: 'text', text: 'Revenue up 40%', style: 'h1', at: { x: 160, y: 80, w: 1200, h: 120 } }

{ type: 'text', text: ['First paragraph.', 'Second paragraph.'], style: 'body1',
  at: { x: 160, y: 240, w: 800, h: 400 } }

type: 'bullets'

A bullet list. Each string in items becomes one bullet point.
type
"bullets"
required
items
string[]
required
List items. Must contain at least one item.
{ type: 'bullets', items: ['ARR $4.2M', 'NRR 118%', '240 customers'],
  style: 'body1', bulletColor: 'var(--slide-brand)',
  at: { x: 160, y: 240, w: 700, h: 500 } }

type: 'numbered'

A numbered list. Each string in items becomes one numbered item.
type
"numbered"
required
items
string[]
required
List items. Must contain at least one item.
{ type: 'numbered', items: ['Define the problem', 'Identify stakeholders', 'Draft solution'],
  style: 'body1', listStyle: 'decimal',
  at: { x: 160, y: 240, w: 800, h: 500 } }

type: 'bar'

A bar chart (vertical or horizontal). The SDK compiles this into a full ChartDocument and stores it as a 'chart' layer.
type
"bar"
required
data
ChartDatum[]
required
Chart data. Each datum has label (string), value (number), and an optional color override.
title
string
Optional chart title rendered above the chart.
orientation
'vertical' | 'horizontal'
Bar direction. Default is 'vertical'.
valueFormat
string
D3-style number format string, e.g. '$0.0"M"', '0,0', '0%'.
dataLabels
boolean
Show value labels on each bar.
cagrArrow
boolean
Render a CAGR arrow between the first and last bar.
{ type: 'bar',
  data: [
    { label: 'Q1', value: 2.1 },
    { label: 'Q2', value: 2.8 },
    { label: 'Q3', value: 3.4 },
  ],
  valueFormat: '$0.0"M"',
  dataLabels: true,
  cagrArrow: true,
  at: { x: 160, y: 240, w: 900, h: 620 } }

type: 'donut'

A donut chart. Compiles to a 'chart' layer.
type
"donut"
required
data
ChartDatum[]
required
Slice data — same shape as bar chart data.
title
string
Optional center label.
valueFormat
string
Number format string for slice labels.
dataLabels
boolean
Show labels on each slice.
{ type: 'donut',
  data: [
    { label: 'Enterprise', value: 62, color: '#3B82F6' },
    { label: 'Mid-Market', value: 28, color: '#60A5FA' },
    { label: 'SMB',        value: 10, color: '#BAE6FD' },
  ],
  valueFormat: '0%',
  at: { x: 600, y: 240, w: 720, h: 600 } }

type: 'chart'

The full chart API — every chart family (bar, stacked bar, line, combo, pie, donut, waterfall, funnel, scatter, bubble, mekko, gantt, range) with full control over datasets, marks, encodings, scales, axes, legend, and affordances. Pass a CreateChartDocumentInput — the same input the Ablo chart toolkit accepts.
type
"chart"
required
document
CreateChartDocumentInput
required
The full chart structure. Validated against the ChartDocumentSchema at compile time; family-default affordances are filled in automatically.
Use type: 'bar' and type: 'donut' for the common cases. Use type: 'chart' when you need a chart family or configuration option those shortcuts don’t expose.

type: 'table'

A data table. Columns can carry alignment, width, and per-column style; cells can be plain values or rich objects with colspan/rowspan.
type
"table"
required
columns
(string | ColumnDef)[]
required
Column definitions. Pass a bare string for a simple header, or an object with { header, key?, align?, verticalAlign?, width?, style? } for full control. Column keys are auto-generated from headers if omitted.
rows
CellInput[][]
required
Row data. Each row is an array of cell values aligned to the columns. Cells can be a string, number, null, or a rich { text?, content?, align?, verticalAlign?, backgroundColor?, colSpan?, rowSpan? } object.
headerRows
number
Number of header rows at the top (default 1). These rows receive the styles.header style.
{ type: 'table',
  columns: ['Quarter', { header: 'Revenue', align: 'right' }, { header: 'Growth', align: 'right' }],
  rows: [
    ['Q1', '$2.1M', '+18%'],
    ['Q2', '$2.8M', '+33%'],
    ['Q3', '$3.4M', '+21%'],
  ],
  headerRows: 1,
  at: { x: 160, y: 200, w: 1100, h: 600 } }

type: 'image'

An image layer. Stored internally as a 'shape' layer with an imageFill. External URLs are automatically rehosted to the Ablo CDN at commit time. Use ablo.images.upload() for local files.
type
"image"
required
url
string
required
A valid HTTPS URL. External URLs are rehosted to the Ablo CDN on commit.
objectFit
'cover' | 'contain' | 'fill'
How the image fills its bounding box. Default is 'cover'.
width
number
Intrinsic width hint in pixels.
height
number
Intrinsic height hint in pixels.
{ type: 'image',
  url: 'https://cdn.example.com/product-shot.jpg',
  objectFit: 'cover',
  at: { x: 960, y: 0, w: 960, h: 1080 } }

type: 'shape'

A vector shape — rectangle, circle, ellipse, triangle, or line. Supports solid fills, CSS gradients, structured fill stacks, opacity, stroke, and corner radius.
type
"shape"
required
shape
'rectangle' | 'circle' | 'ellipse' | 'triangle' | 'line'
required
The shape kind.
fill
string
Solid fill color as a CSS color string.
gradient
string
Raw CSS gradient string, e.g. 'linear-gradient(135deg, #667eea, #764ba2)'.
fills
Fill[]
Structured fill stack — an array of Fill objects (solid, gradient, image, shader). Rendered bottom-to-top. See Fills Reference.
opacity
number
Fill opacity from 0 (transparent) to 1 (opaque). Does not affect stroke.
stroke
string
Stroke color as a CSS color string.
strokeWidth
number
Stroke thickness in pixels.
radius
number
Corner radius in pixels (rectangles only).
x1
number
Line start X, relative to the layer box in 0–1 coordinates (lines only).
y1
number
Line start Y (lines only).
x2
number
Line end X (lines only).
y2
number
Line end Y (lines only).
arrowStart
boolean
Add an arrowhead at the start of the line.
arrowEnd
boolean
Add an arrowhead at the end of the line.
// Rounded rectangle with a brand fill
{ type: 'shape', shape: 'rectangle',
  fills: [solidFill('var(--slide-brand)')],
  radius: 12,
  at: { x: 160, y: 800, w: 300, h: 60 } }

// Arrow line
{ type: 'shape', shape: 'line', stroke: '#94A3B8', strokeWidth: 2,
  arrowEnd: true, x1: 0, y1: 0.5, x2: 1, y2: 0.5,
  at: { x: 200, y: 540, w: 400, h: 4 } }

type: 'icon'

An SVG icon layer from the Ablo icon library.
type
"icon"
required
icon
string
required
Icon key, e.g. 'rocket', 'bar-chart', 'arrow-right', 'check-circle'.
color
string
Icon color. Accepts any CSS color or theme variable.
{ type: 'icon', icon: 'rocket', color: 'var(--slide-brand)',
  at: { x: 880, y: 480, w: 160, h: 160 } }

Full example

The following creates a deck with a single content slide that uses multiple layer types together.
import Decks, { solidFill } from '@abloatai/decks';

const ablo = new Decks(process.env.ABLO_API_KEY!);

await ablo.decks.create({
  title: 'Q3 Investor Update',
  slides: [
    {
      title: 'Key Metrics',
      layers: [
        // Background rectangle
        {
          type: 'shape',
          shape: 'rectangle',
          fills: [solidFill('#0F172A')],
          at: { x: 0, y: 0, w: 1920, h: 1080 },
          z: 0,
        },
        // Slide heading
        {
          type: 'text',
          text: 'Key Metrics — Q3 2024',
          style: 'h1',
          color: '#F1F5F9',
          at: { x: 160, y: 80, w: 1200, h: 110 },
          z: 1,
        },
        // KPI labels
        {
          type: 'bullets',
          items: ['ARR $4.2M', 'NRR 118%', 'CAC payback 9 months'],
          style: 'body1',
          color: '#CBD5E1',
          bulletColor: '#3B82F6',
          bulletStyle: 'arrow-right',
          at: { x: 160, y: 240, w: 600, h: 400 },
          z: 2,
        },
        // Revenue chart
        {
          type: 'bar',
          data: [
            { label: 'Q1', value: 2.1 },
            { label: 'Q2', value: 2.8 },
            { label: 'Q3', value: 3.4 },
          ],
          valueFormat: '$0.0"M"',
          dataLabels: true,
          cagrArrow: true,
          at: { x: 900, y: 160, w: 860, h: 720 },
          z: 2,
        },
        // Company logo
        {
          type: 'image',
          url: 'https://cdn.example.com/logo.svg',
          objectFit: 'contain',
          at: { x: 80, y: 30, w: 180, h: 54 },
          z: 3,
        },
      ],
    },
  ],
});